@decencia/ch-cli 1.3.6 → 1.5.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.
Files changed (34) hide show
  1. package/agent/2t-decencia-channel-issue-coder.md +63 -0
  2. package/agent/2t-decencia-channel-pr-merger.md +51 -0
  3. package/agent/2t-decencia-channel-terraformer.md +55 -0
  4. package/dist/commands/check.d.ts +3 -0
  5. package/dist/commands/check.d.ts.map +1 -0
  6. package/dist/commands/check.js +227 -0
  7. package/dist/commands/check.js.map +1 -0
  8. package/dist/commands/setup-skill.d.ts.map +1 -1
  9. package/dist/commands/setup-skill.js +73 -10
  10. package/dist/commands/setup-skill.js.map +1 -1
  11. package/dist/index.js +2 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/skill-meta.d.ts +2 -0
  14. package/dist/skill-meta.d.ts.map +1 -0
  15. package/dist/skill-meta.js +15 -0
  16. package/dist/skill-meta.js.map +1 -0
  17. package/package.json +5 -3
  18. package/skill/2t-decencia-channel-change-manager/SKILL.md +73 -0
  19. package/skill/2t-decencia-channel-change-propagation-v2/SKILL.md +401 -0
  20. package/skill/2t-decencia-channel-cli-v2/SKILL.md +194 -0
  21. package/skill/2t-decencia-channel-db-schema-v2/SKILL.md +313 -0
  22. package/skill/2t-decencia-channel-github-issue/SKILL.md +116 -0
  23. package/skill/2t-decencia-channel-orchestrator/SKILL.md +64 -0
  24. package/skill/2t-decencia-channel-prd-v2/SKILL.md +73 -0
  25. package/skill/2t-decencia-channel-project-bootstrap/SKILL.md +68 -0
  26. package/skill/2t-decencia-channel-spec-v2/SKILL.md +463 -0
  27. package/skill/2t-decencia-channel-sprint-builder-v2/SKILL.md +77 -0
  28. package/skill/2t-decencia-channel-sqa-v2/SKILL.md +422 -0
  29. package/skill/2t-decencia-channel-work-status-v2/SKILL.md +189 -0
  30. package/dist/commands/invitations.d.ts +0 -3
  31. package/dist/commands/invitations.d.ts.map +0 -1
  32. package/dist/commands/invitations.js +0 -48
  33. package/dist/commands/invitations.js.map +0 -1
  34. package/skill/SKILL.md +0 -500
