@decencia/ch-cli 1.29.0 → 1.31.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 (49) hide show
  1. package/agent/2t-decencia-channel-issue-coder.md +1 -1
  2. package/agent/2t-decencia-channel-pr-merger.md +1 -1
  3. package/agent/2t-decencia-channel-terraformer.md +1 -1
  4. package/dist/commands/policies.d.ts +12 -0
  5. package/dist/commands/policies.d.ts.map +1 -0
  6. package/dist/commands/policies.js +302 -0
  7. package/dist/commands/policies.js.map +1 -0
  8. package/dist/commands/screens.d.ts.map +1 -1
  9. package/dist/commands/screens.js +103 -23
  10. package/dist/commands/screens.js.map +1 -1
  11. package/dist/commands/skills.d.ts +13 -0
  12. package/dist/commands/skills.d.ts.map +1 -1
  13. package/dist/commands/skills.js +43 -7
  14. package/dist/commands/skills.js.map +1 -1
  15. package/dist/commands/specs.d.ts +15 -0
  16. package/dist/commands/specs.d.ts.map +1 -1
  17. package/dist/commands/specs.js +117 -10
  18. package/dist/commands/specs.js.map +1 -1
  19. package/dist/commands/sprints.d.ts +16 -0
  20. package/dist/commands/sprints.d.ts.map +1 -1
  21. package/dist/commands/sprints.js +152 -4
  22. package/dist/commands/sprints.js.map +1 -1
  23. package/dist/commands/sqa.d.ts +23 -0
  24. package/dist/commands/sqa.d.ts.map +1 -1
  25. package/dist/commands/sqa.js +252 -6
  26. package/dist/commands/sqa.js.map +1 -1
  27. package/dist/commands/userflows.d.ts +11 -0
  28. package/dist/commands/userflows.d.ts.map +1 -0
  29. package/dist/commands/userflows.js +275 -0
  30. package/dist/commands/userflows.js.map +1 -0
  31. package/dist/index.js +4 -0
  32. package/dist/index.js.map +1 -1
  33. package/package.json +1 -1
  34. package/skill/2t-decencia-channel-change-manager/SKILL.md +1 -1
  35. package/skill/2t-decencia-channel-change-propagation-v2/SKILL.md +11 -7
  36. package/skill/2t-decencia-channel-cli-v2/SKILL.md +48 -20
  37. package/skill/2t-decencia-channel-db-schema-v2/SKILL.md +4 -4
  38. package/skill/2t-decencia-channel-github-issue/SKILL.md +1 -1
  39. package/skill/2t-decencia-channel-orchestrator/SKILL.md +1 -1
  40. package/skill/2t-decencia-channel-policy-v2/SKILL.md +114 -0
  41. package/skill/2t-decencia-channel-prd-v2/SKILL.md +37 -12
  42. package/skill/2t-decencia-channel-project-bootstrap/SKILL.md +22 -25
  43. package/skill/2t-decencia-channel-screen-v2/SKILL.md +135 -0
  44. package/skill/2t-decencia-channel-spec-v2/SKILL.md +288 -443
  45. package/skill/2t-decencia-channel-sprint-builder-v2/SKILL.md +11 -3
  46. package/skill/2t-decencia-channel-sprint-runner/SKILL.md +1 -1
  47. package/skill/2t-decencia-channel-sqa-v2/SKILL.md +124 -21
  48. package/skill/2t-decencia-channel-userflow-v2/SKILL.md +125 -0
  49. package/skill/2t-decencia-channel-work-status-v2/SKILL.md +3 -3
@@ -2,7 +2,7 @@
2
2
  name: 2t-decencia-channel-cli-v2
3
3
  description: |
4
4
  [2t][v2] 소통채널 CLI(`ch`, npm @decencia/ch-cli) 가이드.
5
- Epic-Story 체계(규모=Story Point)와 db-tables·screens 리소스, --work-status, --id, --points 플래그를 망라한다.
5
+ Epic-Story 체계(규모=Story Point)와 db-tables·screens 리소스, 스토리 명세 플래그(--story·--preconditions), --work-status, --id, --points 등을 망라한다.
6
6
  Use when:
7
7
  (1) spec/db-table/화면(screen)을 CLI로 다룰 때,
8
8
  (2) spec 규모를 Story Point(`--points`)로 매길 때,
@@ -10,7 +10,7 @@ description: |
10
10
  (4) ch screens 명령(list/get/create/update/delete/migrate)으로 화면을 다루거나 레거시 프로젝트를 화면 모드로 이관할 때,
11
11
  (5) spec의 화면 연결을 CLI로 걸거나 풀 때 (`ch specs screen-refs`),
12
12
  (6) Spec ID를 JIRA 스타일(`LOGIN-001`)로 직접 지정할 때 (`ch specs create --id`).
13
- version: 1.29.0
13
+ version: 1.31.0
14
14
  ---
15
15
 
16
16
  <!-- ch-version-gate -->
@@ -42,32 +42,52 @@ ch specs update <specId> --logic /tmp/logic.json # 3) 수정 적용
42
42
 
43
43
  ## 1. spec 명령
44
44
 
