Files
to-do/docs/01-plan/features/todo-app.plan.md
2026-06-15 15:11:50 +09:00

6.8 KiB

Plan — todo-app (간단한 To-Do 앱)

PDCA Phase: Plan · Feature: todo-app · 작성일: 2026-06-15 스택: Node 22 (ESM) + Express · Postgres(src/db.js) · MinIO/S3(src/s3.js) · podman 로컬 / Coolify 배포

Executive Summary

관점 요약
Problem 할 일을 기록·관리할 화면과 저장소가 없다. 현재 앱은 연결 확인용 엔드포인트(/db, /s3)만 존재한다.
Solution Postgres에 할 일(todo)을 CRUD로 저장하고, 할 일별 첨부파일은 MinIO/S3에 저장하는 단일 공용 To-Do 웹 앱. 기존 db.js/s3.js/config.js를 그대로 확장한다.
Function UX Effect 브라우저에서 할 일 추가/완료/삭제, 파일 첨부·다운로드가 즉시 동작. REST API도 함께 제공해 curl/외부 연동 가능.
Core Value DB(구조화 데이터) + S3(바이너리 파일)를 함께 쓰는 가장 단순하고 실용적인 표준 패턴을 적은 코드로 제공.

Context Anchor

항목 내용
WHY 사내 워크스페이스 샘플을 실제로 쓸 수 있는 최소 To-Do 앱으로 만들어 DB+S3 활용 패턴을 보여준다.
WHO 로그인 없이 접근하는 단일 사용자/소규모 팀(단일 공용 목록).
RISK 첨부파일 처리(업로드 크기/타입, presigned URL), schema 마이그레이션 누락, S3 키-DB 레코드 정합성.
SUCCESS 브라우저에서 할 일 CRUD + 첨부 업로드/다운로드가 동작하고 npm run db:check/minio:check가 통과.
SCOPE IN: todo CRUD, 첨부 1개/항목, 웹 UI, REST API. OUT: 인증/멀티유저, 마감일/태그/검색, 실시간 동기화.

1. 배경 및 목표

기존 src/server.js/healthz, /db, /s3, / 만 제공한다. 여기에 To-Do 도메인을 얹는다.

  • 목표: "DB와 S3를 이용한 간단한 To-Do 앱"을 최소 변경으로 구현.
  • 설계 원칙: 외부 연결은 반드시 src/config.js/src/db.js/src/s3.js를 경유(CLAUDE.md 규약). 비밀값은 env에서만.
  • 데이터 분담: 구조화 데이터(todo 본문/상태) → Postgres, 바이너리(첨부파일) → MinIO/S3, 둘을 키로 연결.

2. 요구사항

2.1 기능 요구사항 (FR)

ID 요구사항 우선순위
FR-01 할 일 목록 조회 (최신순) Must
FR-02 할 일 추가 (제목, 선택적 첨부파일 1개) Must
FR-03 할 일 완료/미완료 토글 Must
FR-04 할 일 삭제 (연결된 S3 첨부도 함께 삭제) Must
FR-05 첨부파일 업로드 → MinIO/S3 저장, DB에 키 기록 Must
FR-06 첨부파일 다운로드 (presigned URL 또는 프록시 스트리밍) Must
FR-07 간단한 웹 UI(HTML) — 목록/추가/완료/삭제/첨부 Must
FR-08 REST API(JSON) — 위 동작을 curl로도 수행 가능 Should

2.2 비기능 요구사항 (NFR)

ID 요구사항
NFR-01 ESM, Node 22+, 외부 연결은 config/db/s3 경유 (CLAUDE.md 규약 준수)
NFR-02 비밀값 코드/커밋 금지 — 모두 .project-env env에서 주입
NFR-03 업로드 파일 크기 제한(예: 10MB) 및 기본 검증
NFR-04 podman 빌드/실행 및 Coolify 동일 Dockerfile에서 동작
NFR-05 DB schema는 앱 시작 시 멱등(idempotent) 생성 또는 마이그레이션 스크립트 제공

3. 범위 (Scope)

  • In scope: todo CRUD, 항목당 첨부파일 1개(S3), 서버 렌더 웹 UI, JSON REST API, schema 부트스트랩.
  • Out of scope: 인증/멀티유저, 마감일·태그·우선순위·검색, 다중 첨부, 실시간(WebSocket), 페이지네이션.

4. 데이터 모델 (초안)

table todo (
  id          uuid pk default gen_random_uuid(),
  title       text not null,
  done        boolean not null default false,
  attachment_key   text null,   -- S3 object key (없으면 null)
  attachment_name  text null,   -- 원본 파일명
  attachment_type  text null,   -- content-type
  created_at  timestamptz not null default now()
)
  • 첨부 S3 키 규칙(초안): todos/{todo_id}/{원본파일명} (버킷 coolify-user-data).
  • 삭제 시 DB row 삭제 + S3 object 삭제(정합성).

5. API 설계 (초안)

Method Path 설명
GET / 웹 UI (할 일 목록 페이지)
GET /api/todos 목록(JSON)
POST /api/todos 추가 (multipart: title + 선택 file)
PATCH /api/todos/:id done 토글
DELETE /api/todos/:id 삭제(+ S3 첨부 삭제)
GET /api/todos/:id/attachment 첨부 다운로드(presigned redirect 또는 스트리밍)

6. 구현 항목 (모듈 단위)

모듈 작업 신규/수정
src/schema.js (또는 scripts/migrate.js) todo 테이블 멱등 생성 신규
src/todos.repo.js DB CRUD 쿼리 (pool 사용) 신규
src/attachments.js S3 업로드/삭제/presigned URL (s3.js 확장) 신규
src/routes.todos.js REST 라우트 핸들러 신규
src/server.js 라우트/정적·multipart 미들웨어 연결 수정
public/index.html (또는 인라인 템플릿) 간단한 웹 UI 신규
package.json multer(업로드), @aws-sdk/s3-request-presigner 의존성 추가 수정

7. 의존성

  • 추가 예정: multer(multipart 업로드 파싱), @aws-sdk/s3-request-presigner(다운로드 URL). 추가 후 npm install로 lock 갱신.
  • 기존: express, pg, @aws-sdk/client-s3 재사용.

8. Success Criteria

SC 기준 검증 방법
SC-01 브라우저에서 할 일 추가/완료/삭제가 동작 수동 + L2 UI 테스트
SC-02 첨부파일 업로드 시 S3에 객체 생성, DB에 key 기록 /s3 또는 MinIO 확인 + DB row
SC-03 첨부 다운로드가 정상 동작 다운로드 후 파일 일치 확인
SC-04 할 일 삭제 시 S3 객체도 삭제 삭제 후 S3 키 부재 확인
SC-05 npm run db:check / npm run minio:check 통과 CLI 실행
SC-06 podman build + podman run --env-file .project-env로 동일 동작 컨테이너 기동 확인

9. 리스크 및 대응

리스크 대응
gen_random_uuid() 미존재(pgcrypto) pgcrypto 확장 활성 확인 또는 앱에서 uuid 생성
업로드 대용량/악성 파일 크기 제한(10MB), content-type 화이트리스트 검토
DB-S3 정합성(삭제 누락) 삭제는 S3 먼저 시도 후 DB 삭제, 실패 시 로깅
presigned URL 만료/내부 호스트 노출 짧은 만료 또는 서버 프록시 스트리밍 중 Design에서 택1

10. 다음 단계

/pdca design todo-app — 3가지 아키텍처 옵션(최소변경 / 클린 / 실용균형)을 비교하고 데이터 모델·API·다운로드 방식을 확정.