# flowtodo — 프로젝트 기획서 > 작성: 박동제 (pkdje) · 2026-05-30 · Week 1 산출물 > 갱신: 2026-06-02 — Week 2 시작 시 **퀘스트 게임 UI 오버레이** 결정 추가, 자세한 설계는 [04-quest-game-ui.md](04-quest-game-ui.md). 본 문서의 UI 섹션(§6) 은 그 결정 이후의 톤을 반영하지 않음 — `04` 가 우선. GitHub Wiki에 그대로 옮길 수 있도록 작성되었음. --- ## 1. 서비스 주제 **flowtodo** — DAG(방향 비순환 그래프) 기반 todo 웹앱. 기존 todo 앱은 작업을 1차원 리스트로 다룬다. 하지만 실제 작업은 **선후관계(precedence)** 가 존재한다. "발표 자료" 는 "주제 정하기" 와 "데이터 수집" 둘 다 끝나야 시작할 수 있다. flowtodo 는 이 의존성을 명시적으로 그래프로 모델링하고, 그래프 구조 자체를 시각화의 1급 요소로 삼는다. 여기에 한 가지 더 — **"지금 어떤 작업부터 해야 하는가?"** 를 자동으로 추천한다. 우선순위(사용자 의도) + 다운스트림 임팩트(이 작업을 끝내면 몇 개의 후속 작업이 해금되는지) 를 점수로 합쳐 정렬한다. 추천은 DAG 옆 패널에 점수와 함께 노출되어 "왜 이게 1등인지" 설명 가능하다. ### 한 문장 정의 > 선후관계가 있는 일을 그래프로 정리하고, 다음에 할 일을 자동으로 골라주는 개인용 todo 앱. --- ## 2. 핵심 기능 ### 2.1 필수 (Week 2) - **Task CRUD** — 제목, 설명/메모, 우선순위(1–5), 마감일, 상태(todo/in_progress/done), 선행 작업. - **의존성 관리** — 한 태스크는 여러 선행 작업을 가질 수 있다. 추가 시 사이클이면 거부. - **DAG 시각화** — 노드(태스크) + 엣지(의존성). 자동 레이아웃. 노드는 상태별 색상으로 구분. - **다음 작업 추천** — Ready set(선행 작업이 모두 완료된 todo)을 점수순으로 정렬해 좌측 패널에 표시. - **점수 산식** — `score = 0.6 · (priority/5) + 0.4 · (impact / maxImpact)` (가중치는 일단 하드코딩). ### 2.2 다듬기 (Week 3) - **추천 핀/snooze** — 사용자가 1등을 강제 지정하거나 일부 후보를 큐에서 숨기기. - **노드 시각화 polish** — 우선순위 별, 마감일 D-n, "선행 작업 미완료(막힘)" 상태 흐림 처리. - **가중치 슬라이더** — `w_p` vs `w_i` 비율을 사용자가 조정. - **빈/에러 상태 UI**, **자동 레이아웃 미세 조정**, **배포**. ### 2.3 제외 (YAGNI — 3주에 안 함) 멀티 프로젝트 · 인증/멀티유저 · 태그 · 검색 · 예상 소요시간 · 크리티컬 패스 · 실시간 동기화 · 모바일 반응형 · Undo · 알림. --- ## 3. 기술 스택 및 선택 이유 | 영역 | 선택 | 이유 | |---|---|---| | 프레임워크 | **Next.js 14+ (App Router)** | 풀스택 단일 프로젝트. API 라우트로 MongoDB 핸들러까지 한 곳에서. Vercel 배포가 단순. | | DB | **MongoDB (Atlas free tier)** | 단일 컬렉션 + 임베디드 배열(`prerequisites`) 로 그래프 표현 자연스러움. 스키마 변화에 유연 (1주차 결정 변동 대비). | | DB 드라이버 | **`mongodb` (raw)** | 단일 컬렉션이라 Mongoose 오버킬. 학습용으로도 raw 드라이버가 명확. | | 시각화 | **React Flow** + **dagre** | 노드/엣지/드래그/줌이 네이티브. dagre 가 자동 레이어드 레이아웃을 처리. d3 직접 구현보다 부담 적음. | | 상태관리 | **Zustand** | 그래프 상태(노드/엣지/추천 점수)를 다루기에 Redux/Context 보다 가벼움. Provider 안 감싸도 됨. | | 스타일 | **Tailwind CSS** | "간단하고 예쁘게" 목표에 적합. 유틸 클래스로 빠르게. | | 언어 | **TypeScript** | DAG 데이터/노드 타입이 엄격해야 추천 알고리즘에서 실수 안 함. | ### 후보 비교 (왜 다른 걸 안 골랐는가) - **Mongoose 대신 raw mongodb 드라이버** — 단일 컬렉션이라 ODM 의 인덱스/혹은 미들웨어 이점이 적음. - **React Flow 대신 d3 직접** — 노드 인터랙션(드래그로 엣지 생성, 줌, 컨텍스트 메뉴) 을 처음부터 구현하는 비용이 큼. 3주에 안 맞음. - **Cytoscape.js** — DAG 친화적이지만 React 통합이 React Flow 보다 거침. - **Mongoose 대신 Prisma + PostgreSQL** — 관계형이라 의존성 모델링은 더 깨끗하지만, 학습 비용 ↑. MongoDB 가 이미 결정된 사항. --- ## 4. 데이터 모델 MongoDB 단일 컬렉션 `tasks`: ```ts type Task = { _id: ObjectId title: string // 필수 description?: string // 선택, markdown 허용 status: 'todo' | 'in_progress' | 'done' priority: 1 | 2 | 3 | 4 | 5 // 5 = 가장 높음 dueDate?: Date // 선택 prerequisites: ObjectId[] // 시작 가능하려면 끝나야 하는 작업들 createdAt: Date updatedAt: Date } ``` **설계 결정 메모** - 의존성을 별도 컬렉션이 아니라 `prerequisites` 임베디드 배열로 — 단일 사용자라 동시 쓰기 경합 없고, 노드 수도 수백 수준이므로 충분. - `successors` 는 저장하지 않음. 필요할 때 클라이언트에서 한 번 역인덱스 만들면 됨. 데이터 불일치 위험 방지. - 사이클 방지는 **클라이언트에서 `prerequisites` 추가 시점에 DFS 로 검증**, 서버는 안전망으로 한 번 더 검증. - 단일 DAG 가정 — `projectId` 같은 그룹키는 없음. 멀티 프로젝트는 확장 사항. --- ## 5. 추천 알고리즘 ### 5.1 Ready set ``` ready = tasks.filter(t => t.status === 'todo' && t.prerequisites.every(p => taskMap[p].status === 'done') ) ``` ### 5.2 임팩트 ``` impact(t) = | { u : u 가 t 에 (직간접) 의존하고 u.status ≠ 'done' } | ``` 전체 그래프에 대해 단일 DFS + 메모이제이션으로 O(V+E). ### 5.3 점수 ``` score(t) = w_p · (priority(t) / 5) + w_i · (impact(t) / maxImpact) (기본 w_p = 0.6, w_i = 0.4) ``` ### 5.4 정렬 + 사용자 오버라이드 - 점수 내림차순. - 사용자 핀 → 상단 고정. snooze → 큐에서만 숨김 (DAG 에서는 보임). ### 5.5 왜 가중합인가 - 단순/디버깅 쉬움. - 노드에 점수가 그대로 표시되므로 "왜 이게 1등인지" 즉시 설명 가능. - 가중치를 슬라이더로 노출하면 사용자가 의도(priority 중시) vs 구조 신호(impact 중시) 를 직관적으로 조정 가능. --- ## 6. 화면 흐름 / 페이지 구성 초안 **단일 페이지** — 대시보드 하나가 모든 인터랙션의 중심. ``` ┌────────────────────────────────────────────────────────────────┐ │ flowtodo [+ 새 태스크] [⚙ 설정] │ ├──────────────┬─────────────────────────────────────────────────┤ │ ▶ 추천 (3) │ │ │ ┌──────────┐ │ │ │ │ 디자인 │ │ [DAG 시각화 영역] │ │ │ score 8.2│ │ (React Flow + dagre 자동 레이아웃) │ │ │ ★★★★☆ │ │ │ │ │ 📌 💤 │ │ │ │ └──────────┘ │ │ │ ┌──────────┐ │ │ │ │ 리서치 │ │ │ │ │ score 6.1│ │ │ │ └──────────┘ │ │ │ │ │ │ [▼ 완료(12)]│ │ │ [▼ 막힘(5)] │ │ └──────────────┴─────────────────────────────────────────────────┘ ``` ### 인터랙션 | 액션 | 결과 | |---|---| | 노드 클릭 | 우측 드로어 — 제목/설명/우선순위/마감일/선행작업 편집 | | 노드 더블클릭 | 상태 순환: todo → in_progress → done | | 노드 끝에서 드래그 | 의존성 엣지 생성 (사이클이면 빨갛게 거부) | | 추천 카드 클릭 | 해당 노드로 카메라 이동 + 강조 | | 추천 카드 핀 | 추천 큐 상단 고정 | | 추천 카드 snooze | 추천 큐에서만 숨김 | | `+ 새 태스크` | 모달 — 제목/우선순위/선행작업 | ### 노드 시각 규약 - **색**: done 초록 / in_progress 파랑 / todo 흰색 / 추천 1등 노랑 + 테두리 강조 - **표시**: 제목, 우선순위 별(1–5), 마감일 D-n, (추천 후보일 때) 점수 - **흐림**: 선행작업 미완료인 todo 는 50% opacity ("막힘") ### 반응형 1주차에는 데스크탑 우선. 모바일은 3주차 후반 여유 있을 때 검토. --- ## 7. 3주 일정 | 주차 | 목표 | 산출물 | |---|---|---| | **Week 1 (2026-05-30 ~ )** | 기획 & 워크플로우 설계 | 본 기획서, Agent workflow 문서, GitHub 이슈 백로그, 저장소 셋업, (선택) React Flow 프로토타입 | | **Week 2** | 코어 구현 | MongoDB 연결, Task CRUD API, React Flow DAG 렌더, 생성/편집/의존성/상태 토글, 추천 점수 계산, 추천 패널 | | **Week 3** | 다듬기 + 배포 | 핀/snooze, 노드 polish, 가중치 슬라이더, 빈/에러 상태, Vercel + Atlas 배포, 회고 | --- ## 8. 위험 요소 | 위험 | 대응 | |---|---| | React Flow + dagre 가 큰 그래프(>50 노드)에서 보기 흉할 수 있음 | Week 1 프로토타입에서 mock DAG 로 검증 | | MongoDB Atlas 무료 등급 cold start 지연 | 배포 후 첫 요청 지연 감수, 필요 시 ping 스크립트 | | 3주 안에 다듬기까지 못 끝낼 위험 | Week 2 의 must-have 를 절대 사수, Week 3 는 should-have 만 | --- ## 9. 저장소 / 브랜치 / 위키 - **저장소**: `boostcampwm-snu-2026-1/flowtodo-pkdje` (부캠 조직 저장소) - **브랜치**: `main → dev → features/*` (현재 dev 작업 중) - **이슈**: 기능별 Task 를 이슈로 등록 (`task-backlog.md` 참고) - **Wiki**: 본 기획서 / 워크플로우 / 회고 를 위키 페이지로 게시 - **PR 흐름**: `feature/* → dev → main`