Files
to-do/docs/03-analysis/todo-app.analysis.md
2026-06-15 15:11:50 +09:00

101 lines
4.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Analysis (Check) — todo-app
> PDCA Phase: **Check** · Feature: `todo-app` · 작성일: 2026-06-15
> 상위: [Plan](../01-plan/features/todo-app.plan.md) · [Design](../02-design/features/todo-app.design.md)
## Context Anchor
| 항목 | 내용 |
|------|------|
| WHY | 사내 샘플을 실제 쓰는 최소 To-Do 앱으로 — DB+S3 패턴 시연 |
| WHO | 로그인 없는 단일 공용 목록 |
| RISK | 첨부 처리, schema 마이그레이션, S3-DB 정합성 |
| SUCCESS | 브라우저 CRUD + 첨부 업/다운로드, db/minio check 통과 |
| SCOPE | IN: todo CRUD + 첨부 1개 + 웹UI + API / OUT: 인증·태그·검색 |
## Match Rate
| 축 | 점수 | 가중치 | 기여 |
|----|:----:|:------:|:----:|
| Structural | 100% | 0.15 | 15.0 |
| Functional | 96% | 0.25 | 24.0 |
| Contract | 100% | 0.25 | 25.0 |
| Runtime (L1) | 100% | 0.35 | 35.0 |
| **Overall** | **99%** | | |
> 런타임 실행 공식 적용(서버 기동). 16/16 L1 테스트 통과, 서버 로그 에러 없음.
## 1. Structural Match — 100%
Design §2 모듈 구조 전부 존재, §4 라우트 6개(`GET /`, `GET/POST /api/todos`, `PATCH/DELETE /api/todos/:id`, `GET /api/todos/:id/attachment`) 모두 구현·마운트 확인.
## 2. Functional Depth — 96%
| 항목 | 결과 |
|------|------|
| 업로드 보상 삭제(§5,§6) | ✅ 업로드 실패 시 `repo.remove` |
| 삭제 시 S3 선삭제 후 DB(§6) | ✅ best-effort 로깅 후 진행 |
| pgcrypto fallback(§3) | ✅ 런타임에서 실제 발동 확인(`permission denied``randomUUID`) |
| 입력 검증(title/uuid/done) | ✅ |
| placeholder/미구현 | 없음 |
**4% 사유 (Minor)**: Design §5는 "단일 INSERT(첨부 키 포함)"로 기술됐으나, 구현은 "INSERT → setAttachment UPDATE" 2단계. 동작·정합성은 동일(오히려 id 기반 키 생성에 더 적합). 문서-구현 표현 불일치만 존재.
## 3. API Contract — 100% (3자 검증)
Design §4 ↔ `src/routes.todos.js``public/index.html` fetch 호출 일치:
- 응답 envelope `{data}` / `{error}`
- `hasAttachment` 노출 + `attachment_key` 비노출 ✅ (런타임 L1-8 검증)
- 상태코드(201/400/404/413/204/200) 일치 ✅
- 다운로드 `Content-Disposition` 헤더 ✅ (L1-10)
## 4. Runtime Verification (L1) — 16/16 PASS
| # | 검증 | 기대 | 결과 |
|---|------|:----:|:----:|
| 1 | GET / | 200 | ✅ |
| 2-3 | GET /api/todos + {data} | 200 | ✅ |
| 4 | POST title | 201 | ✅ |
| 5-6 | POST no title + {error} | 400 | ✅ |
| 7 | 첨부 hasAttachment | true | ✅ |
| 8 | attachment_key 비노출 | — | ✅ |
| 9-10 | 다운로드 + Content-Disposition | 200 | ✅ |
| 11 | PATCH done | 200 | ✅ |
| 12-14 | PATCH bad uuid/no done/404 | 400/400/404 | ✅ |
| 15 | DELETE | 204 | ✅ |
| 16 | 삭제 후 다운로드(cascade) | 404 | ✅ |
## 5. Success Criteria 평가
| SC | 상태 | 근거 |
|----|:----:|------|
| SC-01 CRUD UI | ✅ Met | L1 + public/index.html |
| SC-02 업로드→S3+DB key | ✅ Met | L1-7, S3 객체 생성 |
| SC-03 다운로드 | ✅ Met | L1-9/10 내용 일치 |
| SC-04 삭제 시 S3도 삭제 | ✅ Met | L1-16 cascade |
| SC-05 db/minio check | ✅ Met | 둘 다 통과 |
| SC-06 podman | ⚠️ Partial | Dockerfile 무변경으로 빌드 가능하나 이 세션 미실행 |
## 6. Decision Record 준수 검증
| 결정 | 준수 |
|------|:----:|
| Option C(repo/attachments/routes 분리) | ✅ |
| 서버 프록시 스트리밍(presigned 미사용) | ✅ `GetObjectCommand` pipe |
| pgcrypto + randomUUID fallback | ✅ 런타임 발동 |
| 변경점: multer 1.x→2.1.1 | ✅ 의도된 보안 대응, API 동일 |
## 7. Gap 목록
| ID | Severity | 내용 | 조치 |
|----|:--------:|------|------|
| G1 | Minor | §5 단일 INSERT 서술 vs 2단계 구현 | 문서 동기화(선택) |
| G2 | Minor | SC-06 podman 빌드 미검증 | 컨테이너 빌드 1회 권장 |
| G3 | Minor | 파일 content-type 화이트리스트 미적용(NFR-03 일부) | OUT-of-scope 수준, 향후 |
**Critical/Important 갭: 0건.**
## 8. 결론
Overall **99%** (≥90% 목표 달성). Critical/Important 이슈 없음. Minor 3건은 모두 문서/범위 외/검증 절차 항목으로 코드 수정 불요. → iterate 없이 **QA 또는 report** 단계로 진행 가능.