From 6a9cf46db8316e115e79189c5eeacea399a28989 Mon Sep 17 00:00:00 2001 From: Hyemin Lee Date: Mon, 29 Jun 2026 17:13:00 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20=EB=94=94=EC=9E=90=EC=9D=B8=C2=B7?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B0=9C=ED=8E=B8=20=EC=9E=91=EC=97=85=20?= =?UTF-8?q?=EA=B3=84=ED=9A=8D=20=EC=B2=B4=ED=81=AC=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8(PLANS.md)=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 (1M context) --- PLANS.md | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 PLANS.md diff --git a/PLANS.md b/PLANS.md new file mode 100644 index 0000000..9af5926 --- /dev/null +++ b/PLANS.md @@ -0,0 +1,83 @@ +# PLANS.md — 디자인·기능 전격 개편 + +> 목표: `design-refs/AI DEV 포털.dc.html` 의 디자인/기능을 **거의 그대로** 살려서 +> 현재 포털을 개편한다. 단, 제약은 유지 — **빌드 없음 · React 없음 · 서버 렌더링(EJS) + +> 단일 CSS(`public/style.css`) + 가벼운 바닐라 JS(`public/app.js`)**. +> +> 기준: 디자인이 기획(PRD)보다 앞섰으므로 **디자인을 정답으로** 본다. PRD에 빠진 항목은 +> PRD에 보강한다(Phase 6). + +## 확정된 설계 결정 (사용자 합의) +- **반응 2종 유지**: ❤️ 좋아요(heart) + ⭐ 즐겨찾기(star) 둘 다. 인기순 정렬·즐겨찾기 필터 포함. +- **부가 요소 전부 유지**: 다크모드 토글, 토스트, 헤더 검색, 이스터에그(로고 흔들기·👍🚀✨·LGTM 스탬프). +- **공개/비공개(visibility)** 도입: 내 프로젝트는 공개/비공개 전환 가능, 비공개는 피드 미노출. +- **관리자 판별은 실제 Keycloak role** 로. (디자인의 "관리자 보기" 데모 토글은 제거하고 role 기반으로 대체) +- **상세는 모달** + 비-JS 폴백용 `/projects/:id` 단독 페이지도 유지. +- **반응/댓글은 점진적 향상(progressive enhancement)**: JS 없으면 폼 POST→리다이렉트, JS 있으면 fetch 로 즉시 반영. +- 폐쇄망: 폰트/아이콘은 외부 CDN 의존 최소화(시스템 폰트 폴백 + 인라인 SVG/이모지). + +--- + +## Phase 0 — DB 스키마 & db.js ✅ (db:init 실행만 남음) +- [x] `schema.sql`: `projects` 에 `is_public boolean NOT NULL DEFAULT true`, `lang text DEFAULT ''` 컬럼 추가(멱등 `ADD COLUMN IF NOT EXISTS`). +- [x] `schema.sql`: `comments` 에 `parent_id bigint REFERENCES comments(id) ON DELETE CASCADE` 추가(대댓글 1뎁스). +- [x] `schema.sql`: ❤️ 좋아요용 `hearts(project_id, sabun, created_at, PK)` 테이블 추가. (기존 `stars` = ⭐ 즐겨찾기 유지) +- [x] `db.js`: `listProjects(viewer)` — heart_count·star_count·comment_count·owner_name·is_public·lang + viewer hearted/starred. 공개 + 본인 비공개만 반환(남의 비공개 미노출). +- [x] `db.js`: `getProject(id, viewer)` — 단일 조회 + 카운트 + viewer 반응 여부. +- [x] `db.js`: `listComments(projectId)` — parent_id 포함, 작성자 이름. +- [x] `db.js`: `addProject({owner,title,description,repoUrl,appUrl,tags,isPublic,lang})`. +- [x] `db.js`: `addComment({projectId,author,body,parentId})` — 부모가 같은 프로젝트의 최상위일 때만(1뎁스 강제), 새 행 반환. +- [x] `db.js`: `deleteComment({id, sabun})` — 본인만, 자식 댓글까지 cascade. +- [x] `db.js`: `toggleHeart`(❤️) / `toggleStar`(⭐) — `{on,count}` 반환(AJAX 즉시 반영용). +- [x] `db.js`: `setVisibility({id, sabun, isPublic})` — 본인 프로젝트만. +- [x] `db.js`: `deleteProject({id, sabun})` — 본인만. +- [ ] **`npm run db:init` 재실행해 적용** — 로컬에 `.project-env`(DATABASE_URL)가 없어 미실행. 실제 DB 환경에서 사용자가 실행 필요. + +## Phase 1 — 설정 · 권한 · 사이트 카탈로그 ✅ +- [x] `auth.js`: 콜백 claims 에서 role 추출(`realm_access.roles` + 클라이언트 role), `roles` + `isAdmin` 반환 → 세션 저장. +- [x] `config.js`: 도구 URL 8종 환경변수화(기본값 유지). 관리자 role 이름(`ADMIN_ROLE`, 기본 `admin`) 추가. +- [x] `sites.js`: 디자인 도구 목록으로 재구성 — 개발(Coder·Gitea·Kubero·Harbor) + 인프라(OpenEverest·MinIO·Keycloak·LiteLLM, `adminOnly:true`). SSO 플래그·이모지 아이콘·`toolsForUser(isAdmin)` 헬퍼. +- [x] `.project-env.example`: `ADMIN_ROLE` + 도구 URL 항목 추가. +- 참고: `server.js` 는 아직 `siteGroups`(구 export)를 import → **Phase 4 에서 재작성 전까지 부팅 불가** (의도된 중간 상태). + +## Phase 2 — 공통 레이아웃 · CSS · 클라이언트 JS ✅ +- [x] `public/style.css`: CSS 변수 시스템(라이트+다크 `html[data-aidev-theme="dark"]`) 전면 도입. 헤더/도구 그리드/내 프로젝트 패널/피드 그리드/카드/배지/버튼/모달/공유모달/댓글 스레드/토스트/플라이어/푸터/로그인/단독페이지/키프레임/반응형 — **단일 파일**. 반응 아이콘 채움↔외곽선 토글 규칙 포함. +- [x] `views/_header.ejs`: 스티키 다크 헤더(로고+이스터에그 훅, 검색창, 테마 토글, 관리자 배지, 사용자 메뉴 드롭다운+로그아웃). 데모 관리자 토글 제거→실제 role. FOUC 방지 테마 초기화 인라인 스크립트. +- [x] 아이콘: `views/_icons.ejs` 대신 **`src/helpers.js`** 에 `icon(name,{size,fill})` 헬퍼로 구현(Octicon 22종). 더불어 `identicon(seed,size)`(서버 SVG 아바타)·`langColor`·`langFromTags` 도 제공 → Phase 4 에서 res.locals 로 노출. +- [x] `public/app.js`(바닐라): 테마 토글·localStorage, 사용자 메뉴, 상세 모달 열기/닫기(Esc·오버레이), 검색·정렬(최신/인기)·즐겨찾기 필터(피드, 클라이언트), 내 프로젝트 필터(전체/공개/비공개), 댓글 답글 타깃·Enter 등록·삭제 확인, 공유 모달·공개범위 토글, 반응 fetch 즉시 반영, 토스트, 이스터에그(로고 흔들기·👍🚀✨·콘솔 아트), body 데이터속성 시작 신호(`data-toast`/`data-egg`/`data-open-modal`). +- 참고: 대시보드/모달 마크업은 app.js 의 **DOM 계약(data-* 속성)** 에 맞춰 Phase 3/5 에서 렌더. + +## Phase 3 — 대시보드(`/`) ✅ +- [x] `views/dashboard.ejs` ① 개발 도구 섹션: role 필터된 카드 그리드(a target=_blank), SSO 배지, 관리자 전용 카드 스타일(보라) + "관리자 도구 표시 중" 배지. +- [x] ② 내 프로젝트 섹션: 좌측 액센트 바 패널, 전체/공개/비공개 필터 탭+카운트, "새 프로젝트" 버튼, 카드(가시성 배지·언어 점·❤️/⭐/💬 카운트·공개↔비공개 폼 토글), 새 프로젝트 추가 카드, 빈 상태. +- [x] ③ 공유 피드 섹션: 2열 카드 그리드, 인라인 ❤️/⭐ 반응 버튼(채움/외곽선 토글), 작성자 아바타·날짜, 바로가기 링크, 최신/인기 탭 + 즐겨찾기 필터, 검색 빈 상태 요소. +- [x] 검색/정렬/필터용 data-* 속성(`data-search`/`data-created`/`data-pop`/`data-starred`/`data-vis`) 부여 → `app.js` 가 클라이언트 처리. +- [x] 모의 데이터로 EJS 렌더 검증 통과(헤더 include 포함). 모달/공유모달/상세저장소는 Phase 5. + +## Phase 4 — 라우트(`server.js`) +- [ ] `GET /` — 도구(role 필터)+내 프로젝트+피드 데이터 렌더. `?open=:id` 면 해당 모달 자동 오픈. +- [ ] `POST /projects` — 생성(visibility, 태그에서 lang 추론). 완료 후 리다이렉트. +- [ ] `POST /projects/:id/heart` · `POST /projects/:id/star` — 토글. JS(fetch)면 JSON `{on,count}`, 아니면 리다이렉트. +- [ ] `POST /projects/:id/visibility` — 공개/비공개 전환(본인). +- [ ] `POST /projects/:id/delete` — 본인 프로젝트 삭제. +- [ ] `POST /projects/:id/comments` — 댓글/대댓글(`parent_id` 옵션, 1뎁스 검증). JSON/리다이렉트 분기. +- [ ] `POST /comments/:id/delete` — 본인 댓글 삭제. +- [ ] `GET /projects/:id` — 모달 내용과 동일 정보의 단독 페이지(비-JS·공유 링크용). + +## Phase 5 — 상세 모달 · 공유 모달 · 단독 페이지 +- [ ] 대시보드에 상세 모달 마크업: 헤더(제목·가시성·작성자·날짜·언어)·태그·설명·❤️/⭐/바로가기/저장소 버튼·댓글 스레드(대댓글 들여쓰기·LGTM 스탬프·답글/삭제)·댓글 입력(Enter 등록). +- [ ] 공유 모달 마크업: 제목*·설명·태그·배포 URL·공개범위(공개/비공개) 토글 + 안내문. +- [ ] `app.js` 로 모달 데이터 바인딩(렌더된 프로젝트 데이터 사용) + 폼 제출 처리. +- [ ] `views/project.ejs` 단독 페이지를 새 디자인에 맞게 갱신. + +## Phase 6 — 문서 · 마무리 · 점검 +- [ ] `ai-dev-portal-prd.md` 보강: 반응 2종(heart/star), 공개/비공개, lang, 댓글 parent_id, 추가 라우트, 다크모드/검색/토스트 등 디자인 확정 사항 반영. +- [ ] `CLAUDE.md` 구조 맵 갱신(`public/app.js`, `_icons.ejs`, hearts 테이블 등) 필요 시. +- [ ] Pretendard 폰트: 시스템 폰트 폴백 확정. (선택) `public/` 에 woff2 로컬 호스팅 태스크 별도. +- [ ] 로컬 구동 점검: `npm run dev` → 로그인/도구/내프로젝트/피드/모달/공유/반응/댓글/대댓글/삭제/테마/검색 수동 확인. +- [ ] 미인증·관리자/일반 분기·비공개 노출 규칙 점검. + +--- + +### 진행 메모 +- (작업하며 결정·이슈를 여기에 누적)