45
+ 프로젝트 모드에 따라 쓰는 플래그가 다르다 ([[2t-decencia-channel-spec-v2]] §0).
46
+
47
+ **스토리 명세 모드** (`storySpecsEnabled=true` — 신규 프로젝트 기본):
48
+
49
+ ```bash
50
+ # 생성 (사용자 지정 Spec ID = Epic 도메인 코드 prefix 권장)
51
+ # ID 패턴: ^[A-Za-z][A-Za-z0-9_]*-[A-Za-z0-9]+$ (MaxLength 60), 충돌 시 409
52
+ ch specs create --id AUTH-001 \
53
+ --name "로그인" \
54
+ --device web,app --domain 회원 --permission 비회원 \
55
+ --epic AUTH \
56
+ --points 5 \
57
+ --story "회원은 이메일과 비밀번호로 로그인해서, 재인증 없이 자신의 프로젝트에 바로 접근하고 싶다." \
58
+ --preconditions ./preconditions.md \
59
+ --logic ./logic.json \
60
+ --db-tables tbl_users,tbl_sessions
61
+
62
+ # 수정: 지정한 플래그만 PATCH. --no-version 시 버전 기록 생략.
63
+ ch specs update <specId> --story "..." --no-version
64
+ ch specs update <specId> --preconditions ./preconditions.md --no-version
65
+ ch specs update <specId> --points 8 --no-version
66
+ ```
67
+
68
+ - `--story "<줄글>"` — 스토리문장(As a/I want/So that). 스칼라라 그 값만 바뀐다.
69
+ - `--preconditions <텍스트|파일경로>` — 사전 조건 마크다운.
70
+ - `--domain`은 쉼표로 **복수** 지정 (`--domain 회원,관리자`).
71
+ - `--type`(기능유형)·`--content`는 스토리 명세 모드에서 쓰지 않는다 (레거시 전용).
72
+ - `--ui`는 화면 연결이 필요할 때 `{"screenRefs":[...]}`만 싣는다 (생성 시에만 — §1 화면 연결).
73
+
74
+ **레거시 모드** (`storySpecsEnabled` 미설정·false — 기존 프로젝트):
75
+
45
76
  ```bash
46
- # 생성 (자동 ID)
47
77
  ch specs create \
48
78
  --name "로그인" \
49
79
  --device web,app --domain user --type 인증 --permission 비회원 \
50
80
  --content "이메일/비밀번호 로그인" \
51
- --epic 인증 \
52
- --points 5 \
53
- --ui ./ui.json \
54
- --logic ./logic.json \
81
+ --epic 인증 --points 5 \
82
+ --ui ./ui.json --logic ./logic.json \
55
83
  --db-tables tbl_users,tbl_sessions \
56
84
  --work-status ./work-status.md
57
85
 
58
- # 생성 (사용자 지정 Spec ID, JIRA 스타일 — ch-cli 1.3.5+ / ch-api b029f88+)
59
- # 패턴: ^[A-Za-z][A-Za-z0-9_]*-[A-Za-z0-9]+$ (MaxLength 60)
60
- # 충돌 시 409, 패턴 위반 시 400
61
- ch specs create --id LOGIN-001 \
62
- --name "로그인" --device web --domain user --type 인증 --epic 인증
63
-
64
- # 수정: 지정한 플래그만 PATCH. --no-version 시 버전 기록 생략.
65
86
  ch specs update <specId> --epic 인증 --no-version
66
- ch specs update <specId> --points 8 --no-version
67
87
  ch specs update <specId> --work-status ./status.md
68
88
  ```
69
89
 
70
- > `--id`의 자세한 네이밍 규칙·예외·자동 다음 번호 산정 스크립트는 [[2t-decencia-channel-spec-v2]] §1.5 참조.
90
+ > `--id`의 자세한 네이밍 규칙·예외·자동 다음 번호 산정 스크립트는 [[2t-decencia-channel-spec-v2]] §4 참조.
71
91
 
72
92
  ### Story Point (`--points`)
73
93
 
@@ -79,7 +99,7 @@ ch specs update <specId> --points 8 --no-version
79
99
  ```
80
100
 
81
101
  - `--points <n>` — 0 이상의 숫자(보통 피보나치 1/2/3/5/8/13). 진행률(%)·완료율은 없다 — 완료 여부는 `status`로.
82
- - Sprint 용량 = Σ spec.points ([[2t-decencia-channel-sprint-builder-v2]]). 규모 산정 가이드는 [[2t-decencia-channel-spec-v2]] §3.
102
+ - Sprint 용량 = Σ spec.points ([[2t-decencia-channel-sprint-builder-v2]]). 규모 산정 가이드는 [[2t-decencia-channel-spec-v2]] §11.
83
103
 
84
104
  ### Task JSON (`--tasks`) — [deprecated]
85
105
 
@@ -107,7 +127,13 @@ ch specs update <specId> --points 8 --no-version
107
127
 
108
128
  ### UI JSON (`--ui`)
109
129
 
110
- **화면 모드** (`screensEnabled=true`) — spec.ui 소유 4필드만 쓴다.
130
+ **스토리 명세 모드** (`storySpecsEnabled=true`) — `screenRefs`만 쓴다. interactionMap·primaryActions·keyInformation은 스토리 명세에 없다.
131
+
132
+ ```json
133
+ { "screenRefs": ["SCR-LOGIN"] }
134
+ ```
135
+
136
+ **레거시 + 화면 모드** (`screensEnabled=true`) — spec.ui 소유 4필드만 쓴다.
111
137
 
112
138
  ```json
