@angar2/taskery 0.8.1 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +423 -188
- package/bin/add.js +27 -99
- package/bin/backlog.js +240 -113
- package/bin/check.js +166 -0
- package/bin/commands.js +151 -0
- package/bin/finish.js +353 -0
- package/bin/init.js +99 -190
- package/bin/install.js +143 -0
- package/bin/lib.js +513 -1325
- package/bin/mcp.js +31 -263
- package/bin/orche.js +240 -0
- package/bin/plan.js +58 -120
- package/bin/prepare.js +326 -0
- package/bin/prune.js +46 -176
- package/bin/status.js +57 -151
- package/bin/taskery.js +76 -120
- package/bin/update.js +66 -269
- package/package.json +5 -5
- package/template/.taskery/BACKLOG.md +38 -0
- package/template/.taskery/rules/CHANGELOG_RULE.md +31 -0
- package/template/.taskery/rules/DEV_RULE.local.md +8 -0
- package/template/.taskery/rules/GIT_RULE.md +82 -0
- package/template/.taskery/rules/MOCKUP_RULE.md +19 -0
- package/template/.taskery/rules/TASKERY_RULE.md +112 -0
- package/template/.taskery/rules/TASK_DOC_RULE.md +84 -0
- package/template/.taskery/rules/TEST_RULE.local.md +16 -0
- package/template/AGENTS.md +15 -53
- package/template/shared/skills/add-backlog/SKILL.md +8 -38
- package/template/shared/skills/log-friction/SKILL.md +10 -88
- package/template/shared/skills/plan-init/SKILL.md +10 -98
- package/template/shared/skills/project-init/SKILL.md +13 -342
- package/template/shared/skills/task-close/SKILL.md +16 -319
- package/template/shared/skills/task-dev/SKILL.md +19 -233
- package/template/shared/skills/task-init/SKILL.md +11 -68
- package/template/shared/skills/task-orche/SKILL.md +35 -0
- package/template/shared/skills/task-plan/SKILL.md +19 -498
- package/template/shared/skills/task-test/SKILL.md +23 -342
- package/bin/close.js +0 -86
- package/bin/fork.js +0 -112
- package/bin/legacy-quotes.js +0 -60
- package/bin/migrate.js +0 -481
- package/bin/set-status.js +0 -98
- package/template/.claude/hooks/closed-immutable.sh +0 -77
- package/template/.claude/settings.json +0 -18
- package/template/.claude/skills/run-team/SKILL.md +0 -145
- package/template/.codex/agents/task-tester.toml +0 -41
- package/template/.codex/agents/test-plan-author.toml +0 -34
- package/template/.codex/config.toml +0 -17
- package/template/.codex/hooks/closed-immutable.sh +0 -66
- package/template/.project/changelog/.gitkeep +0 -0
- package/template/.project/flows/.gitkeep +0 -0
- package/template/.project/plans/.gitkeep +0 -0
- package/template/.project/rules/CHANGELOG_RULE.md +0 -97
- package/template/.project/rules/GIT_RULE.md +0 -325
- package/template/.project/rules/MOCKUP_RULE.md +0 -86
- package/template/.project/rules/TASKERY_RULE.md +0 -237
- package/template/.project/rules/TASK_DOC_RULE.md +0 -668
- package/template/.project/shared/received/completed/.gitkeep +0 -0
- package/template/.project/shared/sent/completed/.gitkeep +0 -0
- package/template/.project/tasks/.gitkeep +0 -0
- package/template/shared/hooks/git-guard.sh +0 -108
|
@@ -1,668 +0,0 @@
|
|
|
1
|
-
# TASK_DOC_RULE
|
|
2
|
-
|
|
3
|
-
> taskery 태스크 문서(`task.md` 또는 `NNN_kebab-slug.md`) 작성 규칙.
|
|
4
|
-
> **이 양식 그대로 채워. 섹션 추가/삭제 금지. 변형은 hook으로 차단되지 않으나 메인이 일관성 위해 강제 준수.**
|
|
5
|
-
> 프로젝트별 변형이 필요하면 `.project/rules/TASK_DOC_RULE.local.md` 생성 (npx update 미터치, 구속력은 코어와 동등 — `TASKERY_RULE` §7).
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## 1. 양식 Spec
|
|
10
|
-
|
|
11
|
-
### 1.1 헤더 표 — 6컬럼
|
|
12
|
-
|
|
13
|
-
| 생성일 | 플랜 | 유형 | 규모 | 부모 브랜치 | 상태 |
|
|
14
|
-
|--------|------|------|------|-------------|------|
|
|
15
|
-
| 2026-05-08 | 001_mvp | feature | medium | dev | developing |
|
|
16
|
-
|
|
17
|
-
- **생성일**: ISO 형식 (YYYY-MM-DD)
|
|
18
|
-
- **플랜**: 어느 plan(기능 그룹) 하위인지 (예: 001_mvp, 002_compare-products) — `tasks/<NNN_slug>/` 디렉토리 명과 일치
|
|
19
|
-
- **유형**: `feature` / `bug` / `improvement` / `refactor` / `docs` / `chore` (git 브랜치 타입과 직결)
|
|
20
|
-
- **규모**:
|
|
21
|
-
- `micro` — 구현 파트 1개 (단일 함수/설정 수정)
|
|
22
|
-
- `small` — 구현 파트 2-3개 (단순 기능)
|
|
23
|
-
- `medium` — 구현 파트 4-7개 (일반 기능 또는 새 모듈)
|
|
24
|
-
- `large` — 구현 파트 8개 이상 (또는 분리 검토 권장)
|
|
25
|
-
- **부모 브랜치**: 이 task를 분기한 기점 브랜치 = `/task-init` 시점의 메인 워크트리 현재 브랜치 (`dev` / `dev_feat_x` / `master` 등). `/task-close`가 이 브랜치로 되병합한다. `/task-init`이 자동 기록 — 수기 입력 아님. (0.6.0 이전 문서는 이 칸이 없으며, close 시 `dev`로 폴백.)
|
|
26
|
-
- **상태**: 7상태 머신 (1.2 참조) — 표의 *마지막* 컬럼(부모 브랜치가 그 앞)
|
|
27
|
-
|
|
28
|
-
### 1.2 상태 set — 7상태 (-ing/-ed 페어 일관성)
|
|
29
|
-
|
|
30
|
-
```
|
|
31
|
-
draft → planned → developing → developed → testing → tested → closed
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
| 상태 | 시점 | 작성 주체 |
|
|
35
|
-
|------|------|---------|
|
|
36
|
-
| `draft` | task.md 빈 골격 생성 직후 | `/task-init`이 헤더에 작성 |
|
|
37
|
-
| `planned` | plan 완료 (사용자 "이렇게 가자" OK) | `/task-plan` 끝에 메인이 갱신 |
|
|
38
|
-
| `developing` | dev 시작 | `/task-dev` 호출 시 메인 |
|
|
39
|
-
| `developed` | dev 끝 + self-check OK (린트/타입/빌드 PASS) | `/task-dev` 끝에 메인 |
|
|
40
|
-
| `testing` | 격리 세션 진행 중 | `/task-test` 호출 시 메인 |
|
|
41
|
-
| `tested` | 격리 세션 PASS 결과 받은 후 | `/task-test` 끝에 메인 |
|
|
42
|
-
| `closed` | git 마무리 완료 | `/task-close` 끝에 메인 |
|
|
43
|
-
|
|
44
|
-
**FAIL/UNCERTAIN 분기** (세 갈래 — 코드 결함 / 시험문제 결함 / 주관 검수):
|
|
45
|
-
- `/task-test` PASS → `tested` 갱신 → `/task-close` 진행
|
|
46
|
-
- `/task-test` FAIL (**코드 결함**) → 메인이 격리 결과(로그/근거) 보고 → 사용자에게 *"고쳐? OK 마무리?"* 묻기 → "고쳐" 시 `developing`으로 되돌림 → `/task-dev` 재진입
|
|
47
|
-
- `/task-test` UNCERTAIN(**검증 불가 = 시험문제 결함**) → `[AUTO]`인데 대조할 기대값을 구성 못 한 경우. 코드는 멀쩡 → `developing` 아님. **status=`testing` 유지** + `/task-plan`을 *Test Plan 보수 모드*로 재호출(Test Plan 섹션만 보수, Requirements/Scope/Dev Plan/코드 보존) → 보수 후 `/task-test` 재실행. (되돌림용 별도 status 신설 X — 7상태 유지.)
|
|
48
|
-
- `/task-test` UNCERTAIN(**사람 검수**) → 정답지가 주관인 `[USER]` 항목(시각 미세 취향 / UX 느낌). `testing` 유지 + 사용자 직접 검수 → 모두 ✓면 `tested`, ✗면 `developing`(고쳐).
|
|
49
|
-
- `/task-dev` 중 self-check FAIL → `developing` 그대로, 메인 자체 수정 → PASS 시 `developed` 갱신
|
|
50
|
-
|
|
51
|
-
> **시험문제 결함 되돌림이 새 status를 안 만드는 이유**: 새 상태(예: `replanning`)는 -ing/-ed 페어 원칙(본 §1.2)·7상태 고정과 충돌하고 `closed-immutable.sh` 화이트리스트와도 어긋난다. 코드 미변경이라 `developing`을 거칠 이유도 없으므로 `testing`을 유지한 채 Test Plan만 보수한다.
|
|
52
|
-
|
|
53
|
-
### 1.3 섹션 구성 — 6 섹션
|
|
54
|
-
|
|
55
|
-
```markdown
|
|
56
|
-
# TASK-NNN — <태스크 이름>
|
|
57
|
-
|
|
58
|
-
| 생성일 | 플랜 | 유형 | 규모 | 부모 브랜치 | 상태 |
|
|
59
|
-
|--------|------|------|------|-------------|------|
|
|
60
|
-
| ... | ... | ... | ... | ... | ... |
|
|
61
|
-
|
|
62
|
-
## Requirements
|
|
63
|
-
<요구사항 + 메인이 증폭/구체화한 내용>
|
|
64
|
-
|
|
65
|
-
## Scope
|
|
66
|
-
<영향 범위 — 어느 파일의 어느 로직 / 신규 파일 / 등>
|
|
67
|
-
|
|
68
|
-
## Dev Plan
|
|
69
|
-
|
|
70
|
-
### Phase 1 — <짧은 이름>
|
|
71
|
-
- 파일: ...
|
|
72
|
-
- 왜: ...
|
|
73
|
-
- 어떻게: ...
|
|
74
|
-
- 완료 기준: ...
|
|
75
|
-
- 진행: [ ]
|
|
76
|
-
|
|
77
|
-
### Phase 2 — <짧은 이름>
|
|
78
|
-
- ...
|
|
79
|
-
|
|
80
|
-
## Test Plan
|
|
81
|
-
<테스트 방법 — /task-test 격리 세션이 그대로 수행>
|
|
82
|
-
|
|
83
|
-
## Result
|
|
84
|
-
<진행 결과 + 테스트 결과 통합>
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
- Header 섹션은 *별도 헤딩 없이* 표 자체. 그 위 `# TASK-NNN — 이름`은 파일 제목.
|
|
88
|
-
- Phase는 Dev Plan 안 sub-섹션. 별도 파일 X. 진행하며 점진적으로 추가.
|
|
89
|
-
|
|
90
|
-
### 1.4 폐기된 항목
|
|
91
|
-
|
|
92
|
-
- **revision/approved 상태 단계 폐기**: 11상태 → 7상태 단순화. *대화로 OK = 다음 상태로 자동 전이*.
|
|
93
|
-
- **프로젝트 컬럼**: `.project/` 폴더 자체가 프로젝트라 중복.
|
|
94
|
-
- **우선순위 컬럼**: 단독 task 흐름에서 의미 약함. 필요해지면 PLAYBOOK §8 부활.
|
|
95
|
-
- **Phase 별 파일 분리**: waterfall 선제적 작성 함정. Dev Plan 안 sub-섹션으로 점진 추가.
|
|
96
|
-
|
|
97
|
-
### 1.5 task 파일 / 폴더 / 부속 자료 위치 (단일 진실 소스)
|
|
98
|
-
|
|
99
|
-
| 항목 | 위치 | 작성 주체 |
|
|
100
|
-
|------|------|---------|
|
|
101
|
-
| 단일 파일 task | `.project/tasks/<NNN_slug>/<NNN>_<slug>.md` (예: `001_login-feature.md`) | `/task-init` |
|
|
102
|
-
| 폴더 승격 task | `.project/tasks/<NNN_slug>/TASK-<NNN>_<slug>/task.md` | `/task-init` (*사용자 명시 시에만* — 규모 large여도 자동 승격 X) |
|
|
103
|
-
| spec-diffs (변경된 제품 문서(루트) 추적) | `.project/tasks/<NNN_slug>/spec-diffs/<NNN>_<slug>_spec-diff.md` (**`<NNN_slug>` 공통** — 단일/폴더 모두) | `/task-plan` Step 6 (Phase 0 변경 시) |
|
|
104
|
-
| screenshots (UI 작업 자료) | `.project/tasks/<NNN_slug>/screenshots/<NNN>_*.png` (**`<NNN_slug>` 공통**) | `/task-test` 격리 세션 또는 메인 |
|
|
105
|
-
| mockup (UX/UI HTML 목업) | `.project/tasks/<NNN_slug>/mockup/<task-doc-name>-mockup.html` (**`<NNN_slug>` 공통** — 단일/폴더 모두) | `/task-plan` Step 4.5 (UX/UI task 한정) — 단일 진실 소스 `MOCKUP_RULE.md` |
|
|
106
|
-
| test-plan-origin (출제 분리 B 원문) | `.project/tasks/<NNN_slug>/<NNN>_<slug>_test-plan-origin.md` (**`<NNN_slug>` 공통** — 단일/폴더 모두) | `/task-plan` Step 5-B (분리 적용 task 한정) — B 산출 그대로 보존, `/task-test` 오염 대조의 기준 사본 |
|
|
107
|
-
| 폴더 승격 task의 추가 자료 (서브 문서 등) | `TASK-<NNN>_<slug>/` 안 자유 | 메인 / `/task-dev` |
|
|
108
|
-
|
|
109
|
-
**원칙**:
|
|
110
|
-
- spec-diffs / screenshots / mockup은 *`<NNN_slug>` 공통* — 파일명 NNN prefix 또는 task 문서 파일명으로 task 식별. 폴더 승격 task도 동일 (별도 spec-diffs/screenshots/mockup 만들지 X).
|
|
111
|
-
- `<NNN_slug>` 공통 디렉토리는 `/plan-init`이 mkdir.
|
|
112
|
-
- **spec-diff = per-task 기록** — 그 task가 어느 *제품 문서(`.project/` 루트)*를 NEW/MOD/DEL 했는지의 task 산출물. 제품 문서의 *정식 변경 이력은 git*이 단일 진실이며, 별도 전역 변경 인덱스는 두지 않는다.
|
|
113
|
-
- 폴더 승격은 *task의 추가 자료*용 (서브 문서 / 디자인 자료 등) — *spec-diffs / screenshots / mockup 위치 X*.
|
|
114
|
-
|
|
115
|
-
**closed-immutable hook 보호 범위** — task.md 본 파일만 (단일 파일 또는 폴더 승격 task.md). spec-diffs / screenshots / mockup / 폴더 승격 추가 자료는 *역사적 자료*로 자유 수정. **단 test-plan-origin은 hook 보호 밖이어도 규약상 불변** — 오염 대조의 기준 사본이므로 어떤 주체도 수정하지 않는다.
|
|
116
|
-
|
|
117
|
-
---
|
|
118
|
-
|
|
119
|
-
## 2. 작성 방법 — 단계별 절차
|
|
120
|
-
|
|
121
|
-
### 2.1 헤더 작성 (`/task-init`)
|
|
122
|
-
|
|
123
|
-
1. `tasks/<NNN_slug>/` 디렉토리 안 가장 큰 NNN+1로 task 번호 결정 (예: 기존 002까지 있으면 003)
|
|
124
|
-
2. kebab-slug = 태스크 이름 한국어 → 영어 kebab-case (예: "로그인 기능 추가" → `login-feature`)
|
|
125
|
-
3. 파일명 = `NNN_kebab-slug.md` (예: `003_login-feature.md`). *사용자 명시 시* 폴더 승격 (`TASK-003_login-feature/task.md`) — 규모 large여도 자동 승격 X.
|
|
126
|
-
4. 파일 제목 작성: `# TASK-003 — 로그인 기능 추가`
|
|
127
|
-
5. 헤더 표 작성 (6컬럼 모두 채움):
|
|
128
|
-
- 생성일: 오늘 (YYYY-MM-DD)
|
|
129
|
-
- 플랜: 현재 active plan (예: 001_mvp — `NNN_slug` 폴더명)
|
|
130
|
-
- 유형: 사용자/메인 합의 (feature/bug/...)
|
|
131
|
-
- 규모: 사용자/메인 합의 (micro/small/medium/large)
|
|
132
|
-
- 부모 브랜치: `/task-init`(fork) 시점의 현재 브랜치 — 코드가 자동 기록(수기 X)
|
|
133
|
-
- 상태: `draft` (고정)
|
|
134
|
-
6. 6 섹션 placeholder 작성 (Requirements / Scope / Dev Plan / Test Plan / Result는 빈 헤딩만).
|
|
135
|
-
|
|
136
|
-
### 2.2 Requirements 작성 (`/task-plan` 1단계)
|
|
137
|
-
|
|
138
|
-
1. 사용자 발화 정독 — 무엇을 원하는지 명확화.
|
|
139
|
-
2. 메인이 *증폭/구체화* — 사용자가 빠뜨린 디테일 보충 (예: 에러 처리, 빈 값 처리, 보안 고려).
|
|
140
|
-
3. 사용자 confirm — *"이렇게 이해했는데 맞아?"* 한 번 확인.
|
|
141
|
-
4. Requirements 섹션에 작성:
|
|
142
|
-
- 사용자 원래 요구
|
|
143
|
-
- 메인 증폭 디테일
|
|
144
|
-
- 합의된 최종 요구
|
|
145
|
-
|
|
146
|
-
### 2.3 Scope 작성 (`/task-plan` 2단계)
|
|
147
|
-
|
|
148
|
-
1. 코드베이스 탐색 — Grep / Read / `find` 등으로 *영향 받을 파일* 찾기.
|
|
149
|
-
2. 관련 파일 목록 작성:
|
|
150
|
-
- 수정될 파일 (어느 함수/로직)
|
|
151
|
-
- 신규 파일 (예상 경로/역할)
|
|
152
|
-
- 인접 파일 (간접 영향 가능성)
|
|
153
|
-
3. Scope 섹션에 작성 — *"이 task가 다루는 영역은 이 범위"* 정의.
|
|
154
|
-
|
|
155
|
-
### 2.4 Dev Plan 작성 (`/task-plan` 3단계)
|
|
156
|
-
|
|
157
|
-
1. 구현 파트 식별 — 규모(micro/small/medium/large)에 따라 1~8+ phase.
|
|
158
|
-
2. 각 phase = 독립 단위 (커밋 1개 단위로 의미 있는 단위).
|
|
159
|
-
3. 각 phase에 5 필드:
|
|
160
|
-
- **파일**: 변경 대상 (예: `src/auth/login.ts`)
|
|
161
|
-
- **왜**: 이 phase의 동기/목적
|
|
162
|
-
- **어떻게**: 구현 방법 요약 (1~3줄)
|
|
163
|
-
- **완료 기준**: 이 phase가 끝났다고 판단할 기준 (예: "API endpoint 응답 200 반환")
|
|
164
|
-
- **진행**: `[ ]` (미완료) / `[x]` (완료)
|
|
165
|
-
4. **Phase 점진 추가 OK** — 처음에 medium 규모 task의 phase 4개만 작성하고, 진행 중 phase 5 추가 가능. waterfall 선제적 작성 금지.
|
|
166
|
-
|
|
167
|
-
### 2.5 Test Plan 작성 (`/task-plan` 4단계)
|
|
168
|
-
|
|
169
|
-
**본질** — Test Plan = *본 task에서 구현한 요구사항이 정상 동작하는지* 검증 시나리오. **유닛 테스트 X** (유닛 테스트는 `/task-dev` Step 6.5에서 단일 시점 실행 — 코드 정상성 영역, Test Plan과 직교).
|
|
170
|
-
|
|
171
|
-
**검증 대상**:
|
|
172
|
-
- 기능 동작: 사용자 입력 → 기대 결과 / API 호출 → 응답 / 데이터 처리 → 상태 변화
|
|
173
|
-
- UX/UI 동작: 클릭 → 결과 / 호버 → 상태 / 드래그 → 위치 변경
|
|
174
|
-
- UX/UI 시각: 레이아웃 / 색상 / 간격 / 호버 효과 (목업 기준)
|
|
175
|
-
- 백엔드 동작: 시스템 호출 → 외부 응답 / 사이드 이펙트 / 에러 처리
|
|
176
|
-
|
|
177
|
-
**시나리오 형식** — 모든 `[AUTO]` = [실행 명령/입력] + [구체적·관측 가능한 기대값] 한 쌍:
|
|
178
|
-
|
|
179
|
-
```markdown
|
|
180
|
-
## Test Plan
|
|
181
|
-
|
|
182
|
-
| # | 시나리오 | 분류 | 방식 | PASS 기준 (구체적 기대값) |
|
|
183
|
-
|---|---------|------|------|----------|
|
|
184
|
-
| 1 | <쪼갠 장면 한 줄: 무엇을 실행> | [AUTO] / [USER] | <카탈로그 방식> | <관측 가능한 구체값 — 출력/상태코드/조회결과/화면상태> |
|
|
185
|
-
| 2 | ... | ... | ... | ... |
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
- **소원 금지** — "정상 동작 / 잘 됨 / 확인한다"는 PASS 기준이 아님. 눈에 보이는 결과여야 함.
|
|
189
|
-
- **장면 쪼개기** — 한 덩어리 금지, 진짜 떨어질 장면 여러 개로.
|
|
190
|
-
- **잣대** — "고장나면 어떻게 걸리나"를 못 적는 장면 = 버린다. (이게 task-test "문 앞 검사" 자격 — 미달 시 *시험문제 결함*으로 반려됨.)
|
|
191
|
-
|
|
192
|
-
**분류 강제**:
|
|
193
|
-
- `[AUTO]` — 정답지(구체적 기대값)를 구성할 수 있는 영역. 격리 세션이 *실제 명령 실행 + 결과 로그* 확보 → 기대값과 일치 시만 PASS. **시각 *객관* 깨짐(레이아웃/요소 유무/색/배치)도 `[AUTO]`** (캡처-목업 대조, 목업이 정답지).
|
|
194
|
-
- `[USER]` — *정답지가 주관*인 영역만 (시각 미세 취향 / 색조·2px / UX 느낌). 격리 세션은 UNCERTAIN(사람 검수) 분류 + *사용자 직접 검수 항목*으로 리턴(증거 캡처 첨부). UI 인터랙션은 E2E 도구 있으면 `[AUTO]`, 없으면 `[USER]`.
|
|
195
|
-
|
|
196
|
-
**방식 선택 규칙** (요구사항 성격 → 필수 방식, 재량 0): 화면 변경→시각 / 상호작용→UI 동작 / 엔드포인트→API / 데이터 쓰기→상태 조회 / 순수 계산→입출력 / 기존 영역 건드림→회귀. 여러 개 걸리면 다 붙인다.
|
|
197
|
-
|
|
198
|
-
**방식 카탈로그** (시나리오마다 1개 이상 — 각 방식은 *비교할 정답지*가 다름):
|
|
199
|
-
|
|
200
|
-
| 방식 | 적용 영역 | 정답지 | 누가 검사 |
|
|
201
|
-
|------|----------|------|------|
|
|
202
|
-
| 수동 검수 | UI 미세 / UX 느낌 | 주관(목업·사용감) | 사람 (증거 첨부) |
|
|
203
|
-
| 시나리오 스크립트 실행 | 백엔드 / 통합 흐름 (end-to-end script) | 구체적 출력·종료코드 | test 자동 |
|
|
204
|
-
| API/엔드포인트 호출 | 백엔드 / 외부 인터페이스 | 상태코드 + 응답 필드값 | test 자동 |
|
|
205
|
-
| 입출력 비교 | 함수 / 변환 / 처리 | 구체적 기대 출력 (snapshot / golden) | test 자동 |
|
|
206
|
-
| 사이드 이펙트 확인 | DB / 파일 / 로그 | 조회 결과(행/파일/카운트) | test 자동 |
|
|
207
|
-
| 시각 (캡처-목업 대조) | UI 레이아웃/색/배치 | 승인된 목업 | test 자동 (+ 미세는 사람) |
|
|
208
|
-
| 회귀 시나리오 | 기존 기능 영향 | 이전과 동일 결과 | test 자동 |
|
|
209
|
-
| E2E 자동화 도구 | UI 동작 자동화 | 액션 후 관측 변화 | 도구면 test, 아니면 사람 |
|
|
210
|
-
|
|
211
|
-
**관통 규칙**: 어느 방식이든 *실제 관측 결과* == *구체적 정답지*여야 PASS. 정답지가 주관이면 사람한테(단 증거 깔고). 어느 방식도 코드 정독·grep으로 PASS 대체 금지.
|
|
212
|
-
|
|
213
|
-
**UX/UI 영역 분리** (UX/UI 구현 task 한정):
|
|
214
|
-
|
|
215
|
-
| 영역 | 분류 | 기준 |
|
|
216
|
-
|------|------|------|
|
|
217
|
-
| 동작 (클릭 / 호버 / 드래그 / 입력 → 결과) | 도구 있으면 `[AUTO]` E2E, 없으면 `[USER]` | 액션 후 관측 변화 |
|
|
218
|
-
| 시각 *객관* (레이아웃 / 요소 유무 / 색 / 배치 깨짐) | `[AUTO]` 캡처-목업 대조 | 승인 목업 (`mockup/<task-doc-name>-mockup.html`) — 화면 캡처 → 대조 → 어긋남 목록 |
|
|
219
|
-
| 시각 *미세 취향* (2px / 색조 / 호버 강도 / 느낌) | `[USER]` 체크리스트 + 목업 참조 | 사용자 최종 사인 (증거 캡처) |
|
|
220
|
-
|
|
221
|
-
**기대값 출처 표기** (UX/UI task 한정) — 모든 `[AUTO]` PASS 기준 끝에 출처를 단다: `(출처: 목업 §N / Req N)`. 출처를 못 다는 기대값은 `(출처 없음 — 사용자 확인 필요)`로 표기해 합의 때 사용자 확인 항목으로 분리한다. task-test 문 앞 검사의 자격 요건이다.
|
|
222
|
-
|
|
223
|
-
**출제 분리 계약** (해석 여지 태스크 — task-plan Step 2.5 / 5-B):
|
|
224
|
-
- 출제 주체 = 격리 서브에이전트 **B** (입력 = Requirements 합의문 + 승인 목업 + `TEST_RULE.local.md`만 — B 기동 시점에 Dev Plan 부재). B 원문은 `<NNN>_<slug>_test-plan-origin.md`로 그대로 보존한다 (§1.5).
|
|
225
|
-
- **A(메인)의 수정권 = 방식 칸만**, 그것도 `TEST_RULE.local.md` 등재 경로로 교체할 때만. **시나리오 칸·PASS 기준 칸 불가침.**
|
|
226
|
-
- **플래그 문법** — origin과 달라지는 모든 칸에 필수: `【<A수정|사용자결정|보수> · 원안: "<원문>"(· 근거: TEST_RULE.local.md §<절> — A수정만)】`. 정당 경로 3종 = A수정(방식 교체) / 사용자결정(Step 7 합의 변경) / 보수(Test Plan 보수 모드). **무플래그 차이 = task-test가 시험지 오염으로 즉시 반려.**
|
|
227
|
-
- task-test는 origin 대조(룰 18)로 오염을 검사하고, 오염 판정 시 메인이 origin 기준으로 복원한다.
|
|
228
|
-
|
|
229
|
-
**시각 영역 fix 사이클 사전 예고** — 시각 시나리오 있으면 Test Plan 끝에 *"시각 영역 항목 N개 — fix 사이클 1~2회 예상"* 명시 (사용자 기대치 사전 정렬).
|
|
230
|
-
|
|
231
|
-
**검증 / 테스트 명령 참조** — `AGENTS.md`의 `## 검증 명령` (코드 상태: 빌드 / 린트 / 타입체크) + `## 테스트 명령` (테스트 실행: 단위 / 통합 / E2E) 두 섹션을 격리 세션이 자동 참조. Test Plan 본문에 재인용 불필요.
|
|
232
|
-
|
|
233
|
-
**가이드라인**:
|
|
234
|
-
- **자기완결적**: `/task-test` 격리 세션이 *task.md만 보고도* 수행 가능. 메인의 plan/dev 컨텍스트 없이.
|
|
235
|
-
- **명령 / 기대값 포함**: 무엇을 실행하고 무엇이 기대되는지 명확.
|
|
236
|
-
- **메인 가정 X**: 격리 세션이 *코드와 동작만 신뢰*. *"잘 될 거야"* 같은 가정 금지.
|
|
237
|
-
- **grep/Read-only 존재 확인 시나리오 = 보조용, PASS 대체 영구 금지** (stash FRICTION_LOG 2026-06-01 반영) — 구현 코드의 존재 여부를 grep/Read로 재확인하는 시나리오는 *동어반복*. PASS 카운트에서 제외, 실동작 시나리오의 *보조*로만. grep으로 실동작 검증 *대체 불가* (task-test 룰 10과 동일 강도).
|
|
238
|
-
- **요구사항당 end-to-end 1개 이상 강제** — Requirements 각 항목이 *사용자 관점에서 실제 작동하는지* 검증하는 end-to-end 실동작 시나리오 최소 1개 보장. 산출물 실행 → 결과 확인 형태.
|
|
239
|
-
- **무거운 검증 회피 영구 금지** — 부담(빌드 수 분+ / 외부 의존 / 환경 설정) 이유로 실동작 시나리오를 grep 동어반복으로 대체 X. 최소 1회는 실제 산출물로 확인. 부담은 *fix 사이클 1~2회 예상* 같은 사전 예고로 처리 (생략 사유 X).
|
|
240
|
-
|
|
241
|
-
**요구사항 ↔ 시나리오 커버리지 점검** (필수 — stash FRICTION_LOG 2026-06-01 반영):
|
|
242
|
-
|
|
243
|
-
Test Plan 작성 완료 후 *반드시* 점검. *"누적/리셋 안 함"* 같은 요구사항이 시나리오에서 통째로 빠지는 누락 차단용.
|
|
244
|
-
|
|
245
|
-
1. Requirements 합의 항목 전체를 *매트릭스*로 펼침.
|
|
246
|
-
2. 각 항목당 *최소 1개 시나리오 커버* 확인.
|
|
247
|
-
3. 미커버 발견 시 → 시나리오 보강 후 재점검.
|
|
248
|
-
|
|
249
|
-
형식 (Test Plan 끝에 첨부):
|
|
250
|
-
|
|
251
|
-
```markdown
|
|
252
|
-
### Requirements ↔ Test Plan 매트릭스
|
|
253
|
-
|
|
254
|
-
| 요구사항 | 커버 시나리오 # |
|
|
255
|
-
|---------|----------------|
|
|
256
|
-
| <Req 1 한 줄> | #1, #3 |
|
|
257
|
-
| <Req 2 한 줄> | #2 (end-to-end) |
|
|
258
|
-
| <Req 3 한 줄> | #5 |
|
|
259
|
-
```
|
|
260
|
-
|
|
261
|
-
### 2.6 Result 기록 (`/task-dev`, `/task-test` 끝)
|
|
262
|
-
|
|
263
|
-
1. `/task-dev` 끝에 phase별 진행 결과 기록:
|
|
264
|
-
- 각 phase 완료 → `진행: [x]` 갱신
|
|
265
|
-
- 변경 파일 목록 / 코드 요약 추가
|
|
266
|
-
2. `/task-test` 끝에 격리 세션 결과 기록:
|
|
267
|
-
- PASS / FAIL / UNCERTAIN
|
|
268
|
-
- 근거 (로그 인용)
|
|
269
|
-
- FAIL 시 무엇이 깨졌는지
|
|
270
|
-
|
|
271
|
-
---
|
|
272
|
-
|
|
273
|
-
## 3. 가이드라인
|
|
274
|
-
|
|
275
|
-
### 3.1 일관성
|
|
276
|
-
|
|
277
|
-
- 양식 그대로 채워. 섹션 추가/삭제 금지.
|
|
278
|
-
- 헤더 6컬럼 모두 채움 — *"미정"* 같은 placeholder 금지 (의사결정 위임 X). 부모 브랜치는 코드 자동 기록.
|
|
279
|
-
- 상태 7개 외 단어 사용 금지.
|
|
280
|
-
|
|
281
|
-
### 3.2 자기완결성
|
|
282
|
-
|
|
283
|
-
- task.md 하나만 보고도 *Requirements 이해 / Scope 파악 / Dev 재현 / Test 수행* 가능해야.
|
|
284
|
-
- 다른 문서 참조는 *"§ARCHITECTURE.md 1.2 참조"* 식으로 명시. 묵시적 의존 X.
|
|
285
|
-
|
|
286
|
-
### 3.3 메인 가정 X
|
|
287
|
-
|
|
288
|
-
- Test Plan에 *"잘 될 거야"* / *"문제 없을 듯"* 같은 가정 금지.
|
|
289
|
-
- *코드와 동작만 신뢰*. 격리 세션이 가정 없이 수행 가능하게.
|
|
290
|
-
|
|
291
|
-
### 3.4 점진 작성 OK
|
|
292
|
-
|
|
293
|
-
- Phase 선제적 일괄 작성 금지. 진행하며 점진적으로 추가.
|
|
294
|
-
- 단 *전체 스코프*는 처음에 정의 (Scope 섹션). 스코프가 진행 중 늘어나면 *task 분리 검토*.
|
|
295
|
-
|
|
296
|
-
### 3.5 짧고 명확하게
|
|
297
|
-
|
|
298
|
-
- 각 섹션 verbose 금지. 한국어/영어 혼용 OK.
|
|
299
|
-
- bullet point 활용. 산문 단락 최소화.
|
|
300
|
-
|
|
301
|
-
---
|
|
302
|
-
|
|
303
|
-
## 4. 섹션별 짧은 설명 + 예시 스니펫
|
|
304
|
-
|
|
305
|
-
### 4.1 Header
|
|
306
|
-
|
|
307
|
-
**역할**: task 메타 정보. 한 눈에 *언제 / 어느 plan / 무슨 작업 / 얼마만큼 / 지금 어디*.
|
|
308
|
-
|
|
309
|
-
```markdown
|
|
310
|
-
# TASK-007 — 로그인 폼 유효성 검증
|
|
311
|
-
|
|
312
|
-
| 생성일 | 플랜 | 유형 | 규모 | 상태 |
|
|
313
|
-
|--------|------|------|------|------|
|
|
314
|
-
| 2026-05-08 | 001_mvp | feature | small | planned |
|
|
315
|
-
```
|
|
316
|
-
|
|
317
|
-
### 4.2 Requirements
|
|
318
|
-
|
|
319
|
-
**역할**: 사용자 요구 + 메인 증폭. *"무엇을 만드는가"*.
|
|
320
|
-
|
|
321
|
-
```markdown
|
|
322
|
-
## Requirements
|
|
323
|
-
|
|
324
|
-
사용자 요구:
|
|
325
|
-
- 로그인 폼에 이메일/비밀번호 유효성 검증 추가
|
|
326
|
-
|
|
327
|
-
메인 증폭:
|
|
328
|
-
- 빈 값 / 형식 오류 / 길이 부족 케이스 모두 메시지 표시
|
|
329
|
-
- 검증 통과 후에만 API 호출 (네트워크 낭비 회피)
|
|
330
|
-
- 메시지는 i18n 대응 (한국어 / 영어 분기)
|
|
331
|
-
|
|
332
|
-
합의:
|
|
333
|
-
- 위 3가지 모두 적용. i18n은 기존 방식(react-i18next) 그대로 사용.
|
|
334
|
-
```
|
|
335
|
-
|
|
336
|
-
### 4.3 Scope
|
|
337
|
-
|
|
338
|
-
**역할**: 영향 범위. *"어느 파일 어느 로직 다루는가"*.
|
|
339
|
-
|
|
340
|
-
```markdown
|
|
341
|
-
## Scope
|
|
342
|
-
|
|
343
|
-
수정:
|
|
344
|
-
- `src/components/LoginForm.tsx` — 폼 onSubmit + 입력 onChange
|
|
345
|
-
- `src/utils/validation.ts` — 신규 헬퍼 (validateEmail / validatePassword)
|
|
346
|
-
- `src/i18n/ko.json` / `src/i18n/en.json` — 검증 메시지 키 추가
|
|
347
|
-
|
|
348
|
-
신규:
|
|
349
|
-
- `src/utils/validation.test.ts` — 헬퍼 단위 테스트
|
|
350
|
-
|
|
351
|
-
인접 (간접 영향 가능):
|
|
352
|
-
- `src/api/auth.ts` — 호출 시점 변경 (검증 통과 후)
|
|
353
|
-
```
|
|
354
|
-
|
|
355
|
-
### 4.4 Dev Plan
|
|
356
|
-
|
|
357
|
-
**역할**: 구현 phase 분할. *"어떻게 만드는가"*.
|
|
358
|
-
|
|
359
|
-
```markdown
|
|
360
|
-
## Dev Plan
|
|
361
|
-
|
|
362
|
-
### Phase 1 — validation.ts 헬퍼 작성
|
|
363
|
-
- 파일: `src/utils/validation.ts`
|
|
364
|
-
- 왜: 폼 입력 검증 로직 분리, 단위 테스트 가능 단위로
|
|
365
|
-
- 어떻게: validateEmail (regex) + validatePassword (길이 8+) export
|
|
366
|
-
- 완료 기준: validation.test.ts PASS
|
|
367
|
-
- 진행: [x]
|
|
368
|
-
|
|
369
|
-
### Phase 2 — LoginForm 통합
|
|
370
|
-
- 파일: `src/components/LoginForm.tsx`
|
|
371
|
-
- 왜: 폼 onSubmit/onChange에서 헬퍼 호출
|
|
372
|
-
- 어떻게: useState로 errors 관리, validateEmail/Password 결과 setErrors
|
|
373
|
-
- 완료 기준: 폼 빈 값 제출 → 메시지 표시 / 정상값 → API 호출
|
|
374
|
-
- 진행: [x]
|
|
375
|
-
|
|
376
|
-
### Phase 3 — i18n 메시지 추가
|
|
377
|
-
- 파일: `src/i18n/ko.json` / `src/i18n/en.json`
|
|
378
|
-
- 왜: 한국어/영어 메시지 분기
|
|
379
|
-
- 어떻게: validation.email.empty / validation.email.format / validation.password.short 키 추가
|
|
380
|
-
- 완료 기준: 언어 전환 시 메시지 따라 변경 확인
|
|
381
|
-
- 진행: [ ]
|
|
382
|
-
```
|
|
383
|
-
|
|
384
|
-
### 4.5 Test Plan
|
|
385
|
-
|
|
386
|
-
**역할**: 격리 세션이 그대로 수행할 검증. *"제대로 됐는지 어떻게 확인하는가"*.
|
|
387
|
-
|
|
388
|
-
```markdown
|
|
389
|
-
## Test Plan
|
|
390
|
-
|
|
391
|
-
| # | 시나리오 | 분류 | 방식 | PASS 기준 |
|
|
392
|
-
|---|---------|------|------|----------|
|
|
393
|
-
| 1 | 빈 이메일 + 비밀번호 제출 | [USER] | 수동 검수 | "이메일 입력 필요" + "비밀번호 입력 필요" 표시, API 호출 X |
|
|
394
|
-
| 2 | 잘못된 이메일 형식 ("abc") | [USER] | 수동 검수 | "올바른 이메일 형식 아님" 표시, API 호출 X |
|
|
395
|
-
| 3 | 짧은 비밀번호 ("123") | [USER] | 수동 검수 | "비밀번호 8자 이상 필요" 표시, API 호출 X |
|
|
396
|
-
| 4 | 정상값 제출 | [USER] | 수동 검수 | API 호출 → 정상 응답 시 / 리다이렉트 |
|
|
397
|
-
| 5 | 한국어 ↔ 영어 전환 | [USER] | 수동 검수 | 메시지 언어 따라 변경 |
|
|
398
|
-
```
|
|
399
|
-
|
|
400
|
-
> 검증 명령 / 테스트 명령은 `AGENTS.md` 두 섹션을 격리 세션이 자동 참조 — Test Plan 본문 재인용 X.
|
|
401
|
-
|
|
402
|
-
### 4.6 Result
|
|
403
|
-
|
|
404
|
-
**역할**: 진행 + 테스트 결과 통합. *"실제로 어떻게 됐는가"*.
|
|
405
|
-
|
|
406
|
-
```markdown
|
|
407
|
-
## Result
|
|
408
|
-
|
|
409
|
-
### 진행
|
|
410
|
-
- Phase 1: validation.ts 작성, validation.test.ts 12 케이스 PASS.
|
|
411
|
-
- Phase 2: LoginForm 통합 완료. errors state로 메시지 렌더링.
|
|
412
|
-
- Phase 3: i18n 키 6개 추가, 언어 전환 시나리오 확인.
|
|
413
|
-
|
|
414
|
-
### 테스트 (격리 세션 결과)
|
|
415
|
-
- **PASS**.
|
|
416
|
-
- 1~6 시나리오 모두 기대대로.
|
|
417
|
-
- 검증 명령 모두 PASS.
|
|
418
|
-
- 근거: 격리 세션 로그 — `validation.test.ts` 12/12 PASS, dev 브라우저 수동 확인 5/5 PASS.
|
|
419
|
-
```
|
|
420
|
-
|
|
421
|
-
---
|
|
422
|
-
|
|
423
|
-
## 5. 완성 예시 — 유형별 3개
|
|
424
|
-
|
|
425
|
-
### 예시 1: chore/micro (한 줄 픽스)
|
|
426
|
-
|
|
427
|
-
```markdown
|
|
428
|
-
# TASK-001 — README.md 오타 수정
|
|
429
|
-
|
|
430
|
-
| 생성일 | 플랜 | 유형 | 규모 | 상태 |
|
|
431
|
-
|--------|------|------|------|------|
|
|
432
|
-
| 2026-05-08 | 001_mvp | chore | micro | closed |
|
|
433
|
-
|
|
434
|
-
## Requirements
|
|
435
|
-
사용자 요구:
|
|
436
|
-
- README.md "Instalation" 오타를 "Installation"으로 수정.
|
|
437
|
-
|
|
438
|
-
## Scope
|
|
439
|
-
수정:
|
|
440
|
-
- `README.md` — 12행 한 줄.
|
|
441
|
-
|
|
442
|
-
## Dev Plan
|
|
443
|
-
|
|
444
|
-
### Phase 1 — 오타 수정
|
|
445
|
-
- 파일: `README.md`
|
|
446
|
-
- 왜: 표기 오류
|
|
447
|
-
- 어떻게: 12행 "Instalation" → "Installation"
|
|
448
|
-
- 완료 기준: 파일 내 검색 결과 0건
|
|
449
|
-
- 진행: [x]
|
|
450
|
-
|
|
451
|
-
## Test Plan
|
|
452
|
-
|
|
453
|
-
| # | 시나리오 | 분류 | 방식 | PASS 기준 |
|
|
454
|
-
|---|---------|------|------|----------|
|
|
455
|
-
| 1 | README.md 안 오타 검색 | [AUTO] | 시나리오 스크립트 실행 | `grep -n "Instalation" README.md` 결과 0건 |
|
|
456
|
-
| 2 | README.md 안 정정 표기 검색 | [AUTO] | 시나리오 스크립트 실행 | `grep -n "Installation" README.md` 결과 1건 이상 |
|
|
457
|
-
|
|
458
|
-
## Result
|
|
459
|
-
|
|
460
|
-
### 진행
|
|
461
|
-
- Phase 1: 12행 sed 1회 수정.
|
|
462
|
-
|
|
463
|
-
### 테스트 (격리 세션 결과)
|
|
464
|
-
- **PASS**.
|
|
465
|
-
- `grep -n "Instalation" README.md` → 0건.
|
|
466
|
-
- `grep -n "Installation" README.md` → 1건 (12행).
|
|
467
|
-
```
|
|
468
|
-
|
|
469
|
-
---
|
|
470
|
-
|
|
471
|
-
### 예시 2: feature/medium (로그인 기능)
|
|
472
|
-
|
|
473
|
-
```markdown
|
|
474
|
-
# TASK-007 — JWT 기반 로그인 기능
|
|
475
|
-
|
|
476
|
-
| 생성일 | 플랜 | 유형 | 규모 | 상태 |
|
|
477
|
-
|--------|------|------|------|------|
|
|
478
|
-
| 2026-05-08 | 001_mvp | feature | medium | tested |
|
|
479
|
-
|
|
480
|
-
## Requirements
|
|
481
|
-
사용자 요구:
|
|
482
|
-
- 이메일/비밀번호 로그인 기능 추가.
|
|
483
|
-
- JWT 토큰으로 세션 관리.
|
|
484
|
-
|
|
485
|
-
메인 증폭:
|
|
486
|
-
- 비밀번호는 bcrypt 해시 비교 (DB 평문 저장 금지).
|
|
487
|
-
- JWT 만료 24시간, refresh token 별도 (만료 7일).
|
|
488
|
-
- 잘못된 자격증명 시 동일 메시지 (*"이메일 또는 비밀번호가 올바르지 않습니다"*) — enumeration 방어.
|
|
489
|
-
- rate limit (분당 10회) 추가.
|
|
490
|
-
|
|
491
|
-
합의:
|
|
492
|
-
- 위 모두 적용. refresh token은 httpOnly cookie로.
|
|
493
|
-
|
|
494
|
-
## Scope
|
|
495
|
-
수정:
|
|
496
|
-
- `src/api/auth.ts` — login 엔드포인트 추가
|
|
497
|
-
- `src/middleware/jwt.ts` — JWT 검증 미들웨어 (신규)
|
|
498
|
-
- `src/middleware/rateLimit.ts` — express-rate-limit 통합 (신규)
|
|
499
|
-
- `src/db/users.ts` — findByEmail 쿼리 추가
|
|
500
|
-
- `src/utils/password.ts` — bcrypt compare 헬퍼 (신규)
|
|
501
|
-
|
|
502
|
-
신규:
|
|
503
|
-
- `src/api/auth.test.ts` — 로그인 엔드포인트 통합 테스트
|
|
504
|
-
|
|
505
|
-
인접 (간접 영향):
|
|
506
|
-
- `src/app.ts` — 미들웨어 체인 등록
|
|
507
|
-
- `src/types/index.ts` — JwtPayload 타입 추가
|
|
508
|
-
|
|
509
|
-
## Dev Plan
|
|
510
|
-
|
|
511
|
-
### Phase 1 — password.ts bcrypt 헬퍼
|
|
512
|
-
- 파일: `src/utils/password.ts`
|
|
513
|
-
- 왜: 비밀번호 해시 비교 분리, 단위 테스트 가능
|
|
514
|
-
- 어떻게: bcrypt.compare(plain, hash) wrapper export
|
|
515
|
-
- 완료 기준: 단위 테스트 PASS (정상/오류 케이스)
|
|
516
|
-
- 진행: [x]
|
|
517
|
-
|
|
518
|
-
### Phase 2 — users.ts findByEmail
|
|
519
|
-
- 파일: `src/db/users.ts`
|
|
520
|
-
- 왜: 이메일로 사용자 조회 쿼리
|
|
521
|
-
- 어떻게: prisma.user.findUnique({ where: { email } })
|
|
522
|
-
- 완료 기준: 존재/미존재 케이스 모두 정상 동작
|
|
523
|
-
- 진행: [x]
|
|
524
|
-
|
|
525
|
-
### Phase 3 — jwt.ts 미들웨어
|
|
526
|
-
- 파일: `src/middleware/jwt.ts`
|
|
527
|
-
- 왜: 보호 라우트에 JWT 검증
|
|
528
|
-
- 어떻게: jsonwebtoken verify, payload를 req.user에 담음. 만료/무효 시 401
|
|
529
|
-
- 완료 기준: 유효 토큰 통과 / 무효 토큰 401 반환
|
|
530
|
-
- 진행: [x]
|
|
531
|
-
|
|
532
|
-
### Phase 4 — rateLimit.ts 미들웨어
|
|
533
|
-
- 파일: `src/middleware/rateLimit.ts`
|
|
534
|
-
- 왜: 무차별 시도 방어
|
|
535
|
-
- 어떻게: express-rate-limit (분당 10회)
|
|
536
|
-
- 완료 기준: 11번째 요청 429 반환
|
|
537
|
-
- 진행: [x]
|
|
538
|
-
|
|
539
|
-
### Phase 5 — auth.ts login 엔드포인트
|
|
540
|
-
- 파일: `src/api/auth.ts`
|
|
541
|
-
- 왜: 실제 로그인 처리
|
|
542
|
-
- 어떻게: email로 user 조회 → bcrypt 비교 → JWT 발급 + refresh token (httpOnly cookie)
|
|
543
|
-
- 완료 기준: 정상 로그인 200 + JSON { token } / 실패 401
|
|
544
|
-
- 진행: [x]
|
|
545
|
-
|
|
546
|
-
### Phase 6 — app.ts 미들웨어 체인
|
|
547
|
-
- 파일: `src/app.ts`
|
|
548
|
-
- 왜: jwt + rateLimit 등록
|
|
549
|
-
- 어떻게: app.use("/api/auth", rateLimit, authRouter); 보호 라우트에 jwt 미들웨어
|
|
550
|
-
- 완료 기준: 통합 테스트 PASS
|
|
551
|
-
- 진행: [x]
|
|
552
|
-
|
|
553
|
-
## Test Plan
|
|
554
|
-
|
|
555
|
-
| # | 시나리오 | 분류 | 방식 | PASS 기준 |
|
|
556
|
-
|---|---------|------|------|----------|
|
|
557
|
-
| 1 | 정상 로그인 | [AUTO] | API/엔드포인트 호출 | POST /api/auth/login {email, password} → 200, body {token}, Set-Cookie: refreshToken |
|
|
558
|
-
| 2 | 잘못된 비밀번호 | [AUTO] | API/엔드포인트 호출 | 401, body {error: "이메일 또는 비밀번호가 올바르지 않습니다"} |
|
|
559
|
-
| 3 | 미등록 이메일 (enumeration 방어) | [AUTO] | API/엔드포인트 호출 | 401, body 메시지 #2와 동일 |
|
|
560
|
-
| 4 | 빈 입력 / 형식 오류 | [AUTO] | API/엔드포인트 호출 | 400, validation 에러 |
|
|
561
|
-
| 5 | JWT 검증 — 유효 토큰 | [AUTO] | API/엔드포인트 호출 | GET /api/protected with Authorization → 200 |
|
|
562
|
-
| 6 | JWT 검증 — 만료 / 무효 | [AUTO] | API/엔드포인트 호출 | 401 |
|
|
563
|
-
| 7 | Rate limit (11회 연속) | [AUTO] | 시나리오 스크립트 실행 | 11번째 요청 429, 헤더 X-RateLimit-Remaining: 0 |
|
|
564
|
-
| 8 | Refresh token | [AUTO] | API/엔드포인트 호출 | GET /api/auth/refresh with cookie → 200, 새 token 발급 |
|
|
565
|
-
|
|
566
|
-
## Result
|
|
567
|
-
|
|
568
|
-
### 진행
|
|
569
|
-
- Phase 1: password.ts 작성, 단위 테스트 PASS (3 케이스).
|
|
570
|
-
- Phase 2: users.ts findByEmail 추가, prisma 통합 확인.
|
|
571
|
-
- Phase 3: jwt.ts 미들웨어 작성, 단위 테스트 PASS (4 케이스).
|
|
572
|
-
- Phase 4: rateLimit.ts express-rate-limit 통합, 11회 시나리오 확인.
|
|
573
|
-
- Phase 5: auth.ts /login 엔드포인트 완성, 정상/실패 케이스 동작.
|
|
574
|
-
- Phase 6: app.ts 미들웨어 체인 등록, 통합 테스트 PASS.
|
|
575
|
-
|
|
576
|
-
### 테스트 (격리 세션 결과)
|
|
577
|
-
- **PASS**.
|
|
578
|
-
- 1~8 시나리오 모두 기대대로.
|
|
579
|
-
- 검증 명령 모두 PASS.
|
|
580
|
-
- 근거:
|
|
581
|
-
- `npm test src/api/auth.test.ts` → 14/14 PASS
|
|
582
|
-
- 수동 시나리오 1~8 모두 기대 응답 코드/메시지 확인
|
|
583
|
-
- rate limit 11번째 429 확인 (헤더 X-RateLimit-Remaining: 0)
|
|
584
|
-
```
|
|
585
|
-
|
|
586
|
-
---
|
|
587
|
-
|
|
588
|
-
### 예시 3: bug/small (특정 버그 픽스)
|
|
589
|
-
|
|
590
|
-
```markdown
|
|
591
|
-
# TASK-013 — 모바일 사파리에서 폼 제출 시 페이지 새로고침 발생
|
|
592
|
-
|
|
593
|
-
| 생성일 | 플랜 | 유형 | 규모 | 상태 |
|
|
594
|
-
|--------|------|------|------|------|
|
|
595
|
-
| 2026-05-08 | 001_mvp | bug | small | tested |
|
|
596
|
-
|
|
597
|
-
## Requirements
|
|
598
|
-
사용자 보고:
|
|
599
|
-
- 모바일 Safari에서 검색 폼 제출 시 페이지가 새로고침됨. 다른 브라우저는 정상.
|
|
600
|
-
|
|
601
|
-
재현 환경:
|
|
602
|
-
- iOS 17.4 Safari
|
|
603
|
-
- src/components/SearchForm.tsx
|
|
604
|
-
|
|
605
|
-
기대 동작:
|
|
606
|
-
- 폼 제출 시 SPA navigation, 페이지 새로고침 X.
|
|
607
|
-
|
|
608
|
-
## Scope
|
|
609
|
-
수정:
|
|
610
|
-
- `src/components/SearchForm.tsx` — onSubmit 핸들러
|
|
611
|
-
- `src/components/SearchForm.test.tsx` — 회귀 테스트 추가
|
|
612
|
-
|
|
613
|
-
인접 (간접 영향): 없음.
|
|
614
|
-
|
|
615
|
-
## Dev Plan
|
|
616
|
-
|
|
617
|
-
### Phase 1 — preventDefault 호출 누락 픽스
|
|
618
|
-
- 파일: `src/components/SearchForm.tsx`
|
|
619
|
-
- 왜: 모바일 Safari는 form submit 기본 동작이 페이지 새로고침. 다른 브라우저(Chrome 등)는 React가 일부 케이스 자동 차단하지만 Safari는 아님
|
|
620
|
-
- 어떻게: onSubmit handler 첫 줄에 e.preventDefault() 추가
|
|
621
|
-
- 완료 기준: iOS Safari에서 폼 제출 시 새로고침 X (수동 확인)
|
|
622
|
-
- 진행: [x]
|
|
623
|
-
|
|
624
|
-
### Phase 2 — 회귀 테스트 추가
|
|
625
|
-
- 파일: `src/components/SearchForm.test.tsx`
|
|
626
|
-
- 왜: 같은 버그 재발 방지
|
|
627
|
-
- 어떻게: fireEvent.submit + expect(preventDefault) 호출 확인
|
|
628
|
-
- 완료 기준: 단위 테스트 PASS
|
|
629
|
-
- 진행: [x]
|
|
630
|
-
|
|
631
|
-
## Test Plan
|
|
632
|
-
|
|
633
|
-
| # | 시나리오 | 분류 | 방식 | PASS 기준 |
|
|
634
|
-
|---|---------|------|------|----------|
|
|
635
|
-
| 1 | iOS Safari 검색어 입력 후 검색 버튼 클릭 | [USER] | 수동 검수 | 페이지 URL의 search query만 갱신, 새로고침 X (네트워크 탭 document 요청 X) |
|
|
636
|
-
| 2 | 데스크톱 Chrome 동일 동작 (회귀) | [USER] | 수동 검수 | 회귀 X (기존 정상 동작 유지) |
|
|
637
|
-
| 3 | onSubmit handler preventDefault 회귀 테스트 | [AUTO] | 입출력 비교 | fireEvent.submit + expect(preventDefault) 호출 확인 |
|
|
638
|
-
|
|
639
|
-
## Result
|
|
640
|
-
|
|
641
|
-
### 진행
|
|
642
|
-
- Phase 1: SearchForm.tsx onSubmit 첫 줄 e.preventDefault() 추가. 1줄 변경.
|
|
643
|
-
- Phase 2: SearchForm.test.tsx에 회귀 테스트 1 케이스 추가.
|
|
644
|
-
|
|
645
|
-
### 테스트 (격리 세션 결과)
|
|
646
|
-
- **PASS**.
|
|
647
|
-
- iOS 17.4 Safari 수동 확인 — 폼 제출 시 새로고침 X.
|
|
648
|
-
- Chrome 수동 확인 — 회귀 없음.
|
|
649
|
-
- 단위 테스트 PASS.
|
|
650
|
-
- 검증 명령 모두 PASS.
|
|
651
|
-
- 근거:
|
|
652
|
-
- 네트워크 탭 캡처 (document 요청 X)
|
|
653
|
-
- SearchForm.test.tsx 신규 케이스 1/1 PASS
|
|
654
|
-
```
|
|
655
|
-
|
|
656
|
-
---
|
|
657
|
-
|
|
658
|
-
## 6. 수정 이력
|
|
659
|
-
|
|
660
|
-
| 날짜 | 변경 사항 |
|
|
661
|
-
|------|----------|
|
|
662
|
-
| 2026-05-08 | 초안 — 5컬럼 헤더 / 7상태 / 6섹션 / 4단 layer 가이드 / 완성 예시 3개 |
|
|
663
|
-
| 2026-05-08 | §1.5 추가 — task 파일/폴더/부속 자료 위치 단일 진실 소스. spec-diffs/screenshots는 vX.X 공통 통일. closed-immutable hook 보호 범위는 task.md 본 파일만 (스킬 본문 간 위치 모순 통일) |
|
|
664
|
-
| 2026-05-09 | 표현 정제 — 인명 / 경박 표현 / 스킬 용어 / 이전 버전 비교 단락 정리 |
|
|
665
|
-
| 2026-05-30 | stash FRICTION_LOG 기반 정합 — §1.5 mockup 행 추가 (vX.X 공통, 단일 진실 소스 MOCKUP_RULE) + §2.5 Test Plan 본질 재정의 (실질 동작 시나리오 + `[AUTO]` / `[USER]` 분류 강제 + 카탈로그 7방식 + UX/UI 영역 분리 매트릭스 + 시각 fix 사이클 사전 예고 + 검증 / 테스트 명령 두 섹션 참조) + §4.5 / §5 완성 예시 3개 Test Plan 형식 갱신 (분류 표 + PASS 기준 명시. 기존 번호 매김 시나리오 + 검증 명령 나열은 옛 형식). (stash FRICTION_LOG #14+19 / #25 정합) |
|
|
666
|
-
| 2026-06-02 | 0.1.3 F5 정합 — §2.5 가이드라인 안티패턴 3종 추가 (grep/Read-only 보조용 / 요구사항당 end-to-end 1개 이상 / 무거운 검증 회피 금지) + 요구사항 ↔ 시나리오 커버리지 점검 단계 신설 (stash FRICTION_LOG 2026-06-01 Test Plan 동어반복 + 누락 마찰 반영) |
|
|
667
|
-
| 2026-06-27 | PLAYBOOK §13 정합 — plan = 기능 그룹. 헤더 *플랜* 컬럼 = `NNN_slug` 폴더명(예: 001_mvp). §1.5 경로 `tasks/<NNN_slug>/`, *`<NNN_slug>` 공통*으로 통일. spec-diff 정의 = *변경된 제품 문서(루트) 추적*(per-task 기록, 정식 변경 이력은 git 단일 진실) |
|
|
668
|
-
| 2026-08-09 | 출제 분리 정합 — §1.5 test-plan-origin 행 추가(B 원문 보존, 규약상 불변) + §2.5 기대값 출처 표기·출제 분리 계약 명문(방식 칸 불가침 / 플래그 문법 【A수정|사용자결정|보수 · 원안】 / 무플래그 차이=오염 반려). recordion FRICTION 2026-08-09 반영 |
|
|
File without changes
|
|
File without changes
|
|
File without changes
|