@decencia/ch-cli 1.3.4 → 1.4.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/dist/commands/backup.d.ts +6 -0
- package/dist/commands/backup.d.ts.map +1 -0
- package/dist/commands/backup.js +200 -0
- package/dist/commands/backup.js.map +1 -0
- package/dist/commands/check.d.ts +3 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +189 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/setup-skill.d.ts.map +1 -1
- package/dist/commands/setup-skill.js +47 -10
- package/dist/commands/setup-skill.js.map +1 -1
- package/dist/commands/specs.d.ts.map +1 -1
- package/dist/commands/specs.js +3 -0
- package/dist/commands/specs.js.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/skill-meta.d.ts +2 -0
- package/dist/skill-meta.d.ts.map +1 -0
- package/dist/skill-meta.js +15 -0
- package/dist/skill-meta.js.map +1 -0
- package/package.json +3 -2
- package/skill/2t-decencia-channel-change-manager/SKILL.md +73 -0
- package/skill/2t-decencia-channel-change-propagation-v2/SKILL.md +401 -0
- package/skill/2t-decencia-channel-cli-v2/SKILL.md +194 -0
- package/skill/2t-decencia-channel-db-schema-v2/SKILL.md +313 -0
- package/skill/2t-decencia-channel-github-issue/SKILL.md +116 -0
- package/skill/2t-decencia-channel-orchestrator/SKILL.md +64 -0
- package/skill/2t-decencia-channel-prd-v2/SKILL.md +73 -0
- package/skill/2t-decencia-channel-project-bootstrap/SKILL.md +68 -0
- package/skill/2t-decencia-channel-spec-v2/SKILL.md +463 -0
- package/skill/2t-decencia-channel-sprint-builder-v2/SKILL.md +77 -0
- package/skill/2t-decencia-channel-sqa-v2/SKILL.md +422 -0
- package/skill/2t-decencia-channel-work-status-v2/SKILL.md +189 -0
- package/dist/commands/invitations.d.ts +0 -3
- package/dist/commands/invitations.d.ts.map +0 -1
- package/dist/commands/invitations.js +0 -48
- package/dist/commands/invitations.js.map +0 -1
- package/skill/SKILL.md +0 -500
|
@@ -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.4.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로.
|
|
@@ -0,0 +1,422 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: 2t-decencia-channel-sqa-v2
|
|
3
|
+
description: |
|
|
4
|
+
[2t][v2] 소통채널 SQA 운영 가이드.
|
|
5
|
+
시트 구성 2축(A. 명세별 기능 TC — §4.3 영역별 TC 번들 라이브러리에서 도출 / B. 비기능 4축 표준 40개),
|
|
6
|
+
§4.3은 명세 영역(접근권한/목록/폼/삭제/상태전이/UI일반/백엔드/규칙/내보내기/차트)마다
|
|
7
|
+
Functional·Publishing·Frontend·Backend 카테고리를 한 묶음으로 제공하는 누적 라이브러리.
|
|
8
|
+
Use when:
|
|
9
|
+
(1) SQA 시트를 새로 작성하거나 항목을 보강할 때,
|
|
10
|
+
(2) spec.tasks에서 추출한 검증 항목을 SQA 시트에 등록할 때,
|
|
11
|
+
(3) 보안/성능/접근성/호환성 비기능 TC를 시트에 채워야 할 때,
|
|
12
|
+
(4) 명세 영역별 완성형 TC 번들(퍼블리싱/프론트/백엔드 디센시아 운영 관점 포함)을 가져다 쓸 때,
|
|
13
|
+
(5) 새 명세 작업 중 반복 패턴을 발견해 영역별 번들을 보강할 때,
|
|
14
|
+
(6) Sprint 종료 전 spec별 SQA 통과 여부를 점검할 때.
|
|
15
|
+
version: 1.4.0
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
<!-- ch-version-gate -->
|
|
19
|
+
## ⚠️ 시작 전 필수 — 버전 게이트 (생략 금지)
|
|
20
|
+
|
|
21
|
+
이 스킬로 **어떤 작업이든 수행하기 전에 가장 먼저** 아래를 실행한다:
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
ch check
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
- exit code 0(통과)이 **아니면 즉시 중단**한다. 출력에 안내된 업데이트 명령(`npm install -g @decencia/ch-cli@latest` 또는 `ch setup-skill`)을 사용자에게 전달하고, 갱신이 끝나기 전까지 **이 스킬의 어떤 단계도 진행하지 않는다.**
|
|
28
|
+
- `ch`가 미설치/미인증이어도 먼저 `ch check`를 시도한다. (네트워크 불가 시 ch check는 통과시키되 경고를 남긴다.)
|
|
29
|
+
|
|
30
|
+
구버전 스킬·CLI 사용을 막기 위한 게이트다. 건너뛰지 말 것.
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
# SQA — spec.tasks 와의 통합
|
|
34
|
+
|
|
35
|
+
## 0. Read-before-Write
|
|
36
|
+
|
|
37
|
+
시트 항목(item) 단위 CRUD는 이제 CLI로 모두 지원된다(§3.5). 항상 `ch sqa get <sheetId> --json`으로 현재 항목 목록·id를 먼저 받고 수정한다. 항목 수정/삭제/순서변경은 `id`를 키로 지정하므로 최신 id 확보가 선행되어야 한다.
|
|
38
|
+
|
|
39
|
+
## 1. 핵심 규칙
|
|
40
|
+
|
|
41
|
+
> **spec의 완료 조건 = 그 spec에 연결된 SQA 항목이 모두 통과**
|
|
42
|
+
|
|
43
|
+
별도 acceptanceCriteria 필드 없음. spec.tasks의 완료(체크박스)는 개발 진척 표시이고, **공식 완료는 SQA**가 판정한다.
|
|
44
|
+
|
|
45
|
+
## 2. spec.tasks → SQA 항목 매핑
|
|
46
|
+
|
|
47
|
+
spec.tasks 작성 시 다음 패턴 권장:
|
|
48
|
+
- Task: 개발자가 끝낼 단위 작업 (예: "로그인 폼 UI 구현")
|
|
49
|
+
- SQA 항목: QA가 검증할 시나리오 (예: "잘못된 비밀번호 5회 시 잠금")
|
|
50
|
+
|
|
51
|
+
**1:N 관계**: 1개 task가 여러 SQA 항목을 유발할 수 있음. SQA 항목 작성 시 `relatedSpec` + (자유) `relatedTask` 메모로 추적.
|
|
52
|
+
|
|
53
|
+
## 3. 신규 SQA 작성 워크플로우
|
|
54
|
+
|
|
55
|
+
0. **시트 생성** (없으면 먼저):
|
|
56
|
+
```bash
|
|
57
|
+
# --date 생략 시 오늘로 자동 채움 (서버 DTO가 performDate 필수)
|
|
58
|
+
ch sqa create --name "Sprint 1 SQA" --date 2026-06-01
|
|
59
|
+
```
|
|
60
|
+
1. **spec.tasks를 가져온다**:
|
|
61
|
+
```bash
|
|
62
|
+
ch specs get <specId> --json | jq '.tasks'
|
|
63
|
+
```
|
|
64
|
+
2. 각 task의 description(있다면)과 logic.businessRules 참고하여 검증 항목 도출.
|
|
65
|
+
3. SQA 시트에 항목 추가 (§3.5 CLI 명령 사용).
|
|
66
|
+
4. 항목 작성 시 `relatedSpec`에 specId 명시(생략 시 미연결).
|
|
67
|
+
|
|
68
|
+
## 3.5 시트 항목(item) CRUD — CLI 완전 지원
|
|
69
|
+
|
|
70
|
+
시트 항목은 시트 문서의 `items[]` 배열에 임베드된다. 항목 단위 CRUD가 모두 CLI로 지원된다(ch-cli 1.3.3+).
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
# 단건 추가 ( --spec 생략 가능 → 미연결 항목 )
|
|
74
|
+
ch sqa add-item <sheetId> --test "잘못된 비밀번호 5회 시 잠금" --spec <specId>
|
|
75
|
+
|
|
76
|
+
# 일괄 추가 — JSON 배열 또는 { "items": [...] }
|
|
77
|
+
# items.json: [ { "testItem": "...", "relatedSpec": "<specId>" }, { "testItem": "..." } ]
|
|
78
|
+
ch sqa add-items <sheetId> --file items.json
|
|
79
|
+
|
|
80
|
+
# 항목 수정 ( --test / --spec 중 지정한 것만 변경, --spec "" 로 연결 해제 )
|
|
81
|
+
ch sqa update-item <sheetId> <itemId> --test "수정된 항목명" --spec <specId>
|
|
82
|
+
|
|
83
|
+
# 항목 삭제 ( 삭제 후 order 1..N 자동 재정렬 )
|
|
84
|
+
ch sqa delete-item <sheetId> <itemId>
|
|
85
|
+
|
|
86
|
+
# 순서 변경 ( 현재 모든 itemId를 빠짐없이·중복없이 나열 )
|
|
87
|
+
ch sqa reorder-items <sheetId> --order item-0-...,item-1-...,item-2-...
|
|
88
|
+
ch sqa reorder-items <sheetId> --file order.json # ["id1","id2",...] 또는 { "order":[...] }
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
- `<itemId>`는 `ch sqa get <sheetId> --json`의 `items[].id`. 항상 최신값을 먼저 확보(§0).
|
|
92
|
+
- 시트 항목 CRUD는 **시트 템플릿**을 바꾼다. 이미 `start-run`으로 스냅샷된 진행 중 Run에는 소급 적용되지 않는다.
|
|
93
|
+
- 항목 결과(Pass/Fail) 입력은 Run 쪽: `ch sqa check <runId> <itemId> --result yes|no --note ...` / `check-bulk`.
|
|
94
|
+
|
|
95
|
+
## 4. SQA 시트 구성 표준 — 무엇을 넣어야 하는가
|
|
96
|
+
|
|
97
|
+
명세별 E2E 항목만 넣고 끝내지 말 것. SQA 시트는 다음 **2축**으로 구성한다.
|
|
98
|
+
|
|
99
|
+
| 축 | 단위 | 출처 / 도출 방법 | 비고 |
|
|
100
|
+
|---|---|---|---|
|
|
101
|
+
| A. 명세별 기능 TC | spec 1개당 | spec.ui/logic/tasks를 읽고 **§4.3 영역별 TC 번들 라이브러리**에서 해당 영역들을 골라 명세 맥락으로 구체화 | spec당 보통 5~15개 |
|
|
102
|
+
| B. 비기능 4축 표준 TC | 시트 1개당 묶음 | 표준(OWASP/Core Web Vitals/WCAG/호환성)을 그대로 등록 | **시트당 40개** (보안 12 + 성능 10 + 접근성 10 + 호환성 8) |
|
|
103
|
+
|
|
104
|
+
축 B는 spec 단위가 아니므로 `relatedSpec`을 비워두거나 "common"/"standard" 가상 specId로 일관 관리.
|
|
105
|
+
|
|
106
|
+
§4.3 라이브러리에는 **Functional/Publishing/Frontend/Backend 카테고리가 영역별로 한 묶음**으로 들어 있다. 별도 시트가 아니라 각 명세 A축 항목으로 풀어 쓴다.
|
|
107
|
+
|
|
108
|
+
## 4.1 시트 구성 권장 비율
|
|
109
|
+
|
|
110
|
+
| 우선순위 | 비중 | 기준 |
|
|
111
|
+
|---|---|---|
|
|
112
|
+
| High | 60% | 핵심 비즈니스 플로우, 권한/인증, 데이터 무결성, 보안 핵심 |
|
|
113
|
+
| Medium | 30% | 부가 기능, 성능, 접근성, 호환성 |
|
|
114
|
+
| Low | 10% | UI 디테일, 반응형, 에지 케이스 |
|
|
115
|
+
|
|
116
|
+
## 4.2 비기능 4축 표준 TC (40개)
|
|
117
|
+
|
|
118
|
+
모든 SQA 시트에 아래 항목을 포함한다. "ISO/IEC 25010 + OWASP Top 10:2025 + WCAG 2.2 AA + Core Web Vitals" 기반.
|
|
119
|
+
|
|
120
|
+
### 4.2.1 Security — OWASP Top 10:2025 (12개)
|
|
121
|
+
|
|
122
|
+
| # | subType | TC 항목 | 근거 |
|
|
123
|
+
|---|---|---|---|
|
|
124
|
+
| 1 | access-control | 비인가 역할로 관리자 페이지 접근 시 차단/리다이렉트 | A01 |
|
|
125
|
+
| 2 | access-control | 권한별 API 엔드포인트 403 반환 | A01 |
|
|
126
|
+
| 3 | config | 보안 헤더(CSP, X-Frame-Options, X-Content-Type) 설정 | A02 |
|
|
127
|
+
| 4 | config | 에러 응답에 스택트레이스/디버그 정보 미노출 | A02 |
|
|
128
|
+
| 5 | input-validation | `<script>` 삽입 시 이스케이프 처리 (XSS) | A03 |
|
|
129
|
+
| 6 | input-validation | NoSQL/SQL 인젝션 패턴 필터링 | A03 |
|
|
130
|
+
| 7 | input-validation | 서버사이드 유효성 검증 (클라이언트 우회 방지) | A03 |
|
|
131
|
+
| 8 | auth-security | 만료 토큰으로 API 호출 시 401 | A07 |
|
|
132
|
+
| 9 | auth-security | 로그인 실패 N회 시 잠금/지연 | A07 |
|
|
133
|
+
| 10 | auth-security | 세션 만료 후 재인증 요구 | A07 |
|
|
134
|
+
| 11 | data-protection | 모든 통신 HTTPS 강제 | A08 |
|
|
135
|
+
| 12 | supply-chain | `npm audit` / 의존성 취약점 스캔 통과 | A06 |
|
|
136
|
+
|
|
137
|
+
### 4.2.2 Performance — Core Web Vitals + ISO 25010 (10개)
|
|
138
|
+
|
|
139
|
+
| # | subType | TC 항목 | 기준 |
|
|
140
|
+
|---|---|---|---|
|
|
141
|
+
| 1 | loading | LCP ≤ 2.5s | CWV |
|
|
142
|
+
| 2 | loading | FCP ≤ 1.8s | CWV |
|
|
143
|
+
| 3 | interactivity | INP ≤ 200ms | CWV |
|
|
144
|
+
| 4 | visual-stability | CLS < 0.1 | CWV |
|
|
145
|
+
| 5 | server-response | TTFB ≤ 800ms | CWV |
|
|
146
|
+
| 6 | server-response | API P95 ≤ 500ms | ISO 25010 |
|
|
147
|
+
| 7 | resource | 이미지 최적화 (WebP/AVIF, lazy load) | ISO 25010 |
|
|
148
|
+
| 8 | resource | JS 번들 gzip ≤ 200KB | ISO 25010 |
|
|
149
|
+
| 9 | caching | 정적 자산 Cache-Control 헤더 | ISO 25010 |
|
|
150
|
+
| 10 | memory | SPA 장시간 사용 시 메모리 누수 없음 | ISO 25010 |
|
|
151
|
+
|
|
152
|
+
### 4.2.3 Accessibility — WCAG 2.2 Level AA (10개)
|
|
153
|
+
|
|
154
|
+
| # | subType | TC 항목 | 근거 |
|
|
155
|
+
|---|---|---|---|
|
|
156
|
+
| 1 | perceivable | 의미 있는 이미지에 alt 제공 | WCAG 1.1.1 |
|
|
157
|
+
| 2 | color-contrast | 일반 텍스트 대비 4.5:1 이상 | WCAG 1.4.3 |
|
|
158
|
+
| 3 | color-contrast | 대형 텍스트(18pt+) 대비 3:1 이상 | WCAG 1.4.3 |
|
|
159
|
+
| 4 | keyboard | Tab/Enter/Esc로 주요 기능 사용 가능 | WCAG 2.1.1 |
|
|
160
|
+
| 5 | keyboard | 포커스 표시(outline) 시각적으로 확인 가능 | WCAG 2.4.7 |
|
|
161
|
+
| 6 | operable | Skip to content 링크 제공 | WCAG 2.4.1 |
|
|
162
|
+
| 7 | understandable | 페이지별 고유 `<title>` | WCAG 2.4.2 |
|
|
163
|
+
| 8 | understandable | 모든 폼 input에 `<label>` 연결 | WCAG 1.3.1 |
|
|
164
|
+
| 9 | understandable | 폼 에러 위치/내용 식별 가능 | WCAG 3.3.1 |
|
|
165
|
+
| 10 | touch-target | 터치 타겟 최소 24×24px | WCAG 2.5.8 |
|
|
166
|
+
|
|
167
|
+
### 4.2.4 Compatibility — 크로스 브라우저/디바이스 (8개)
|
|
168
|
+
|
|
169
|
+
| # | subType | TC 항목 |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| 1 | browser | Chrome 최신 2버전 정상 동작 |
|
|
172
|
+
| 2 | browser | Safari 최신 2버전 정상 동작 |
|
|
173
|
+
| 3 | browser | Edge 최신 버전 정상 동작 |
|
|
174
|
+
| 4 | browser | Firefox 최신 버전 정상 동작 |
|
|
175
|
+
| 5 | mobile | iOS Safari 정상 동작 |
|
|
176
|
+
| 6 | mobile | Android Chrome 정상 동작 |
|
|
177
|
+
| 7 | responsive | 375 / 768 / 1440 레이아웃 정상 |
|
|
178
|
+
| 8 | responsive | 가로/세로 회전 시 레이아웃 유지 |
|
|
179
|
+
|
|
180
|
+
## 4.3 명세별 기능 TC 도출 가이드 (A축) — 영역별 TC 번들 라이브러리
|
|
181
|
+
|
|
182
|
+
**이 섹션의 최종 목표**: 각 "명세 영역"마다 그대로 갖다 쓸 수 있는 **완성형 TC 번들**을 누적해 라이브러리로 키운다. 신규 명세를 만나면 해당 영역의 번들에서 골라 명세 맥락으로만 구체화하면 된다. (현재는 기반 단계 — 골격 + 일부 영역 시범 채움. 누락 영역은 시간이 지나며 보강한다.)
|
|
183
|
+
|
|
184
|
+
### 사용 절차
|
|
185
|
+
|
|
186
|
+
1. spec.ui/logic/tasks를 읽어 그 spec이 속한 **명세 영역**을 1~N개 식별 (예: "지점 관리 화면" = 접근권한 + 목록 + 등록/수정 폼 + 삭제).
|
|
187
|
+
2. 각 영역 번들의 항목을 가져와 그 명세의 도메인 단어로 구체화. 추상 문구 그대로 박지 말 것.
|
|
188
|
+
- 추상: "Update시 모달창이나 수정 페이지로 데이터가 제대로 전달 되는가?"
|
|
189
|
+
- 명세별: "지점 수정 모달 진입 시 기존 지점명·지역·전화 필드가 prefill됨"
|
|
190
|
+
3. 명세 성격상 해당 안 되는 항목은 스킵 (예: API spec엔 퍼블리싱·반응형 항목 적용 X).
|
|
191
|
+
4. `relatedSpec`은 해당 명세 specId (A축이므로 항상 명시).
|
|
192
|
+
|
|
193
|
+
### 번들 구성 원칙
|
|
194
|
+
|
|
195
|
+
각 영역 번들은 다음 카테고리를 한 묶음으로 제공한다 — 별도로 흩어놓지 않는다.
|
|
196
|
+
- **Functional** — 영역 본질의 정상/비정상 경로
|
|
197
|
+
- **Publishing** — 디자인 시스템·아이콘·이미지·패딩·반응형
|
|
198
|
+
- **Frontend** — 상태 전달·refresh·permission·필터·네비게이션
|
|
199
|
+
- **Backend** — RLS/firestore.rules, 클라이언트 직접 CRUD 원칙
|
|
200
|
+
|
|
201
|
+
→ 한 영역의 번들만 펼쳐도 "그 영역 명세를 쓸 때 검토해야 할 모든 관점"이 한 곳에 있다.
|
|
202
|
+
|
|
203
|
+
**명세 복잡도별 권장 TC 수**:
|
|
204
|
+
- 단순(조회만): 5~8개
|
|
205
|
+
- 보통(CRUD): 8~12개
|
|
206
|
+
- 복잡(다기능): 12~20개
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
### 4.3.1 [영역] 접근 권한 / 인증
|
|
211
|
+
**Trigger**: spec.logic에 역할/권한 분기, 보호된 라우트, 로그인 게이트 언급이 있을 때.
|
|
212
|
+
|
|
213
|
+
| 카테고리 | TC 후보 |
|
|
214
|
+
|---|---|
|
|
215
|
+
| Functional | 허용 역할로 접근 → 정상 렌더링 |
|
|
216
|
+
| Functional | 비허용 역할로 접근 → 403 또는 리다이렉트 |
|
|
217
|
+
| Functional | 비로그인 상태 접근 → 로그인 페이지로 리다이렉트 |
|
|
218
|
+
| Functional | 로그인 후 원래 가려던 페이지로 복귀 (returnTo) |
|
|
219
|
+
| Frontend | 기본 페이지(로그인 전, 로그인 후)가 제대로 설정되어 있는가? — 명세에 맞춰 구체화 |
|
|
220
|
+
| Backend | 권한별 API 엔드포인트 호출 시 서버에서 403 검증 |
|
|
221
|
+
|
|
222
|
+
### 4.3.2 [영역] 목록 화면 (List)
|
|
223
|
+
**Trigger**: spec.ui에 테이블/카드 그리드/리스트, 검색/필터/정렬/페이징 언급.
|
|
224
|
+
|
|
225
|
+
| 카테고리 | TC 후보 |
|
|
226
|
+
|---|---|
|
|
227
|
+
| Functional | 데이터 정상 조회 및 N개 표시 |
|
|
228
|
+
| Functional | 빈 상태(0건) → 빈 상태 안내 표시 |
|
|
229
|
+
| Functional | 검색어 입력 → 매칭 결과만 표시 |
|
|
230
|
+
| Functional | 필터 적용 → 조건 일치 결과만 표시 |
|
|
231
|
+
| Functional | 정렬 토글 → 해당 컬럼 기준 오름/내림차순 |
|
|
232
|
+
| Functional | 페이징/무한스크롤 → 다음 페이지 정상 로딩 |
|
|
233
|
+
| Publishing | 정확한 아이콘을 사용하고 있는가? (정렬·필터·액션 아이콘 일치) |
|
|
234
|
+
| Publishing | 화면 크기가 변하는 환경에서도 반응형으로 레이아웃이 잘 구성되어 있는가? |
|
|
235
|
+
| Publishing | 화면 상하좌우 패딩이 Design system의 규정을 준수하고 있는가? |
|
|
236
|
+
| Frontend | 본인의 데이터만 제대로 필터링해서 쿼리하고 있는가?(타 유저 데이터 노출 차단) |
|
|
237
|
+
|
|
238
|
+
### 4.3.3 [영역] 등록/수정 폼
|
|
239
|
+
**Trigger**: spec.ui에 입력 폼, 모달, 등록/수정/저장 액션 언급.
|
|
240
|
+
|
|
241
|
+
| 카테고리 | TC 후보 |
|
|
242
|
+
|---|---|
|
|
243
|
+
| Functional | 정상값 입력 + 저장 → 성공 후 목록에 반영 |
|
|
244
|
+
| Functional | 필수 필드 빈값으로 저장 → 오류 메시지 표시 |
|
|
245
|
+
| Functional | 형식 오류(이메일/숫자/날짜) → 인라인 검증 메시지 |
|
|
246
|
+
| Functional | 저장 중 네트워크 오류 → 재시도 안내 + 사용자 입력 보존 |
|
|
247
|
+
| Frontend | Update시 모달창이나 수정 페이지로 데이터가 제대로 전달 되는가? (prefill 확인) |
|
|
248
|
+
| Frontend | CRUD 관련 작업 시 변경된 사항이 보이는 페이지에 바로바로 반영되는가?(목록 refresh) |
|
|
249
|
+
| Frontend | CRUD 작업 시 permission 관련 조치는 되어있는가? (UI 버튼 노출 + 서버 검증 양쪽) |
|
|
250
|
+
| Publishing | 버튼간, 요소간 패딩 정책이 잘 적용되어 있는가? (저장/취소 버튼 간격) |
|
|
251
|
+
|
|
252
|
+
### 4.3.4 [영역] 삭제
|
|
253
|
+
**Trigger**: spec.ui/logic에 삭제 액션/휴지통/소프트 삭제 언급.
|
|
254
|
+
|
|
255
|
+
| 카테고리 | TC 후보 |
|
|
256
|
+
|---|---|
|
|
257
|
+
| Functional | 삭제 클릭 → 확인 다이얼로그 표시 |
|
|
258
|
+
| Functional | 확인 → 삭제 후 목록에서 제거 + 토스트 |
|
|
259
|
+
| Functional | 취소 → 변경 없음 |
|
|
260
|
+
| Frontend | CRUD 관련 작업 시 변경된 사항이 보이는 페이지에 바로바로 반영되는가?(목록 refresh) |
|
|
261
|
+
| Backend | 테이블별 RLS 설정이 제대로 되어있는가? — 본인 소유만 삭제 가능 |
|
|
262
|
+
|
|
263
|
+
### 4.3.5 [영역] 상태 전이 (Workflow)
|
|
264
|
+
**Trigger**: spec.logic에 상태 머신(예: 대기 → 진행 → 완료), 승인 플로우 언급.
|
|
265
|
+
|
|
266
|
+
| 카테고리 | TC 후보 |
|
|
267
|
+
|---|---|
|
|
268
|
+
| Functional | 허용 전이 → 상태 변경 성공 |
|
|
269
|
+
| Functional | 비허용 전이 → 차단 + 안내 |
|
|
270
|
+
| Functional | 전이 이력 기록 (감사 로그) |
|
|
271
|
+
| Backend | 전이 권한이 서버에서도 검증되는가? (클라이언트 우회 방지) |
|
|
272
|
+
|
|
273
|
+
### 4.3.6 [영역] 화면(UI) 일반 — 모든 화면 spec에 공통 적용
|
|
274
|
+
**Trigger**: spec.ui가 정의된 모든 화면 명세.
|
|
275
|
+
|
|
276
|
+
| 카테고리 | TC 후보 |
|
|
277
|
+
|---|---|
|
|
278
|
+
| Publishing | 정확한 아이콘을 사용하고 있는가? |
|
|
279
|
+
| Publishing | 정확한 이미지를 사용하고 있는가? |
|
|
280
|
+
| Publishing | 아이콘 및 이미지의 해상도는 적절하게 설정되어 있는가? |
|
|
281
|
+
| Publishing | Design system과 UI component들이 빠짐없이 구현되어 있는가? |
|
|
282
|
+
| Publishing | 실제로 구현된 화면들이 Design system을 준수하고 있는가? |
|
|
283
|
+
| Publishing | 실제로 구현된 화면들이 UI component를 적극적으로 활용하고 있는가? |
|
|
284
|
+
| Publishing | 화면 크기가 변하는 환경에서도 반응형으로 레이아웃이 잘 구성되어 있는가? |
|
|
285
|
+
| Publishing | 화면 상하좌우 패딩이 Design system의 규정을 준수하고 있는가? |
|
|
286
|
+
| Publishing | 버튼간, 요소간 패딩 정책이 잘 적용되어 있는가? |
|
|
287
|
+
| Frontend | 화면간 네비게이팅이 적절하게 연결되어 있는가? |
|
|
288
|
+
| Frontend | (모바일의 경우) 키보드가 올라왔을때 콘텐츠들이 가려져서 사용하지 못하게 되는 경우가 있는가? |
|
|
289
|
+
|
|
290
|
+
> 화면 spec이라면 §4.3.6에서 해당되는 항목을 1차로 깔고, 그 위에 영역별(4.3.1~4.3.5) 번들을 얹는다.
|
|
291
|
+
|
|
292
|
+
### 4.3.7 [영역] 백엔드 / 데이터 접근
|
|
293
|
+
**Trigger**: spec에 dbTableRefs 또는 API/저장소 동작 정의.
|
|
294
|
+
|
|
295
|
+
| 카테고리 | TC 후보 |
|
|
296
|
+
|---|---|
|
|
297
|
+
| Backend | 테이블별 RLS 설정이 제대로 되어있는가? (Firestore: rules) |
|
|
298
|
+
| Backend | Storage에도 RLS 설정이 되어 있는가? (Firestore: Storage Rules) |
|
|
299
|
+
| Backend | 기본적인 CRUD작업을 프론트에서 하도록 되어있는가?(서버에서 처리하게 되면 RLS가 의미 없어짐) |
|
|
300
|
+
| Backend | 본인의 데이터만 제대로 필터링해서 쿼리하고 있는가?(다른 유저에 종속된 데이터 혹은 보여서는 안되는 데이터 조회시도) — 서버 사이드 |
|
|
301
|
+
|
|
302
|
+
### 4.3.8 [영역] 비즈니스 규칙
|
|
303
|
+
**Trigger**: spec.logic.businessRules에 도메인 규칙이 정의되어 있을 때.
|
|
304
|
+
|
|
305
|
+
| 카테고리 | TC 후보 |
|
|
306
|
+
|---|---|
|
|
307
|
+
| Functional | 각 규칙의 **정상 경로** 1개 — 예: "5회 미만 실패 → 로그인 가능" |
|
|
308
|
+
| Functional | 각 규칙의 **비정상/경계 경로** 1개 — 예: "5회째 실패 → 잠금" |
|
|
309
|
+
| Functional | 규칙 충돌/우선순위 — 둘 이상 규칙이 동시에 충족될 때 의도된 결과 |
|
|
310
|
+
|
|
311
|
+
### 4.3.9 [영역] 내보내기 / 보고서
|
|
312
|
+
**Trigger**: spec.logic에 엑셀/PDF/CSV export 또는 인쇄 기능.
|
|
313
|
+
|
|
314
|
+
| 카테고리 | TC 후보 |
|
|
315
|
+
|---|---|
|
|
316
|
+
| Functional | 내보내기 클릭 → 파일 다운로드 완료 |
|
|
317
|
+
| Functional | 파일 내용이 화면 표시 데이터와 일치 |
|
|
318
|
+
| Functional | 권한 없는 사용자 → 내보내기 버튼 비활성/차단 |
|
|
319
|
+
|
|
320
|
+
### 4.3.10 [영역] 차트 / 시각화
|
|
321
|
+
**Trigger**: spec.ui에 그래프/차트/대시보드 KPI 카드 언급.
|
|
322
|
+
|
|
323
|
+
| 카테고리 | TC 후보 |
|
|
324
|
+
|---|---|
|
|
325
|
+
| Functional | 데이터 정상 시 차트 렌더링 |
|
|
326
|
+
| Functional | 데이터 0건 시 "데이터 없음" 안내 |
|
|
327
|
+
| Functional | 집계 결과가 원본 합과 일치 |
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
> **라이브러리 확장 규칙**: 새 명세 작업하다가 위 번들에 없는 패턴이 반복적으로 등장하면 → 그 영역의 번들에 항목 추가하거나 새 영역 §4.3.N 신설. 한 번 적은 항목은 다음 명세에서 그대로 재사용 가능해야 한다.
|
|
332
|
+
|
|
333
|
+
## 4.4 TC 작성 규칙
|
|
334
|
+
|
|
335
|
+
### 항목 문장
|
|
336
|
+
한 문장으로, 주어 없이, **동작 + 결과** 형태.
|
|
337
|
+
|
|
338
|
+
```
|
|
339
|
+
좋은 예: "필수 필드 빈값으로 저장 클릭 시 오류 메시지 표시"
|
|
340
|
+
좋은 예: "비허용 역할로 접근 시 403 또는 리다이렉트"
|
|
341
|
+
나쁜 예: "지점 관리 테스트" (너무 모호)
|
|
342
|
+
나쁜 예: "로그인 확인"
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
### relatedSpec
|
|
346
|
+
- A축(§4.3 영역별 번들에서 도출한 모든 항목): 반드시 해당 명세의 specId 명시
|
|
347
|
+
- B축(비기능 4축 표준 40개): 비워두거나 "common"/"standard" 가상 specId 사용 — 프로젝트 정책 결정 후 일관 적용
|
|
348
|
+
|
|
349
|
+
### Windows CRLF 주의
|
|
350
|
+
파일 기반 입력 시 `\r`이 specId 끝에 붙어 연결이 깨진다. heredoc 권장, 부득이 파일이면 `tr -d '\r'`로 정제.
|
|
351
|
+
|
|
352
|
+
## 4.5 스펙 커버리지 검증
|
|
353
|
+
|
|
354
|
+
항목 등록 후 반드시 실행 — A축에서 누락된 spec이 없는지 확인. 통과 못 하면 `start-run` 금지.
|
|
355
|
+
|
|
356
|
+
```bash
|
|
357
|
+
ch specs list --json --per-page 100 | node -e "
|
|
358
|
+
const specs = JSON.parse(require('fs').readFileSync(0,'utf8')).data.map(s=>s.id);
|
|
359
|
+
const sheet = JSON.parse(require('child_process').execSync('ch sqa get <sheetId> --json'));
|
|
360
|
+
const linked = [...new Set((sheet.data||sheet).items.map(i=>i.relatedSpec).filter(Boolean))];
|
|
361
|
+
const missing = specs.filter(id => !linked.includes(id));
|
|
362
|
+
if (missing.length) { console.error('누락된 스펙:', missing.length, missing); process.exit(1); }
|
|
363
|
+
else console.log('OK:', specs.length, '개 스펙 커버 완료');
|
|
364
|
+
"
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
누락된 spec이 있으면 해당 spec의 content를 다시 읽고 TC를 추가한 후 재검증.
|
|
368
|
+
|
|
369
|
+
## 5. spec 완료 점검 절차
|
|
370
|
+
|
|
371
|
+
```bash
|
|
372
|
+
# 1) spec에 연결된 SQA 항목 조회 → 해당 spec의 항목이 든 시트의 Run summary 확인
|
|
373
|
+
ch sqa summary <runId>
|
|
374
|
+
# 2) 모두 "통과(Pass)" 상태인지 확인
|
|
375
|
+
# 3) 통과 → spec.status 를 "완료"로 갱신
|
|
376
|
+
ch specs update <specId> --status 완료 --no-version
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
수동으로 status를 바꾸기 전에 SQA 통과 여부를 반드시 확인.
|
|
380
|
+
|
|
381
|
+
## 6. workStatus와의 분담
|
|
382
|
+
|
|
383
|
+
- **spec.workStatus**: 개발자의 진행 메모, 블로커, 의사결정 로그.
|
|
384
|
+
- **SQA 항목.note**: QA의 검증 결과/재현 단계.
|
|
385
|
+
- 둘은 분리 유지. workStatus에 SQA 결과를 복붙하지 말 것.
|
|
386
|
+
|
|
387
|
+
## 7. 결함 보고 규칙 (Run의 항목 note)
|
|
388
|
+
|
|
389
|
+
`check --result no --note ...` 시 note에 다음을 포함.
|
|
390
|
+
|
|
391
|
+
```
|
|
392
|
+
[심각도] Critical / Major / Minor
|
|
393
|
+
[현상] 실제 발생한 문제
|
|
394
|
+
[기대] 기대했던 결과
|
|
395
|
+
[재현] 재현 절차
|
|
396
|
+
[환경] 브라우저/해상도/계정
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
## 8. 시트 작성 완료 자가 점검 체크리스트
|
|
400
|
+
|
|
401
|
+
- [ ] A축: 모든 spec에 최소 3개 이상 TC가 있는가? (§4.5 커버리지 통과)
|
|
402
|
+
- [ ] A축 항목 작성 시 §4.3 영역별 번들(Functional/Publishing/Frontend/Backend)을 명세 성격에 맞게 적용했는가?
|
|
403
|
+
- [ ] B축: 보안 12 / 성능 10 / 접근성 10 / 호환성 8 — 40개 모두 포함?
|
|
404
|
+
- [ ] High 우선순위 TC가 60% 이상인가?
|
|
405
|
+
- [ ] 정상 경로 + 비정상 경로(에러) 모두 커버?
|
|
406
|
+
- [ ] 빈 상태(데이터 없음) 테스트 포함?
|
|
407
|
+
- [ ] TC 항목이 "동작+결과" 한 문장인가? (§4.3 번들의 추상 문구도 명세별 구체 시나리오로 변환됐는가?)
|
|
408
|
+
- [ ] specId에 CRLF `\r` 미포함? (파일 입력 시 필수)
|
|
409
|
+
- [ ] `start-run` 후 스펙 페이지 "관련 SQA" 탭 연결 표시 확인?
|
|
410
|
+
- [ ] 이번 명세 작업 중 §4.3 번들에 없는 반복 패턴을 발견했다면, 번들에 추가했는가? (라이브러리 확장)
|
|
411
|
+
|
|
412
|
+
## 9. 흔한 함정
|
|
413
|
+
|
|
414
|
+
- spec.tasks를 전부 done 처리해도 SQA 통과 안 됐으면 spec.status는 완료로 바꾸지 않음.
|
|
415
|
+
- **명세별 E2E만 넣고 끝내지 말 것** — §4.3 번들에서 Publishing/Frontend/Backend 카테고리 누락, §4.2 비기능 4축 미등록이 가장 흔한 실수.
|
|
416
|
+
- §4.3 번들을 **별도 시트 묶음으로 등록**하지 말 것 — 각 명세의 A축 항목으로 풀어 써야 한다. 추상 문구 그대로 박아넣지 말 것.
|
|
417
|
+
- 항목 단위 CRUD(§3.5)는 **시트 템플릿**만 변경 — 진행 중 Run에는 반영 안 됨. Run 항목 결과는 `check`/`check-bulk`로.
|
|
418
|
+
- `update-item`/`delete-item`/`reorder-items`는 `itemId` 키 기반 → 반드시 `ch sqa get --json`으로 최신 id 확보 후 실행(stale id 주의).
|
|
419
|
+
- `reorder-items`의 `--order`는 현재 모든 항목 id를 빠짐없이·중복없이 나열해야 함. 일부만 주면 400.
|
|
420
|
+
- `ch sqa create`는 서버 DTO상 `performDate`가 필수 — CLI에서 `--date` 생략하면 오늘 날짜로 자동 채워지지만, 명시적 날짜가 필요하면 `--date YYYY-MM-DD` 지정.
|
|
421
|
+
- 신규 프로젝트에 SQA 시트가 없는 상태에서 spec을 완료 처리하면 추적 불가 — 신규 프로젝트는 SQA 시트 초기 생성 권장.
|
|
422
|
+
- B축(비기능 표준) 항목의 `relatedSpec`을 명세별 spec과 섞어 넣으면 §4.5 커버리지 검증이 잘못 통과될 수 있음 — B축은 빈 값 또는 "common"으로 일관.
|