113
139
  {
@@ -161,7 +187,8 @@ ch specs update <specId> --points 8 --no-version
161
187
  ```
162
188
 
163
189
  - `dataFlowScenarios[]`=시나리오, 각 시나리오의 `steps[]`=순서 있는 단계, 각 단계의 `refs[]`=**db-tables의 tableId(+선택 field)를 가리키는 구조적 참조**(SSOT — 스키마 정의는 db-tables에만). 서버가 실존 검증: 없는 tableId/컬럼이면 400. `direction`은 `READ|WRITE|READWRITE`.
164
- - 단계 `description`은 필드명 나열이 아니라 **완결 문장**으로 — [[2t-decencia-channel-spec-v2]] §5.
190
+ - `stateTransitions`(화면 상태 전이)는 **레거시 전용**이다. 스토리 명세 모드에서는 쓰지 않는다. 스토리 명세의 흐름은 로직 플로우 하나다(정상/예외 구분 없음 실패 경로는 분기로) — [[2t-decencia-channel-spec-v2]] §7.
191
+ - 단계 `description`은 필드명 나열이 아니라 **완결 문장**으로 — [[2t-decencia-channel-spec-v2]] §7.
165
192
  - 하위호환: 레거시 `dataFlow`(문자열)/`dataFlowRefs[]`/`businessRuleRefs[]`도 그대로 수용된다(점진 마이그레이션). SQA 항목도 동일 취지로 `--db-tables`(쉼표 구분)를 가진다 — [[2t-decencia-channel-sqa-v2]].
166
193
 
167
194
  ### dbTableRefs (`--db-tables`)
@@ -248,6 +275,7 @@ ch db-tables delete <tableId> # 참조 spec의 dbTableRefs도
248
275
  ## 3. screens 명령 (화면)
249
276
 
250
277
  화면(Screen)은 화면 정의의 SSOT다. `ch_projects.screensEnabled=true`인 프로젝트에서 쓴다.
278
+ **무엇을 적어야 하는지**(필수 기재항목 6종·디스크립션 작성규칙·예외상태 4종)는 [[2t-decencia-channel-screen-v2]]가 정본이다.
251
279
 
252
280
  ```bash
253
281
  ch screens list # 표 출력: order | id | name | route | epic | states | specs
@@ -281,7 +309,7 @@ ch screens migrate --rollback # 화면 모드만 끄기 (화
281
309
  ch screens migrate --rollback --force # 되돌아갈 route가 없어도 강행 (기본은 서버가 409로 거절)
282
310
  ```
283
311
 
284
- - `--id`는 JIRA 스타일(`SCR-001`). 패턴 `^[A-Za-z][A-Za-z0-9_]*-[A-Za-z0-9]+$`, 중복 시 409.
312
+ - `--id`는 슬러그 스타일(`SCR-001`, `STORE-ORDER-DETAIL` 같은 다중 세그먼트 허용). 패턴 `^[A-Za-z][A-Za-z0-9_]*(-[A-Za-z0-9_]+)+$`, 중복 시 409. (spec ID 패턴과 다르다 — 화면만 완화됐다.)
285
313
  - 화면 소유 필드다. spec.ui가 아니라 여기에 적는다.
286
314
  - `--figma-node-id <id>` — 이 화면의 Figma 노드 ID(`123:456`). Figma URL의 `?node-id=` 값에서 `-`를 `:`로 바꾼 값이다.
287
315
  - `--page-file <path>` — 이 화면의 **페이지 진입 파일** 경로 하나(예: `src/app/store/[code]/page.tsx`). 하위 컴포넌트는 적지 않는다.
@@ -8,7 +8,7 @@ description: |
8
8
  (2) DB 테이블 단위로 컬럼·인덱스·보안규칙을 등록·수정할 때,
9
9
  (3) 새 테이블을 추가하면서 전체 인벤토리도 함께 업데이트할 때,
10
10
  (4) spec.dbTableRefs와 양방향 동기화가 필요한 작업 시.
11
- version: 1.29.0
11
+ version: 1.31.0
12
12
  ---
13
13
 
14
14
  <!-- ch-version-gate -->
@@ -277,7 +277,7 @@ description 활용 권장:
277
277
 
278
278
  ### 5-4. state-machines.json — 엔티티 상태머신
279
279
 
280
- 엔티티가 **저장되는 상태 컬럼**을 가지면(주문 `status`, 배포 `phase` 등) 그 생애주기를 여기에 정의한다. 화면의 휘발성 UI 전이(idle/loading 등)는 여기 말고 spec.logic.stateTransitions에 적는다[[2t-decencia-channel-spec-v2]] §5-3.
280
+ 엔티티가 **저장되는 상태 컬럼**을 가지면(주문 `status`, 배포 `phase` 등) 그 생애주기를 여기에 정의한다. 화면의 휘발성 UI 전이(idle/loading 등)는 여기 적지 않는다 — 화면(screens)의 `states`에, 레거시 프로젝트는 spec.logic.stateTransitions에 적는다([[2t-decencia-channel-spec-v2]] §L-3).
281
281
 
282
282
  `StateMachine[]` — 한 테이블에 상태머신 여러 개 가능(컬럼별).
283
283
 
@@ -327,7 +327,7 @@ description 활용 권장:
327
327
 
328
328
  #### spec dataFlow와의 상호참조 (`columnRef` ↔ `toState`)
329
329
 
330
- spec은 이 상태머신을 **`columnRef`로 잇는다**. spec의 dataFlow ref에서 `field`가 이 머신의 `columnRef`와 같으면, 그 ref는 이 엔티티의 상태 접근이다. 그 ref가 WRITE면 `toState`에 목표 상태(이 머신 `states[].value` 중 하나)를 적는다 — [[2t-decencia-channel-spec-v2]] §6-2-1.
330
+ spec은 이 상태머신을 **`columnRef`로 잇는다**. spec의 dataFlow ref에서 `field`가 이 머신의 `columnRef`와 같으면, 그 ref는 이 엔티티의 상태 접근이다. 그 ref가 WRITE면 `toState`에 목표 상태(이 머신 `states[].value` 중 하나)를 적는다 — [[2t-decencia-channel-spec-v2]] §10-2.
331
331
 
332
332
  - **링크 방향**: db-tables가 상태를 **정의**(states·transitions)하고, spec은 `tableId` + `field`(=columnRef) + `toState`로 **참조**만 한다.
333
333
  - `ch specs get`은 이 머신 요약(states·transitions)을 spec ref 옆에 **읽기 시점에 인라인**해 준다. 그래서 상태 목록을 spec에 베낄 필요가 없다.
@@ -372,7 +372,7 @@ spec은 이 상태머신을 **`columnRef`로 잇는다**. spec의 dataFlow ref
372
372
  ## 8. 흔한 함정
373
373
 
374
374
  - columns/indexes/securityRules/stateMachines JSON은 **전체 교체**. 일부 수정 시 반드시 `get` 후 편집.
375
- - 상태 컬럼의 생애주기(주문 status 등)를 spec.logic.stateTransitions에 적으면 SSOT 위반 — 저장되는 엔티티 상태는 db-tables.stateMachines가 SSOT. spec의 stateTransitions는 화면 휘발성 전이만.
375
+ - 상태 컬럼의 생애주기(주문 status 등)를 spec 쪽(흐름·레거시 stateTransitions)정의하면 SSOT 위반 — 저장되는 엔티티 상태는 db-tables.stateMachines가 SSOT. spec의 흐름은 `toState` 링크로 참조만 한다.
376
376
  - 전체 스펙 문서의 `--content`도 통째 교체. 작은 수정도 `get` 후 부분 편집해 통째 전송.
377
377
  - `relatedSpecIds`를 JSON에 명시해도 서버가 무시 (자동 관리 영역).
378
378
  - 새 테이블을 만들고 전체 스펙 인벤토리 갱신을 잊으면, 문서 읽는 사람이 그 테이블의 존재를 모른다.
@@ -2,7 +2,7 @@
2
2
  name: 2t-decencia-channel-github-issue
3
3
  description: gh CLI로 현재 repo에 GitHub 이슈를 작성한다. 이슈 1개=유형 1개(feat/fix/bug), 표준 본문 양식(작업내용·관련 명세 백링크·완료조건)으로 발행. "이슈 만들어줘"/"깃헙 이슈로 등록해줘" 요청 시, 또는 소통채널 기획·명세 작업 후 처리할 일들을 GitHub 이슈로 옮길 때 사용. 멱등성/중복방지·확인단계는 다루지 않음(요청대로 바로 생성).
4
4
  allowed-tools: Bash(gh:*) Bash(git:*) Read Write
5
- version: 1.29.0
5
+ version: 1.31.0
6
6
  ---
7
7
 
8
8
  <!-- ch-version-gate -->
@@ -2,7 +2,7 @@
2
2
  name: 2t-decencia-channel-orchestrator
3
3
  description: 소통채널 작업의 단일 진입점(디스패처). 사용자 요청을 듣고 7종(bootstrap·terraformer·change-manager·github-issue·issue-coder·pr-merger·sprint-runner) 중 적절한 곳으로 라우팅하고, 필요하면 여러 단계를 순차 오케스트레이션한다. 대화형 스킬은 메인 세션에서 Skill로, 자율 에이전트는 Agent로 위임. "소통채널 작업 해줘"·"이거 어떻게 처리하지?"처럼 무엇부터 할지 모를 때, 또는 신규기획/코드편입/기획변경/이슈/구현/머지/스프린트실행 어디로든 시작할 때.
4
4
  allowed-tools: Skill Agent Read Bash(ch:*) Bash(gh:*) Bash(git:*)
5
- version: 1.29.0
5
+ version: 1.31.0
6
6
  ---
7
7
 
8
8
  <!-- ch-version-gate -->
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: 2t-decencia-channel-policy-v2
3
+ description: |
4
+ [2t][v2] 소통채널 정책정의서 작성 가이드.
5
+ 여러 Story·영역에 걸치는 프로젝트 정책을 판정 가능한 문장으로 명문화한다.
6
+ 3단계 절차: 수확(유저플로우·로직 플로우의 분기에서 질문 발굴) → 확정(선택지 설계·의사결정) → 명문화.
7
+ Use when:
8
+ (1) 정책정의서를 새로 쓰거나 수정할 때,
9
+ (2) 유저플로우·기능명세를 검토하다 "이건 정해진 게 없다"는 질문이 나왔을 때,
10
+ (3) 알림 발송 매트릭스·크레딧 지급 기준·타임아웃 처리 같은 횡단 정책을 정리할 때.
11
+ version: 1.31.0
12
+ ---
13
+
14
+ <!-- ch-version-gate -->
15
+ ## ⚠️ 시작 전 필수 — 버전 게이트 (생략 금지)
16
+
17
+ 이 스킬로 **어떤 작업이든 수행하기 전에 가장 먼저** 아래를 실행한다:
18
+
19
+ ```bash
20
+ ch check
21
+ ```
22
+
23
+ - exit code 0(통과)이 **아니면 즉시 중단**한다. 출력에 안내된 업데이트 명령(`npm install -g @decencia/ch-cli@latest` 또는 `ch setup-skill`)을 사용자에게 전달하고, 갱신이 끝나기 전까지 **이 스킬의 어떤 단계도 진행하지 않는다.**
24
+ - `ch`가 미설치/미인증이어도 먼저 `ch check`를 시도한다. (네트워크 불가 시 ch check는 통과시키되 경고를 남긴다.)
25
+
26
+ 구버전 스킬·CLI 사용을 막기 위한 게이트다. 건너뛰지 말 것.
27
+
28
+
29
+ # 정책정의서 — 작성 표준
30
+
31
+ 정책정의서는 **여러 Story·영역에 걸치는 프로젝트 정책**을 판정 가능한 문장으로 기록하는 문서다. 웹 "정책정의서" 탭에 올린다.
32
+
33
+ ## 0. 경계 — 어디에 적나
34
+
35
+ | 규칙의 범위 | 적는 곳 |
36
+ |---|---|
37
+ | 한 Story 안에서만 유효한 규칙 | spec의 비즈니스 규칙 ([[2t-decencia-channel-spec-v2]] §8) |
38
+ | 여러 Story·영역에 걸치는 정책 | **정책정의서** (여기) |
39
+
40
+ - 정책 본문을 spec의 businessRules에 복붙하지 않는다. spec은 `연관 Spec ID` 링크로 잇는다.
41
+ - enum·상태값 정의는 여전히 db-tables가 SSOT다. 정책은 그 값을 *이용한 결정*만 적는다.
42
+
43
+ ## 1. 구성요소
44
+
45
+ | 항목 | 필드 | 작성 |
46
+ |---|---|---|
47
+ | Policy ID | `id` | 사용자 지정 권장 — `POL-001` (spec ID와 같은 패턴 `PREFIX-숫자`) |
48
+ | 정책명 | `name` | 무엇에 관한 정책인지 한 줄 |
49
+ | 영역/분류 | `category` | 자유 문자열. Epic 도메인 코드(AUTH/ORDER/POINT…)와 맞추면 검색이 편하다 |
50
+ | 본문 | `content` | **마크다운**. 웹 탭이 마크다운 뷰어로 렌더한다 |
51
+ | 연관 Spec ID | `relatedSpecIds[]` | 이 정책이 적용되는 Story들 |
52
+
53
+ ## 2. 작성 절차 (3단계)
54
+
55
+ ### ① 질문을 발굴한다 (수확)
56
+
57
+ 정해진 게 없는 지점을 찾아 질문 목록으로 만든다.
58
+
59
+ - **유저플로우에서 분기 처리된 부분들**을 검토한다 ([[2t-decencia-channel-userflow-v2]]). 갈림길마다 "이 갈림의 기준은 확정됐나?"
60
+ - **기능명세 로직 플로우의 실패·차단 분기**를 검토한다. 분기마다 "임계값·대기시간·처리방향이 정해졌나?"
61
+ - 산출물: "정책이 필요한 질문" 목록. 예: "결제 대기 중 상대가 응답하지 않으면 언제까지 기다리나?"
62
+
63
+ ### ② 선택지를 설계해 확정을 받아낸다 (확정)
64
+
65
+ - 질문마다 **선택지 2~4개**를 설계해 의사결정자에게 제시한다. 열린 질문("어떻게 할까요?")으로 묻지 않는다.
66
+ - 각 선택지에 트레이드오프를 한 줄씩 붙인다.
67
+ - 예: "무응답 대기: (A) 24시간 후 자동취소 — 단순, (B) 72시간 + 1회 리마인드 — 전환율 유리".
68
+ - 확정받지 못한 질문은 정책정의서에 넣지 않는다. 질문 목록에 남겨둔다.
69
+
70
+ ### ③ 판정 가능한 문장으로 굳힌다 (명문화)
71
+
72
+ 확정된 결정을 **참/거짓을 판정할 수 있는 문장**으로 적는다.
73
+
74
+ - 주체·조건·수치·기한이 문장 안에 있어야 한다.
75
+ - ❌ `무응답 시 적절히 처리한다`
76
+ - ❌ `크레딧은 일정 기간 후 만료된다`
77
+ - ⭕ `구매자가 결제 요청 후 24시간 내 응답하지 않으면 시스템이 거래를 자동 취소하고 판매자에게 알림톡을 보낸다`
78
+ - ⭕ `가입 축하 크레딧 3,000원은 가입일로부터 30일 후 자정에 만료된다`
79
+ - 표로 정리되는 정책(이벤트×수신처 매트릭스 등)은 마크다운 표를 쓴다.
80
+
81
+ ## 3. 정책정의서로 작성할 만한 내용
82
+
83
+ - 알림톡·이메일이 발송되는 **이벤트와 수신처 목록** (이벤트 × 채널 × 수신자 매트릭스)
84
+ - 무료 지급 크레딧의 **지급 기준·지급 액수·만료 기간**
85
+ - 거래 플로우 등에서 **한쪽이 응답하지 않을 때의 대기시간과 처리방향**
86
+ - 환불·취소 가능 조건과 수수료
87
+ - 등급·권한 승격/강등 기준
88
+ - 데이터 보존 기간·삭제 정책
89
+
90
+ 하나의 정책정의서 = 하나의 주제. 전 영역을 한 문서에 몰아넣지 않는다.
91
+
92
+ ## 4. 업로드 — 웹 탭 · CLI
93
+
94
+ ```bash
95
+ ch policies list # 표: id | category | name | specs
96
+ ch policies get POL-001 # 상세 (--json 이면 순수 JSON)
97
+ ch policies create --id POL-001 --name "거래 무응답 처리" \
98
+ --category ORDER --file ./policy.md --related-specs ORDER-003,ORDER-007
99
+ ch policies update POL-001 --file ./policy.md
100
+ ch policies delete POL-001
101
+ ```
102
+
103
+ - `--file`은 마크다운 본문. CRLF는 자동 정제된다. `--related-specs`는 쉼표 구분 spec ID.
104
+ - 웹 "정책정의서" 탭: 목록에서 클릭하면 사이드 패널에서 열람·수정한다 (상세기획과 같은 UI).
105
+ - Read-before-Write: 수정 전 `get`으로 현재 본문을 받아 편집한다.
106
+
107
+ ## 5. 흔한 함정
108
+
109
+ - **확정 없이 명문화** — ②를 건너뛰고 에이전트가 임의로 정책을 정하지 않는다. 선택지를 만들어 확정을 받는다.
110
+ - **판정 불가능한 문장** — "적절히", "일정 기간", "빠르게"가 들어가면 정책이 아니다. 수치로.
111
+ - **spec businessRules와 중복** — 한 Story 규칙은 spec에, 횡단 정책은 여기에. 복붙 금지 (§0).
112
+ - **질문 없이 백지에서 쓰기** — 정책은 유저플로우·로직 플로우의 분기에서 수확한 질문에서 나온다 (①).
113
+ - **한 문서에 전 영역 몰아넣기** — 주제별로 나눈다.
114
+ - 확정 안 된 질문을 본문에 "TBD"로 남기기 — 본문에는 확정된 것만. 미확정은 질문 목록으로 관리.
@@ -2,12 +2,12 @@
2
2
  name: 2t-decencia-channel-prd-v2
3
3
  description: |
4
4
  [2t][v2] 소통채널 PRD 작성/수정 가이드.
5
- Epic-Story 체계와의 연결성에 초점 (PRD Epic → spec의 --epic).
5
+ Epic-Story 체계와의 연결성에 초점 (PRD 기능 요구사항의 카테고리 → spec의 --epic).
6
6
  Use when:
7
7
  (1) PRD를 작성하거나 갱신할 때,
8
8
  (2) PRD 구성에서 Epic/스토리 구조를 후속 spec 작성에 매핑할 때,
9
9
  (3) Read-before-Write 규칙으로 PRD content를 안전하게 수정해야 할 때.
10
- version: 1.29.0
10
+ version: 1.31.0
11
11
  ---
12
12
 
13
13
  <!-- ch-version-gate -->
@@ -37,7 +37,7 @@ PRD는 **무엇을 왜 만드는가(기능·가치·범위)의 개요**만 다
37
37
  - 같은 설명을 PRD와 spec 양쪽에 적으면 변경 시 어긋난다. **상세 설명은 spec 한 곳에만** 둔다.
38
38
  - 독자가 동작 상세를 보고 싶으면 spec으로, 데이터 모델을 보고 싶으면 DB 스키마 문서(웹 "DB 스키마" 탭)로 간다 — PRD가 그 사본을 들고 있지 않는다.
39
39
 
40
- > spec의 상세 설명은 **완결 문장**으로 쓴다(필드명·단어 나열 금지) — [[2t-decencia-channel-spec-v2]] §5. PRD는 그 상세를 옮겨 적지 않고 한 줄 개요로만 가리킨다.
40
+ > spec의 상세 설명은 **완결 문장**으로 쓴다(필드명·단어 나열 금지) — [[2t-decencia-channel-spec-v2]] §7. PRD는 그 상세를 옮겨 적지 않고 한 줄 개요로만 가리킨다.
41
41
 
42
42
  ## 0. Read-before-Write
43
43
 
@@ -55,23 +55,48 @@ ch prd set --content /tmp/prd-edited.md # 2) 통째 교체 (버전
55
55
  # 프로젝트명 PRD
56
56
 
57
57
  ## 1. 개요
58
+ ### 1.1 제품 한줄 정의
59
+ ### 1.2 문제 정의
60
+ ### 1.3 해결 방식(핵심가치)
61
+ ### 1.4 핵심 업무 흐름
62
+
58
63
  ## 2. 사용자 페르소나 / 시나리오
59
64
 
60
- ## 3. Epic 목록
61
- ### 3.1 [Epic: 인증]
62
- - 목적, KPI
63
- - 포함 Story: 로그인, 회원가입, 비밀번호 재설정
64
- ### 3.2 [Epic: 결제]
65
+ ## 3. 용어정의
66
+ - 프로젝트에서 쓰는 단어의 확정 의미
67
+
68
+ ## 4. 전제조건/의존성
69
+ - 개발 팀에서 통제하지 못하는 것들
70
+ - 예) PG 가맹 심사는 고객사가 진행하며, 심사 완료 전까지 결제 연동 검증 불가
71
+ - 예) 서버 인프라는 고객사 기존 AWS 계정을 사용하며, 접근 권한은 착수 시 발급
72
+ - 예) 콘텐츠(상품 정보, 이미지)는 고객사가 입력
73
+
74
+ ## 5. 기술스택
75
+
76
+ ## 6. 외부연동목록
77
+
78
+ ## 7. 기능 요구사항
79
+ ### 7.1 [AUTH — 회원·인증]
80
+ | 기능 | 설명 |
81
+ |---|---|
82
+ | 로그인 | 이메일/비밀번호로 로그인한다 |
83
+ | 회원가입 | ... |
84
+ ### 7.2 [ORDER — 주문·결제]
65
85
  - ...
66
86
 
67
- ## 4. 비기능 요구사항
68
- ## 5. 마일스톤 / 일정
87
+ ## 8. 범위 제외
88
+ - 해당 프로젝트에서 포함되지 않는 개발 범위
69
89
  ```
70
90
 
71
91
  > ⚠️ **데이터 모델 절은 두지 않는다.** 테이블/컬럼/스키마는 PRD의 책임이 아니다 — DB 스키마는 [[2t-decencia-channel-db-schema-v2]](db-schema/db-tables)가 SSOT. PRD는 Epic/Story가 다루는 *기능*만 서술한다.
72
92
 
73
- PRD의 각 Epic → spec 작성 시 `--epic` 값으로 그대로 사용.
74
- PRD의Story 항목 → 1개 spec(=Story)으로 생성.
93
+ 기능 요구사항(§7)의 각 카테고리 → spec 작성 시 `--epic` 값으로 그대로 사용.
94
+ 기능 목록표의 기능 → 1개 spec(=Story)으로 생성.
95
+
96
+ **카테고리 = Epic = 도메인 단위 코드**다. 기능 묶음이 아니라 도메인으로 나눈다.
97
+ 표준 코드: `AUTH`(회원·인증) `PROD`(상품·탐색) `ORDER`(주문·결제) `POINT`(포인트·쿠폰) `ADMIN`(관리자) `SYS`(공통·시스템).
98
+ 프로젝트 성격에 맞게 추가한다. 코드 규칙·Spec ID 연계는 [[2t-decencia-channel-spec-v2]] §3.
99
+ 각 기능 행은 Story로 쪼갤 수 있어야 한다 — INVEST·수직 분할은 [[2t-decencia-channel-spec-v2]] §2.
75
100
 
76
101
  ## 2. 마크다운 작성 규칙
77
102
 
@@ -2,7 +2,7 @@
2
2
  name: 2t-decencia-channel-project-bootstrap
3
3
  description: 신규 기획을 사용자와 대화하며 step-by-step으로 소통채널 프로젝트로 만드는 오케스트레이터 스킬. (1)대화로 PRD 완성 → (2)기능명세(spec) 내용 확정 → (3)DB 스키마 → (4)spec 업로드 → (5)화면 구성·연결 → (6)SQA 시트. 각 단계 사용자 승인 게이트, 작성 디테일은 기존 2t-decencia-channel-*-v2 스킬을 적극 재사용. "새 기획 만들어줘"·"프로젝트 처음부터 세팅" 류 요청 시.
4
4
  allowed-tools: Bash(ch:*) Bash(git:*) Read Write
5
- version: 1.29.0
5
+ version: 1.31.0
6
6
  ---
7
7
 
8
8
  <!-- ch-version-gate -->
@@ -52,8 +52,9 @@ ch check
52
52
  - **schema 설정**(⚠️ 빠지면 웹 UI가 빈 칼럼으로 보임) + **specVersion=2**(Epic-Story·Story Point).
53
53
  - cwd에 `.ch-project`(`{"projectId":"..."}`) 기록 → 이후 issue-coder/머저가 사용.
54
54
 
55
- ### 0-1. 화면 모드 확인 (screensEnabled)
56
- - **신규 프로젝트는 서버가 `screensEnabled: true`로 만든다.** 화면 정보의 SSOT는 screens 리소스다. **신규 프로젝트 spec에는 `ui.route`를 쓰지 않는다.**
55
+ ### 0-1. 모드 확인 (screensEnabled · storySpecsEnabled)
56
+ - **신규 프로젝트는 서버가 `screensEnabled: true` + `storySpecsEnabled: true`로 만든다.** 화면 정보의 SSOT는 screens 리소스다. **신규 프로젝트 spec에는 `ui.route`를 쓰지 않는다.**
57
+ - `storySpecsEnabled=true`면 spec은 **스토리 명세 구조**다(스토리문장·사전 조건·로직 플로우·비즈니스 규칙 — [[2t-decencia-channel-spec-v2]] §1). 기존 프로젝트(플래그 없음)는 종전 ui/logic 구조 그대로다.
57
58
  - 기존 프로젝트를 이어 쓰면 `ch projects info --json`으로 `screensEnabled`를 본다. **키가 아예 없거나 false면 레거시다.** (레거시 프로젝트 응답에는 이 키가 없다. 없음 = false로 읽는다.)
58
59
  - **레거시는 route 방식을 그대로 유지한다.** §5(화면 구성)를 건너뛰고 spec의 `ui.route`를 계속 쓴다.
59
60
 
@@ -72,10 +73,13 @@ ch check
72
73
  ## 2. 기능명세(spec) — 내용 확정
73
74
  *(PRD 승인 후에만)*
74
75
  - `2t-decencia-channel-spec-v2` 규칙대로 PRD의 Epic/Story → spec 본문을 짠다.
75
- - ui 필드는 화면 모드 기준으로 채운다: `interactionMap`·`primaryActions`·`keyInformation`. **`route`·`access`·`figmaNodeId`·`file`은 쓰지 않는다.** 4개는 화면(screens) 소유다.
76
- - `screenRefs`(화면 연결)도 spec.ui 소유지만 지금은 비워둔다. 화면이 아직 없다 — §5에서 연결한다.
77
- - 레거시 프로젝트(§0-1) 예외다. 종전대로 `route`·`access`·`figmaNodeId`·`file`을 spec에 쓴다.
78
- - 이 단계의 산출물은 **기능 목록 + spec 본문 초안**이다. 항목: 이름 · epic · points · 핵심 액션 · 필요 테이블 후보.
76
+ - **Story 분해부터 검증한다** INVEST·수직 분할([[2t-decencia-channel-spec-v2]] §2). 기술 레이어("주문 테이블 생성")로 자르지 않고, 경로가 여럿이면 경로별로 쪼갠다.
77
+ - Epic은 도메인 단위 코드로 (AUTH/PROD/ORDER/POINT/ADMIN/SYS — [[2t-decencia-channel-spec-v2]] §3). PRD 기능 요구사항의 카테고리와 같은 코드다.
78
+ - spec 본문은 스토리 명세 구조로 짠다: 스토리문장(As a/I want/So that 줄글) · 사전 조건 · 로직 플로우 · 비즈니스 규칙.
79
+ - interactionMap·primaryActions·keyInformation·stateTransitions는 쓰지 않는다 스토리 명세에 없다.
80
+ - 화면 연결(`screenRefs`)은 지금은 비워둔다. 화면이 아직 없다 — §5에서 연결한다.
81
+ - 레거시 프로젝트(§0-1)는 예외다. 종전 ui/logic 구조([[2t-decencia-channel-spec-v2]] §L)로 쓴다.
82
+ - 이 단계의 산출물은 **기능 목록 + spec 본문 초안**이다. 항목: 이름 · Spec ID(EPIC-NNN) · epic · points · 스토리문장 · 필요 테이블 후보.
79
83
  - ⚠️ **서버 업로드는 여기서 하지 않는다.** 테이블을 먼저 만들고 §4에서 `dbTableRefs`와 함께 생성한다.
80
84
  - → **[게이트] 사용자 확인.** OK면 3단계.
81
85
 
@@ -83,7 +87,7 @@ ch check
83
87
  *(기능명세 승인 후에만)*
84
88
  - `2t-decencia-channel-db-schema-v2`로 db-schema(ERD/정책) + db-tables(컬럼·인덱스·보안규칙) 작성.
85
89
  - `spec.dbTableRefs` ↔ `dbTable.relatedSpecIds` 양방향.
86
- - **spec 업로드보다 앞선다.** spec 생성 시 `--db-tables`에 실제 tableId가 필요하기 때문이다([[2t-decencia-channel-spec-v2]] §6-3 — 테이블 먼저, spec 연결은 그 다음).
90
+ - **spec 업로드보다 앞선다.** spec 생성 시 `--db-tables`에 실제 tableId가 필요하기 때문이다([[2t-decencia-channel-spec-v2]] §10-3 — 테이블 먼저, spec 연결은 그 다음).
87
91
  - → **[게이트] 사용자 확인.** OK면 4단계.
88
92
 
89
93
  ## 4. spec 업로드
@@ -93,32 +97,25 @@ ch check
93
97
 
94
98
  ```bash
95
99
  ch specs create --id PROJ-001 --name "프로젝트 목록" \
96
- --device 웹 --domain 프로젝트 --type 화면 \
97
- --epic "프로젝트" --points 5 \
98
- --ui ui.json --logic logic.json --db-tables tbl_projects,tbl_members
100
+ --device 웹 --domain 프로젝트 --permission 관리자 \
101
+ --epic PROJ --points 5 \
102
+ --story "관리자는 진행 중인 프로젝트를 한눈에 보고, 원하는 프로젝트로 바로 들어가고 싶다." \
103
+ --preconditions ./preconditions.md \
104
+ --logic logic.json --db-tables tbl_projects,tbl_members
99
105
  ```
100
106
 
101
- ⚠️ `--device`·`--domain`·`--type`은 **필수 플래그**다. 빼면 CLI가 실행 즉시 실패한다. 값은 `ch specs meta --json`이 준 스키마 안에서 고른다.
107
+ ⚠️ `--device`·`--domain`은 **필수 플래그**다. 값은 `ch specs meta --json`이 준 스키마 안에서 고른다. `--domain`은 쉼표로 복수 지정 가능하다.
102
108
 
103
- `ui.json` (화면 모드):
104
-
105
- ```json
106
- {
107
- "interactionMap": "## 인터랙션\n...",
108
- "primaryActions": "- 프로젝트를 만든다",
109
- "keyInformation": "- 진행 중 프로젝트 수"
110
- }
111
- ```
112
-
113
- - `route`·`access`·`figmaNodeId`·`file`은 화면(screens)에 있다. spec.ui에 넣지 않는다.
114
- - `interactionMap`은 기능이 소유한다. 화면 모드에서도 계속 쓴다.
115
- - `screenRefs`도 여기에 넣지 않는다. 화면이 아직 없다 — 연결은 §5에서 `ch specs screen-refs`로 건다.
109
+ - `logic.json`은 로직 플로우 시나리오(실패·차단 분기 포함) + businessRules — [[2t-decencia-channel-spec-v2]] §7·§8.
110
+ - `--ui`는 생성 시점에 넣지 않는다. 화면이 아직 없다 — 연결은 §5에서 `ch specs screen-refs`로 건다.
111
+ - 레거시 프로젝트(§0-1)는 종전 플래그(`--type`·`--content`·`--ui ui.json`)를 그대로 쓴다 — [[2t-decencia-channel-cli-v2]] §1.
116
112
  - → **[게이트] 사용자 확인.** OK면 5단계.
117
113
 
118
114
  ## 5. 화면 구성·연결
119
115
  *(spec 업로드 후에만. 레거시 프로젝트는 건너뛴다 — §0-1)*
120
116
 
121
117
  기능들을 **화면에 배치**한다. 화면은 사용자가 실제로 마주하는 단위다.
118
+ 화면마다 적을 내용(필수 기재항목 6종·디스크립션 작성규칙·예외상태 4종)은 [[2t-decencia-channel-screen-v2]]를 따른다.
122
119
 
123
120
  **입력**: §2의 기능 목록 + §4에서 만든 spec ID.
124
121
 
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: 2t-decencia-channel-screen-v2
3
+ description: |
4
+ [2t][v2] 소통채널 화면설계서 작성 가이드.
5
+ 화면당 필수 기재항목 6종(ID·화면명·접근권한 / 영역별 표시 데이터 / 액션별 동작·이동 /
6
+ 입력 검증 규칙 / 예외상태 4종 / 연결 기획 ID)과 디스크립션 작성규칙(출처까지·결과까지·검증까지·정책은 참조만).
7
+ IA 트리 뷰(zoom/pan)·와이어프레임+디스크립션 좌우 분할 뷰 기준.
8
+ Use when:
9
+ (1) 화면(screens) 문서를 작성·수정할 때,
10
+ (2) 화면의 표시 데이터·액션·입력 검증·예외상태를 기재할 때,
11
+ (3) 웹 "화면" 탭의 IA 트리·화면 상세에 올릴 내용을 쓸 때.
12
+ version: 1.31.0
13
+ ---
14
+
15
+ <!-- ch-version-gate -->
16
+ ## ⚠️ 시작 전 필수 — 버전 게이트 (생략 금지)
17
+
18
+ 이 스킬로 **어떤 작업이든 수행하기 전에 가장 먼저** 아래를 실행한다:
19
+
20
+ ```bash
21
+ ch check
22
+ ```
23
+
24
+ - exit code 0(통과)이 **아니면 즉시 중단**한다. 출력에 안내된 업데이트 명령(`npm install -g @decencia/ch-cli@latest` 또는 `ch setup-skill`)을 사용자에게 전달하고, 갱신이 끝나기 전까지 **이 스킬의 어떤 단계도 진행하지 않는다.**
25
+ - `ch`가 미설치/미인증이어도 먼저 `ch check`를 시도한다. (네트워크 불가 시 ch check는 통과시키되 경고를 남긴다.)
26
+
27
+ 구버전 스킬·CLI 사용을 막기 위한 게이트다. 건너뛰지 말 것.
28
+
29
+
30
+ # 화면설계서 — 작성 표준
31
+
32
+ 화면설계서는 화면(screen) 하나가 **무엇을 보여주고, 눌리면 어떻게 되고, 어떤 입력을 어떻게 검증하는지**를 적는 문서다. 웹 "화면" 탭의 IA 트리에서 노드를 클릭하면 보인다.
33
+
34
+ 역할 분담: 흐름(시나리오)은 spec([[2t-decencia-channel-spec-v2]] §7), 여정 갈림길은 유저플로우([[2t-decencia-channel-userflow-v2]]), 횡단 정책은 정책정의서([[2t-decencia-channel-policy-v2]]). 화면설계서는 **그 화면 안에서 보이는 것·눌리는 것**만 적는다.
35
+
36
+ ## 1. 필수 기재항목
37
+
38
+ | 항목 | 내용 |
39
+ |---|---|
40
+ | 화면 ID + 화면명 + 접근권한 | `id`(슬러그, 예: `STORE-ORDER-DETAIL`) · `name` · `access` |
41
+ | 영역별 표시 데이터 | 화면을 영역(헤더/목록/요약 카드…)으로 나누고, 각 영역에 표시되는 데이터를 **출처까지** 적는다 |
42
+ | 액션별 동작 및 이동화면 | 버튼·링크·제스처마다 동작과 **결과**(이동 화면 ID·성공/실패 갈림)를 적는다 |
43
+ | 입력 검증 규칙 | 입력마다 **필수/형식/길이/중복** + 실패 시 노출 문구 |
44
+ | 예외상태 4종 | **빈상태 · 로딩 · 에러 · 권한 없음** — 4종 전부, 각각 무엇을 보여주는지 |
45
+ | 연결된 기획 ID | 이 화면에 걸린 spec ID들 (`relatedSpecIds` — 서버 관리, `ch specs screen-refs`로 연결) |
46
+
47
+ ## 2. 디스크립션 작성규칙
48
+
49
+ | 규칙 | 나쁜 예 | 좋은 예 |
50
+ |---|---|---|
51
+ | **데이터는 출처까지** | 주문 정보 표시 | `ORDERS.주문번호, 상품명, 결제금액` |
52
+ | **버튼은 결과까지** | 취소 버튼 | 취소 확정 → PG 취소 요청, 성공 시 `SCR-08` 이동, 실패 시 `E-02` |
53
+ | **입력은 검증까지** | 사유 입력 | 필수, 선택형+기타(200자), 미선택 시 '사유를 선택해주세요' 노출 |
54
+ | **정책은 참조만** | 취소 규칙 본문을 복사해 기재 | `POL-007` 적용 |
55
+
56
+ - 데이터 출처는 `테이블.컬럼` 이름 참조다. 컬럼 정의(type·nullable)는 적지 않는다 — db-tables가 SSOT.
57
+ - 이동 화면은 화면 ID로 가리킨다. "다음 화면으로" 같은 서술 금지.
58
+ - 정책 본문을 복사하지 않는다. Policy ID로 참조만 한다.
59
+
60
+ ## 3. 예외상태 4종 — 빠짐없이
61
+
62
+ 모든 화면은 4종을 전부 적는다. "해당 없음"이면 그렇게 적는 것도 기재다.
63
+
64
+ | 상태 | 적을 것 |
65
+ |---|---|
66
+ | 빈상태 | 데이터 0건일 때 무엇을 보여주나 (안내 문구 + 유도 액션) |
67
+ | 로딩 | 스피너/스켈레톤 어느 쪽인지, 어디에 |
68
+ | 에러 | 실패 안내 + 재시도 수단 |
69
+ | 권한 없음 | 차단 화면인지 리다이렉트인지, 안내 문구 |
70
+
71
+ ## 4. IA 트리 뷰
72
+
73
+ - 웹 "화면" 탭은 화면들을 **IA 트리**(route 계층)로 보여준다. 유저플로우와 같은 zoom in/out·pan 뷰어다.
74
+ - 노드를 클릭하면 화면 상세가 열린다: **좌측 와이어프레임 뷰 · 우측 디스크립션**(§1 항목들).
75
+ - 트리가 읽히려면 route를 계층적으로 짓는다 (`/store/orders` → `/store/orders/[id]`). 화면 ID 슬러그도 계층을 반영한다.
76
+
77
+ ## 5. 업로드 — CLI
78
+
79
+ 화면 생성·수정의 기본 명령은 [[2t-decencia-channel-cli-v2]] §3. 구조 확장 필드는 JSON 파일로 준다.
80
+
81
+ ```bash
82
+ ch screens update SCR-ORDER-DETAIL \
83
+ --areas ./areas.json --actions ./actions.json --input-rules ./input-rules.json \
84
+ --states ./states.json
85
+ ```
86
+
87
+ `areas.json` — 영역별 표시 데이터 (출처까지):
88
+
89
+ ```json
90
+ [
91
+ { "name": "주문 요약", "description": "ORDERS.주문번호, 상품명, 결제금액" },
92
+ { "name": "배송 정보", "description": "SHIPMENTS.송장번호, 택배사, 배송상태" }
93
+ ]
94
+ ```
95
+
96
+ `actions.json` — 액션별 동작·이동 (결과까지):
97
+
98
+ ```json
99
+ [
100
+ { "name": "취소 확정", "description": "PG 취소 요청. 성공 시 이동, 실패 시 E-02 노출", "targetScreenId": "SCR-ORDER-CANCELED" },
101
+ { "name": "뒤로가기", "description": "목록으로 복귀 (변경사항 없음)", "targetScreenId": "SCR-ORDER-LIST" }
102
+ ]
103
+ ```
104
+
105
+ `input-rules.json` — 입력 검증 규칙:
106
+
107
+ ```json
108
+ [
109
+ { "name": "취소 사유", "rules": "필수, 선택형+기타(200자), 미선택 시 '사유를 선택해주세요' 노출" }
110
+ ]
111
+ ```
112
+
113
+ `states.json` — 예외상태 4종 필수 (추가 상태 허용):
114
+
115
+ ```json
116
+ [
117
+ { "name": "빈상태", "description": "주문 내역이 없습니다 + [상품 보러가기]" },
118
+ { "name": "로딩", "description": "스켈레톤 3행" },
119
+ { "name": "에러", "description": "불러오지 못했습니다 + [재시도]" },
120
+ { "name": "권한 없음", "description": "본인 주문만 열람 가능 안내 후 목록으로 리다이렉트" }
121
+ ]
122
+ ```
123
+
124
+ - 배열 JSON은 **통째 교체**다. 수정 전 `ch screens get <id> --json`으로 받아 편집한다 (Read-before-Write).
125
+ - `targetScreenId`는 실존 화면 ID여야 한다 (서버 검증).
126
+
127
+ ## 6. 흔한 함정
128
+
129
+ - **출처 없는 데이터 서술** — "주문 정보 표시"는 기재가 아니다. `테이블.컬럼`까지.
130
+ - **결과 없는 버튼 서술** — "취소 버튼"은 기재가 아니다. 성공/실패 뒤에 무엇이 오는지까지.
131
+ - **검증 없는 입력 서술** — 필수/형식/길이/중복 + 실패 문구까지.
132
+ - **정책 본문 복붙** — Policy ID 참조만 (§2). 정책이 바뀌면 화면설계서가 낡는다.
133
+ - **예외상태 일부 생략** — 4종 전부. 해당 없으면 "해당 없음"이라고 적는다.
134
+ - **흐름 서술** — 여러 화면에 걸친 시나리오는 spec·유저플로우의 몫이다. 이 화면 안의 것만.
135
+ - 화면과 spec은 N:1이다. spec 수만큼 화면을 만들지 않는다 ([[2t-decencia-channel-spec-v2]] §9).