@@ -0,0 +1,463 @@
1
+ ---
2
+ name: 2t-decencia-channel-spec-v2
3
+ description: |
4
+ [2t][v2] 소통채널 기능명세(=Story) 작성/수정 표준.
5
+ Epic-Story-Task 구조에서 UI/Logic/DB/Task 필드 각각의 작성 패턴, JSON 템플릿, 입자 기준을 다룬다.
6
+ Spec ID는 JIRA 스타일 사용자 지정(`LOGIN-001`) 또는 자동 생성 선택 가능 — §1.5.
7
+ 작업 일지(workStatus)는 라이프사이클이 달라 [[2t-decencia-channel-work-status-v2]]로 분리.
8
+ Use when:
9
+ (1) spec(=Story)을 작성·수정할 때,
10
+ (2) UI 메타데이터·비즈니스 로직·DB 참조를 함께 다룰 때,
11
+ (3) Task를 JIRA 스타일(points·assignee·description·completedAt)로 잘게 쪼갤 때,
12
+ (4) 신규 spec ID를 `LOGIN-001` 같은 JIRA 스타일로 부여하고 싶을 때 (`ch specs create --id`).
13
+ version: 1.5.0
14
+ ---
15
+
16
+ <!-- ch-version-gate -->
17
+ ## ⚠️ 시작 전 필수 — 버전 게이트 (생략 금지)
18
+
19
+ 이 스킬로 **어떤 작업이든 수행하기 전에 가장 먼저** 아래를 실행한다:
20
+
21
+ ```bash
22
+ ch check
23
+ ```
24
+
25
+ - exit code 0(통과)이 **아니면 즉시 중단**한다. 출력에 안내된 업데이트 명령(`npm install -g @decencia/ch-cli@latest` 또는 `ch setup-skill`)을 사용자에게 전달하고, 갱신이 끝나기 전까지 **이 스킬의 어떤 단계도 진행하지 않는다.**
26
+ - `ch`가 미설치/미인증이어도 먼저 `ch check`를 시도한다. (네트워크 불가 시 ch check는 통과시키되 경고를 남긴다.)
27
+
28
+ 구버전 스킬·CLI 사용을 막기 위한 게이트다. 건너뛰지 말 것.
29
+
30
+
31
+ # 기능명세 — Story / Epic / Task 작성 표준
32
+
33
+ CLI 명령은 [[2t-decencia-channel-cli-v2]], DB 테이블 작성은 [[2t-decencia-channel-db-schema-v2]] 참조.
34
+
35
+ ---
36
+
37
+ ## 0. 핵심 개념
38
+
39
+ | 계층 | 매핑 | 역할 |
40
+ |---|---|---|
41
+ | **Spec ID** | `spec.id` (string) | 식별자. **JIRA 스타일 사용자 지정 가능** (예: `LOGIN-001`). §1.5 |
42
+ | **Epic** | `spec.epic` (string) | 분류 라벨. 같은 에픽 spec끼리 자동 그룹핑 |
43
+ | **Story** | spec 자체 (1 spec = 1 story) | 명세 1건. CLI 명칭은 `specs` 그대로 |
44
+ | **Task** | `spec.tasks[]` | Story 완료를 위한 체크리스트 (points/assignee/description/completedAt) |
45
+ | **UI** | `spec.ui` (object) | Figma·route·file·access·interactionMap |
46
+ | **Logic** | `spec.logic` (object) | dataFlow·stateTransitions·businessRules |
47
+ | **DB** | `spec.dbTableRefs` (string[]) | db-tables 컬렉션의 테이블 ID 배열. 양방향 동기화 |
48
+
49
+ `spec.workStatus`(작업 일지)는 개발 진행 중에 누적되는 별개 라이프사이클 — [[2t-decencia-channel-work-status-v2]] 참조.
50
+
51
+ **완료 조건**: 별도 acceptanceCriteria 없음. **연관 SQA 통과 = 완료**.
52
+
53
+ ---
54
+
55
+ ## 🚨 BLOCKING: Read-before-Write
56
+
57
+ ```bash
58
+ ch specs get <specId> --json > /tmp/spec.json # 1) 현재 상태 백업
59
+ # 편집 (tasks/ui/logic JSON 통째 교체 위험)
60
+ ch specs update <specId> --tasks /tmp/tasks.json --no-version
61
+ ch specs get <specId> --json | jq '.tasks' # 3) 검증
62
+ ```
63
+
64
+ `--tasks` / `--ui` / `--logic` / `--work-status`는 **각 필드 자체를 통째로 교체**. 일부만 바꾸려면 반드시 전체 가져와서 편집 후 전송.
65
+
66
+ ---
67
+
68
+ ## 1. 필드 분담
69
+
70
+ | 위치 | 들어가는 것 |
71
+ |---|---|
72
+ | `content` | 개요 1~3줄 + 권한 요약. 짧게 유지 |
73
+ | `ui.*` | 화면 메타 (figma/route/file/access) + 인터랙션 맵 |
74
+ | `logic.dataFlow` | 데이터 READ/WRITE 흐름 |
75
+ | `logic.stateTransitions` | 상태 머신 |
76
+ | `logic.businessRules` | 도메인 규칙 |
77
+ | `dbTableRefs[]` | 참조 테이블 ID (스키마 본문은 db-tables 문서에) |
78
+ | `tasks[]` | 작업 단위 체크리스트 |
79
+
80
+ ---
81
+
82
+ ## 1.5 Spec ID — 식별자 명명 규칙 (ch-cli 1.3.5+, ch-api `b029f88`+)
83
+
84
+ ### 1.5-1. 두 가지 모드
85
+
86
+ | 모드 | 사용법 | 결과 ID 예 |
87
+ |---|---|---|
88
+ | **자동 (기본)** | `ch specs create --name ...` (`--id` 생략) | `g3pWKfTpO0uSRU2KEiqh` (Firestore auto-id) |
89
+ | **사용자 지정** | `ch specs create --id LOGIN-001 --name ...` | `LOGIN-001` |
90
+
91
+ 기존 spec(랜덤 ID)은 그대로 유지된다. 신규 생성 시에만 패턴 선택 가능.
92
+
93
+ ### 1.5-2. 허용 패턴
94
+
95
+ 서버 검증 정규식: `^[A-Za-z][A-Za-z0-9_]*-[A-Za-z0-9]+$` (MaxLength 60)
96
+
97
+ | 형태 | 허용 | 예 |
98
+ |---|---|---|
99
+ | JIRA 표준 | ✅ | `LOGIN-001`, `AUTH-12`, `USER-A1` |
100
+ | 언더스코어 prefix | ✅ | `USER_ADMIN-007` |
101
+ | 소문자 prefix | ✅ | `login-001` (단, 팀 컨벤션상 대문자 권장) |
102
+ | 숫자 prefix 시작 | ❌ | `1LOGIN-001` |
103
+ | 하이픈 없음 | ❌ | `LOGIN001` |
104
+ | 끝부분 특수문자 | ❌ | `LOGIN-001@v2` |
105
+
106
+ ### 1.5-3. 네이밍 권장
107
+
108
+ - **prefix = Epic 또는 도메인 약어 (대문자)**, **`-` + 3자리 0패딩 숫자**가 가장 가독성 좋음.
109
+ - 예: `AUTH-001`, `AUTH-002`, `DASHBOARD-001` …
110
+ - prefix는 Epic과 1:1로 묶으면 검색·정렬 모두 편함. (예: Epic "인증" → `AUTH-*`)
111
+ - 숫자 폭은 프로젝트 규모로 결정 (소형 3자리, 대형 4~5자리).
112
+ - 너무 긴 prefix는 피한다 (Firestore 키 길이·URL 가독성).
113
+
114
+ ### 1.5-4. 충돌 시 동작
115
+
116
+ - 이미 같은 ID의 spec이 존재하면 서버가 **409 Conflict** 반환.
117
+ - 메시지: `Spec ID "LOGIN-001"가 이미 존재합니다. 다른 ID를 사용하세요.`
118
+ - 패턴 위반 시 **400 Bad Request** (`Spec ID는 "PREFIX-숫자" 형식이어야 합니다 ...`).
119
+
120
+ ### 1.5-5. 사용 예
121
+
122
+ ```bash
123
+ # 단일 spec — JIRA 스타일
124
+ ch specs create --id LOGIN-001 --name "로그인 화면" \
125
+ --device web --domain user --type 인증 --epic 인증
126
+
127
+ # Epic의 다음 번호 자동 산정 (간단 스크립트)
128
+ NEXT=$(ch specs list --json --per-page 200 \
129
+ | jq -r '[.data[].id | select(test("^AUTH-[0-9]+$"))] | map(split("-")[1] | tonumber) | (max // 0) + 1' \
130
+ | xargs printf '%03d')
131
+ ch specs create --id "AUTH-$NEXT" --name "비밀번호 재설정" ... --epic 인증
132
+
133
+ # 기존 자동 ID 그대로 (--id 생략)
134
+ ch specs create --name "임시 화면" --device web --domain admin --type 관리
135
+ # → id: g3pWKfTpO0uSRU2KEiqh (자동)
136
+ ```
137
+
138
+ ### 1.5-6. 마이그레이션 주의
139
+
140
+ - 기존 spec의 ID는 **변경 불가** (Firestore 문서 키 = ID). 바꾸려면 새 ID로 재생성 + 기존 삭제 + 모든 참조(dbTable.relatedSpecIds, SQA.relatedSpec) 일괄 갱신 — [[2t-decencia-channel-change-propagation-v2]] 참조.
141
+ - 같은 프로젝트 안에 자동 ID와 사용자 지정 ID가 **공존 허용**. 일관성을 원하면 새 ID는 모두 사용자 지정으로 통일.
142
+
143
+ ---
144
+
145
+ ## 2. 작성 전 절차
146
+
147
+ ```bash
148
+ # 0) 신규 프로젝트라면 schema 등록 (UI 컬럼 노출에 필수)
149
+ ch projects set-schema --devices "웹,모바일" --domains "본사관리,회원관리" \
150
+ --types "조회,관리" --permissions "관리자,일반"
151
+
152
+ # 1) 스키마 옵션 확인
153
+ ch specs meta --json
154
+
155
+ # 2) 기존 spec/db-tables 목록 확인 (중복·연결 대상 파악)
156
+ ch specs list --json --per-page 100
157
+ ch db-tables list --json
158
+ ```
159
+
160
+ ---
161
+
162
+ ## 3. Task — JIRA 스타일 체크리스트
163
+
164
+ ### 3-1. tasks.json 구조
165
+
166
+ ```json
167
+ [
168
+ {
169
+ "id": "",
170
+ "title": "로그인 폼 UI 구현",
171
+ "done": false,
172
+ "assignee": "박준하",
173
+ "points": 5,
174
+ "description": "## 세부\n- React Hook Form + Yup\n- error UI 별도 컴포넌트\n- 참고: [Figma](https://...)"
175
+ },
176
+ {
177
+ "id": "",
178
+ "title": "Firebase Auth 연결",
179
+ "done": false,
180
+ "points": 3,
181
+ "description": "- signInWithEmailAndPassword 사용\n- 5회 실패 시 잠금 로직은 별도 spec"
182
+ },
183
+ {
184
+ "id": "a1b2c3d4",
185
+ "title": "유효성 검증",
186
+ "done": true,
187
+ "points": 1,
188
+ "completedAt": "2026-05-29T08:00:00.000Z"
189
+ }
190
+ ]
191
+ ```
192
+
193
+ 서버가 자동 처리:
194
+ - `id` 비어있으면 UUID 부여
195
+ - `done: true && completedAt 없음` → 현재 ISO 부여
196
+ - `done: false` → completedAt 제거
197
+ - 전체 progress(%) 자동 재계산 (`Math.round(doneCount / total * 100)`)
198
+
199
+ ### 3-2. 입자 기준
200
+
201
+ | 너무 크다 | 적정 | 너무 작다 |
202
+ |---|---|---|
203
+ | "로그인 기능 구현" (points 13+) | "로그인 폼 UI 구현" (3~5p) | "input 태그 추가" (0p) |
204
+
205
+ - **1 Task = 반나절~2일 작업**. points 1~8 (피보나치).
206
+ - 13 이상이면 쪼개라.
207
+ - 1 이하면 description bullet으로 합쳐라.
208
+
209
+ ### 3-3. points 부여 가이드 (피보나치)
210
+
211
+ | points | 의미 | 예 |
212
+ |---|---|---|
213
+ | 1 | 거의 자명. 30분~2시간 | 단순 텍스트 변경, 색상 토큰 적용 |
214
+ | 2 | 1일 이내. 구현 + 단순 검증 | 기존 폼에 필드 추가 |
215
+ | 3 | 1~2일. 신규 컴포넌트/엔드포인트 | 로그인 폼 UI 구현 |
216
+ | 5 | 2~3일. 통합 작업 (API + UI + state) | Firebase Auth 통합 |
217
+ | 8 | 1주~. 큰 모듈, 모르는 영역 포함 | 결제 모듈 통합 |
218
+ | 13 | 너무 큼 — **쪼개라** | — |
219
+
220
+ ### 3-4. description 작성 권장
221
+
222
+ - 마크다운 사용 가능 (목록·표·코드블록·링크)
223
+ - 들어가야 할 것: 구체 산출물, 의존성, 참고 자료(Figma/문서 링크), 엣지케이스
224
+ - 들어가지 말 것: 작업 일지(→ [[work-status-v2]] 참조), 완료 보고(→ done + completedAt)
225
+
226
+ ### 3-5. assignee 표기
227
+
228
+ 자유 문자열. 한글 이름 또는 GitHub 핸들. 팀 컨벤션 통일 권장.
229
+
230
+ ---
231
+
232
+ ## 4. UI — Figma · Route · Interaction Map
233
+
234
+ ### 4-1. ui.json 구조
235
+
236
+ ```json
237
+ {
238
+ "figmaNodeId": "12345:67890",
239
+ "route": "/login",
240
+ "file": "src/app/login/page.tsx",
241
+ "access": "public",
242
+ "interactionMap": "## 인터랙션\n\n| 요소 | 타입 | 액션 | 동작 |\n|---|---|---|---|\n| 이메일 input | input | onBlur | 형식 검증 |\n| 비밀번호 input | input + 토글 | 클릭 | 숨김/표시 |\n| 로그인 버튼 | 버튼 | 클릭 | 비동기 인증 |\n| 회원가입 링크 | 링크 | 클릭 | → /register |\n\n### 다이얼로그/바텀시트\n- 잠금 안내: 5회 실패 시 표시\n"
243
+ }
244
+ ```
245
+
246
+ ### 4-2. 필드 작성 가이드
247
+
248
+ | 필드 | 작성 규칙 |
249
+ |---|---|
250
+ | `figmaNodeId` | Figma URL의 `?node-id=` 값. `-` → `:` 치환. 예: `12345:67890` |
251
+ | `route` | 화면 경로. SPA면 `/login`, 동적 세그먼트는 `/users/[id]` |
252
+ | `file` | 진입 컴포넌트 파일 경로(저장소 기준). 예: `src/app/login/page.tsx` |
253
+ | `access` | `public`, `auth`, `admin`, `role:센터장` 등 자유 문자열. 권한 체크 진입점 표기 |
254
+ | `interactionMap` | **모든 인터랙티브 요소**를 마크다운 표로. 다이얼로그/바텀시트/키보드 단축키는 별도 절 |
255
+
256
+ ### 4-3. interactionMap 표 권장 컬럼
257
+
258
+ ```markdown
259
+ | 요소 | 타입 | 액션 | 동작/이동경로 |
260
+ |---|---|---|---|
261
+ | 뒤로가기 | 아이콘 | 탭 | Navigator.pop() |
262
+ | 폴더 만들기 | 버튼 | 탭 | → /folders/create |
263
+ | 이미지 카드 | 카드 | 탭 | → /images/:id |
264
+ | 이미지 카드 | 카드 | 롱프레스 | 선택 모드 진입 |
265
+ | 공유 토글 | 스위치 | ON/OFF | is_shared 변경 + 참여자 UI 표시 |
266
+ | ⋮ 메뉴 | 아이콘 | 탭 | 바텀시트(관리/삭제) |
267
+ ```
268
+
269
+ 규칙:
270
+ - 같은 요소에 여러 액션 → **행 분리** (탭/롱프레스/스와이프 등)
271
+ - 모달·바텀시트가 열리면 그 안의 요소도 별도 행
272
+ - 이동 경로는 `/path` 또는 동작 설명
273
+
274
+ ### 4-4. 비화면 명세
275
+
276
+ 화면이 없는 기능 명세(Cron, 배치, 외부 연동)는 `ui` 통째 생략. 대신 `logic`에 집중.
277
+
278
+ ---
279
+
280
+ ## 5. Logic — 데이터 흐름 · 상태 전이 · 비즈니스 규칙
281
+
282
+ ### 5-1. logic.json 구조
283
+
284
+ ```json
285
+ {
286
+ "dataFlow": "...",
287
+ "stateTransitions": "...",
288
+ "businessRules": "..."
289
+ }
290
+ ```
291
+
292
+ 세 필드 모두 마크다운. 필요한 것만 채워도 됨.
293
+
294
+ ### 5-2. dataFlow — READ/WRITE 매핑 표
295
+
296
+ 이 spec이 다루는 데이터의 출처/목적지를 명시.
297
+
298
+ ```markdown
299
+ | 데이터 | 소스/대상 | 방향 | 조건/비고 |
300
+ |---|---|---|---|
301
+ | 이메일·비밀번호 | 사용자 입력 | IN | 클라이언트 검증 |
302
+ | Firebase Auth credential | Firebase | WRITE | signInWithEmailAndPassword |
303
+ | ID Token | Firebase | READ | 쿠키에 httpOnly 저장 |
304
+ | users/{uid} 문서 | Firestore | READ | 최초 로그인 시 lastLoginAt 갱신 |
305
+ | users/{uid}.lastLoginAt | Firestore | WRITE | serverTimestamp() |
306
+ ```
307
+
308
+ 규칙:
309
+ - READ: 화면/기능이 읽는 데이터
310
+ - WRITE: 기능 결과로 쓰이는 데이터
311
+ - 조건/비고: 필터·정렬·트랜잭션 여부·인덱스 활용 등
312
+ - 외부 API 호출도 동일 형식 (소스/대상 = "Firebase Auth", "Toss Payments API" 등)
313
+
314
+ ### 5-3. stateTransitions — 상태 머신 표
315
+
316
+ 상태가 있는 기능(주문/배포/인증 등)은 머신 다이어그램 대신 표로.
317
+
318
+ ```markdown
319
+ | 현재 상태 | 이벤트 | 다음 상태 | 사이드이펙트 |
320
+ |---|---|---|---|
321
+ | idle | submit | loading | spinner 표시 |
322
+ | loading | success | authenticated | 토큰 저장 + /dashboard 이동 |
323
+ | loading | error | error | 에러 메시지 + lockCount++ |
324
+ | error | retry | loading | spinner |
325
+ | authenticated | logout | idle | 토큰 제거 |
326
+ | error | (lockCount >= 5) | locked | 1시간 잠금 타이머 |
327
+ ```
328
+
329
+ 규칙:
330
+ - 컬럼: 현재 / 이벤트 / 다음 / 사이드이펙트 (이펙트 컬럼은 옵션)
331
+ - 가드 조건은 이벤트 컬럼에 `(조건)` 또는 별도 컬럼
332
+ - 진입 시점 = idle (또는 init)을 명시
333
+
334
+ ### 5-4. businessRules — 도메인 규칙 목록
335
+
336
+ 번호/불릿 마크다운.
337
+
338
+ ```markdown
339
+ - 비밀번호 5회 연속 실패 시 해당 계정 1시간 잠금 (lockedUntil 필드)
340
+ - 휴면 계정(마지막 로그인 후 30일 경과)은 이메일 재인증 후 로그인 허용
341
+ - 동일 계정 동시 세션 3개 초과 시 가장 오래된 세션 강제 만료
342
+ - 비밀번호 정책: 영문 + 숫자 + 특수문자 포함 8자 이상
343
+ - 어드민 권한 계정은 IP 화이트리스트 통과 시에만 로그인
344
+ ```
345
+
346
+ 규칙:
347
+ - 1 규칙 = 1 불릿
348
+ - 임계값·기간·조건을 구체 수치로
349
+ - 큰 규칙은 별도 spec 분리 가능
350
+
351
+ ---
352
+
353
+ ## 6. DB — dbTableRefs로 테이블 연결
354
+
355
+ ### 6-1. 흐름
356
+
357
+ 1. 먼저 `db-tables` 컬렉션에 테이블 문서를 만든다 (CLI: `ch db-tables create`).
358
+ 2. spec 생성/수정 시 `--db-tables tbl_users,tbl_sessions` 로 ID를 연결한다.
359
+ 3. 서버가 `spec.dbTableRefs` ↔ `table.relatedSpecIds` **양방향 동기화**.
360
+
361
+ ### 6-2. spec vs db-tables 분담
362
+
363
+ | 위치 | 내용 |
364
+ |---|---|
365
+ | **spec** | "이 화면/기능이 어느 테이블의 어떤 컬럼을 R/W하는가" — `logic.dataFlow` 표에 기술 |
366
+ | **db-tables** | 컬럼 정의, 인덱스, 보안 규칙, 역할 매트릭스 |
367
+
368
+ spec.dbTableRefs는 **포인터만**. 스키마 본문은 [[2t-decencia-channel-db-schema-v2]] 참조.
369
+
370
+ ### 6-3. 신규 spec에서 신규 테이블이 필요한 경우 순서
371
+
372
+ ```bash
373
+ # 1) 테이블 먼저 생성
374
+ ch db-tables create --name users \
375
+ --description "회원 기본정보" \
376
+ --columns ./users-columns.json \
377
+ --indexes ./users-indexes.json \
378
+ --security ./users-security.json
379
+ # → {"id": "tbl_xyz123"}
380
+
381
+ # 2) spec 생성/연결
382
+ ch specs create --name "로그인" ... --db-tables tbl_xyz123
383
+ ```
384
+
385
+ ### 6-4. 기존 테이블 추가 연결
386
+
387
+ ```bash
388
+ # 현재 dbTableRefs 가져와 새 ID 합치기
389
+ ch specs get <specId> --json | jq -r '.dbTableRefs | join(",")'
390
+ # 결과에 새 ID를 쉼표로 이어서:
391
+ ch specs update <specId> --db-tables tbl_xyz,tbl_new --no-version
392
+ ```
393
+
394
+ ---
395
+
396
+ ## 7. 작업 일지 — 별도 스킬 참조
397
+
398
+ spec 작성 시점이 아니라 **개발 진행 중에 누적**되는 일지(`spec.workStatus`)는 라이프사이클이 달라 [[2t-decencia-channel-work-status-v2]]에서 따로 다룬다. spec을 처음 만드는 시점에는 비워둔다.
399
+
400
+ ---
401
+
402
+ ## 8. 명세 유형별 패턴
403
+
404
+ ### 8-A. 화면 명세 (가장 흔함)
405
+
406
+ - `ui` 모든 필드 채움 (figmaNodeId/route/file/access/interactionMap)
407
+ - `logic.dataFlow` 필수
408
+ - `tasks[]` 5~10개 (UI/로직/테스트 분리)
409
+ - `dbTableRefs` 화면이 R/W하는 테이블 전부
410
+
411
+ ### 8-B. 기능 명세 (Cron · 배치 · 외부 연동)
412
+
413
+ - `ui` 통째 생략
414
+ - `logic.dataFlow` + `logic.businessRules` 필수
415
+ - `logic.stateTransitions` 작업 상태 머신
416
+ - `tasks[]` 트리거·처리·에러처리·로깅
417
+
418
+ ### 8-C. 공통 명세 (인증 · 알림 · 업로드)
419
+
420
+ - `ui` 생략 (모듈이라 화면 없음)
421
+ - `logic.businessRules` 중심 (정책·제약)
422
+ - `tasks[]` 인터페이스 구현·통합 테스트
423
+ - 다른 spec이 이걸 import한다는 점을 `note`에 명시
424
+
425
+ ---
426
+
427
+ ## 9. 분해 크기 검증
428
+
429
+ 너무 큰 spec은 분리.
430
+
431
+ | 지표 | 한계 | 조치 |
432
+ |---|---|---|
433
+ | `tasks` 개수 | 12+ | spec 분리 검토 |
434
+ | Task points 합 | 30+ | sprint 1회로 못 끝남 → 분리 |
435
+ | `logic.dataFlow` 표 행 수 | 15+ | 화면/기능이 다중일 가능성 → 분리 |
436
+ | `ui.interactionMap` 줄 수 | 80+ | 화면이 너무 큼 → 분리 |
437
+ | 같은 spec에 화면 2개 이상 | 항상 분리 | 1 화면 = 1 spec |
438
+
439
+ ---
440
+
441
+ ## 10. 흔한 함정
442
+
443
+ - `--tasks/--ui/--logic` JSON 통째 교체 → 일부 수정도 **반드시 get 후 편집**.
444
+ - `dbTableRefs`를 손으로 JSON에 넣어도 서버가 무시 (CLI `--db-tables` 또는 웹 picker만 사용).
445
+ - 항구적 작업 정의는 `tasks[].description`. 시간축 진행 메모는 workStatus(별도 스킬).
446
+ - estimate(시간)는 사용하지 않음. points만 사용.
447
+
448
+ ---
449
+
450
+ ## 11. 작업 순서 체크리스트
451
+
452
+ 신규 화면 spec 1건을 만들 때:
453
+
454
+ 1. `ch specs meta --json` → 스키마 옵션 확인
455
+ 2. 화면이 사용하는 테이블 정리 → 없으면 `ch db-tables create` 먼저
456
+ 3. **Spec ID 결정** (§1.5) — JIRA 스타일(`EPIC-NNN`) 사용 시 다음 번호 결정. 자동 ID로 가도 됨
457
+ 4. `tasks.json` 작성 (5~10개, points 부여)
458
+ 5. `ui.json` 작성 (figmaNodeId/route/file/access/interactionMap)
459
+ 6. `logic.json` 작성 (dataFlow 필수, 나머지 해당 시)
460
+ 7. `ch specs create [--id LOGIN-001] --name ... --epic ... --tasks ... --ui ... --logic ... --db-tables tbl_a,tbl_b`
461
+ 8. `ch specs get <id> --json`으로 결과 검증
462
+ 9. SQA 항목은 [[2t-decencia-channel-sqa-v2]]에 따라 별도 등록
463
+ 10. 개발 착수 후의 진행 일지는 [[2t-decencia-channel-work-status-v2]]에서 관리
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: 2t-decencia-channel-sprint-builder-v2
3
+ description: |
4
+ [2t][v2] 소통채널 Sprint 구성 가이드.
5
+ spec의 epic·tasks·points를 활용한 스프린트 산정과 자동 배치 원칙.
6
+ Use when:
7
+ (1) sprint를 구성할 때,
8
+ (2) Story Point 합산 기반 sprint 용량 산정이 필요할 때,
9
+ (3) Epic·도메인·의존성을 함께 고려해 spec을 sprint에 배분할 때.
10
+ version: 1.5.0
11
+ ---
12
+
13
+ <!-- ch-version-gate -->
14
+ ## ⚠️ 시작 전 필수 — 버전 게이트 (생략 금지)
15
+
16
+ 이 스킬로 **어떤 작업이든 수행하기 전에 가장 먼저** 아래를 실행한다:
17
+
18
+ ```bash
19
+ ch check
20
+ ```
21
+
22
+ - exit code 0(통과)이 **아니면 즉시 중단**한다. 출력에 안내된 업데이트 명령(`npm install -g @decencia/ch-cli@latest` 또는 `ch setup-skill`)을 사용자에게 전달하고, 갱신이 끝나기 전까지 **이 스킬의 어떤 단계도 진행하지 않는다.**
23
+ - `ch`가 미설치/미인증이어도 먼저 `ch check`를 시도한다. (네트워크 불가 시 ch check는 통과시키되 경고를 남긴다.)
24
+
25
+ 구버전 스킬·CLI 사용을 막기 위한 게이트다. 건너뛰지 말 것.
26
+
27
+
28
+ # Sprint Builder — Epic × Story Point 기반 배분
29
+
30
+ ## 0. Read-before-Write
31
+
32
+ ```bash
33
+ ch specs list --json > /tmp/specs.json # 모든 spec과 tasks/points 확보
34
+ ch sprints list --json > /tmp/sprints.json
35
+ # 분석 후
36
+ ch sprints create --name "Sprint 1" --start 2026-06-01 --end 2026-06-14 --specs <id1>,<id2>
37
+ ```
38
+
39
+ ## 1. 산정 절차
40
+
41
+ 1. 모든 spec을 `ch specs list --json`로 수집.
42
+ 2. 각 spec의 `epic`, `tasks[].points` 추출.
43
+ 3. spec 단위 totalPoints = Σ tasks.points (points 없는 task는 1로 가정 또는 skip — 정책 결정).
44
+ 4. Sprint 용량(예: 30 SP / 2주) 설정 후, 다음 순서로 채우기:
45
+ - **의존성** (PRD/spec.dbTableRefs 분석): DB 테이블 신규 생성 spec → 그걸 참조하는 spec 순.
46
+ - **Epic 단위 묶음**: 같은 Epic은 한 sprint에 몰아주는 게 컨텍스트 비용 ↓.
47
+ - **도메인 균형**: 한 sprint에 너무 한쪽 도메인(user/admin)에 치우치지 않게.
48
+ 5. 남는 SP는 다음 sprint로 carry-over.
49
+
50
+ ## 2. 계획 확인 단계 (사용자 컨펌)
51
+
52
+ 자동 배치 후 다음 표를 사용자에게 제시하고 컨펌:
53
+
54
+ ```
55
+ Sprint 1 (06-01 ~ 06-14, 용량 30 SP)
56
+ | Epic | Spec | Points |
57
+ |---|---|---|
58
+ | 인증 | 로그인 | 5 |
59
+ | 인증 | 회원가입 | 3 |
60
+ | 대시보드 | 메인 대시보드 | 8 |
61
+ | ... | ... | ... |
62
+ 합계: 28 SP / 30 SP
63
+ ```
64
+
65
+ 컨펌 후 `ch sprints create` 실행.
66
+
67
+ ## 3. workStatus 활용
68
+
69
+ 각 spec.workStatus에 현재 진행 상황이 적혀 있으면 우선순위 산정에 반영:
70
+ - "블로커" 키워드 → sprint 보류 후보
71
+ - "완료 임박" → 현 sprint 마무리 후보
72
+
73
+ ## 4. 흔한 함정
74
+
75
+ - points 없는 task가 많으면 산정 부정확 → spec 작성 시 모든 task에 points 부여 권장(0/1/2/3/5/8).
76
+ - Sprint에 spec 추가 후 spec 내 tasks를 늘리면 sprint SP 합이 변동 — sprint 재산정 필요.
77
+ - Sprint와 spec.workStatus는 별개. Sprint 진행 상황은 sprint 자체 status로, spec별 메모는 workStatus로.