spec-lite 1.2.2 → 1.3.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/package.json +1 -1
- package/skills/spec-brownfield-feature/SKILL.md +4 -0
- package/skills/spec-test/SKILL.md +365 -0
- package/skills/spec-tsd/SKILL.md +230 -0
- package/skills-overview.md +72 -15
- package/templates/integrations/test-template.md +166 -0
- package/templates/main/feature/frd-template.md +22 -7
- package/templates/main/feature/tsd-template.md +220 -0
- package/templates/main/feature/test-plan-template.md +0 -60
package/package.json
CHANGED
|
@@ -266,6 +266,10 @@ Brownfield init hoàn tất! Main artifacts:
|
|
|
266
266
|
├── component/ ({N} components, mỗi cái có crd.md + cdd.md)
|
|
267
267
|
└── feature/ ({N} features, mỗi cái có frd.md + fdd.md)
|
|
268
268
|
|
|
269
|
+
Bước tiếp theo (tùy chọn):
|
|
270
|
+
/spec-tsd [F-XXX] → bootstrap tsd.md (Test Spec Document) cho từng feature
|
|
271
|
+
— derive 1:1 từ frd.md, có test coverage tracking từ ngày 1.
|
|
272
|
+
|
|
269
273
|
Để bắt đầu implement, dùng /spec-new để tạo integration đầu tiên.
|
|
270
274
|
grep "NEEDS_CLARIFY" để tìm và fill in khi có thêm context.
|
|
271
275
|
```
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-test
|
|
3
|
+
description: Tạo test.md cho một integration bằng cách mechanical derive Test Scenarios + Test Cases từ Flows/US/AC/VR/FAC trong frd.md. Auto-cascade lên feature/{F-XXX}/tsd.md. Role QC, song song với /spec-tech (DEV) — cả hai chỉ phụ thuộc spec.md approved.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# spec-test
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Tạo `test.md` cho một integration trong `specs/integrations/{slug}/`.
|
|
11
|
+
|
|
12
|
+
`test.md` là verification design ở integration level — định nghĩa **how to verify** rằng integration đáp ứng `spec.md`. Nội dung gồm Test Strategy (per integration) + Changes blocks cascade lên feature `tsd.md` (Test Spec Document).
|
|
13
|
+
|
|
14
|
+
**Hai artifact tách bạch:**
|
|
15
|
+
- `specs/integrations/{slug}/test.md` — integration-level, ephemeral, PR record bất biến sau approve (single-word naming như `spec.md` / `tech.md` / `plan.md`).
|
|
16
|
+
- `specs/main/feature/{F-XXX}-{slug}/tsd.md` — feature-level, persistent canonical artifact (3-letter naming như `frd.md` / `fdd.md`). TC content cuối cùng nằm ở đây.
|
|
17
|
+
|
|
18
|
+
**Role:** QC. Song song với `/spec-tech` (DEV role). Cả hai chỉ phụ thuộc `spec.md` approved — không có thứ tự bắt buộc giữa chúng.
|
|
19
|
+
|
|
20
|
+
**Cốt lõi:** agent **mechanical derive** TC từ frd.md (mỗi Flow → TS, mỗi US/AC → Functional TC, mỗi VR → Validation TC positive+negative, mỗi FAC → Feature AC TC). Agent KHÔNG sáng tạo TC ngoài frd — phần đó là QC thêm tay khi review.
|
|
21
|
+
|
|
22
|
+
## When to Use
|
|
23
|
+
|
|
24
|
+
- `spec.md` đã được approve → bắt đầu thiết kế verification
|
|
25
|
+
- Bổ sung `test.md` cho integration đã có spec.md/tech.md nhưng chưa có test.md
|
|
26
|
+
|
|
27
|
+
## When NOT to Use
|
|
28
|
+
|
|
29
|
+
- `spec.md` chưa có hoặc chưa approve → chạy `/spec-new` trước
|
|
30
|
+
- Integration có `features: []` (không touch feature nào) → `test.md` không áp dụng vì component-level `tsd.md` không tồn tại trong kit này (xem `templates/main/feature/tsd-template.md` — component contract verify gián tiếp qua feature TC + unit test trong code). Verification cho integration thuần component → đặt trong tech.md hoặc phase Verification của plan.md.
|
|
31
|
+
- Chỉ muốn cập nhật `test.md` đã có → edit file trực tiếp
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## Process
|
|
36
|
+
|
|
37
|
+
### Bước 1: Xác định integration
|
|
38
|
+
|
|
39
|
+
**Nếu có ARGUMENT:**
|
|
40
|
+
- Parse argument: có thể là số thứ tự (`2`, `002`) hoặc slug (`002-implement-todo`)
|
|
41
|
+
- Quét `specs/integrations/*/spec.md`, tìm integration khớp với argument
|
|
42
|
+
- Nếu không tìm thấy → báo lỗi:
|
|
43
|
+
> Không tìm thấy integration khớp với "{argument}". Kiểm tra lại tên hoặc số thứ tự.
|
|
44
|
+
- Nếu tìm thấy → dùng integration đó, bắt đầu luôn
|
|
45
|
+
|
|
46
|
+
**Nếu không có ARGUMENT:**
|
|
47
|
+
|
|
48
|
+
Quét `specs/integrations/`. Liệt kê **tất cả** integrations có `spec.md`, đánh dấu những cái đã có `test.md`:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Integrations:
|
|
52
|
+
|
|
53
|
+
[1] 001-implement-auth — Implement Auth spec✓ test✓
|
|
54
|
+
[2] 002-implement-todo — Implement Todo Management spec✓ test—
|
|
55
|
+
|
|
56
|
+
Chọn số integration:
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Nếu không có integration nào → thông báo:
|
|
60
|
+
> Chưa có integration nào. Hãy chạy `/spec-new` trước.
|
|
61
|
+
|
|
62
|
+
Nếu integration đã có `test.md` → hỏi trước khi tiếp tục:
|
|
63
|
+
> `test.md` đã tồn tại cho integration này. Tiếp tục sẽ ghi đè. Tiếp tục không?
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
### Bước 1b: Gate check
|
|
68
|
+
|
|
69
|
+
Đọc frontmatter của `specs/integrations/{slug}/spec.md`.
|
|
70
|
+
|
|
71
|
+
**Check 1 — spec.md phải approved:**
|
|
72
|
+
|
|
73
|
+
Nếu `status` **không phải** `approved`:
|
|
74
|
+
|
|
75
|
+
> ⛔ `spec.md` của integration **{slug}** chưa được approve (status hiện tại: `{status}`).
|
|
76
|
+
>
|
|
77
|
+
> `/spec-test` cần spec.md approved vì cascade frd.md (nguồn của TC) chỉ apply sau khi approve.
|
|
78
|
+
>
|
|
79
|
+
> Để tiếp tục:
|
|
80
|
+
> 1. Review `specs/integrations/{slug}/spec.md`
|
|
81
|
+
> 2. Approve (đổi `status: draft` → `status: approved`)
|
|
82
|
+
>
|
|
83
|
+
> Sau đó chạy lại `/spec-test`.
|
|
84
|
+
|
|
85
|
+
**Dừng hoàn toàn.**
|
|
86
|
+
|
|
87
|
+
**Check 2 — features non-empty:**
|
|
88
|
+
|
|
89
|
+
Đọc `features:` trong frontmatter. Nếu `[]`:
|
|
90
|
+
|
|
91
|
+
> ⛔ Integration **{slug}** không touch feature nào (`features: []`).
|
|
92
|
+
>
|
|
93
|
+
> `/spec-test` cascade lên `feature/{F-XXX}/tsd.md` — không áp dụng cho integration thuần component.
|
|
94
|
+
> Component contract được verify gián tiếp qua feature TC + unit test trong code (xem `templates/main/feature/tsd-template.md`).
|
|
95
|
+
>
|
|
96
|
+
> Đặt verification cho integration này trong:
|
|
97
|
+
> - `tech.md > Implementation Notes` — verification approach
|
|
98
|
+
> - `plan.md > Verification phase` — test tasks cụ thể
|
|
99
|
+
>
|
|
100
|
+
> Không có gì để làm với `/spec-test`. Dừng.
|
|
101
|
+
|
|
102
|
+
Nếu cả 2 check pass → tiếp tục Bước 2.
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
### Bước 2: Load context
|
|
107
|
+
|
|
108
|
+
Load các file sau:
|
|
109
|
+
|
|
110
|
+
- `specs/integrations/{slug}/spec.md` — đọc toàn bộ + frontmatter (`features`)
|
|
111
|
+
- `specs/main/feature/{F-XXX}-{slug}/frd.md` — cho mỗi feature trong frontmatter `features` (source của TC — bắt buộc tồn tại vì cascade từ spec.md đã apply)
|
|
112
|
+
- `specs/main/feature/{F-XXX}-{slug}/tsd.md` — cho mỗi feature trong frontmatter `features` (nếu tồn tại — cần để diff và assign next ID)
|
|
113
|
+
- `specs/integrations/{slug}/tech.md` — đọc nếu tồn tại (optional, dùng để hint environment / data set / NFR perf threshold)
|
|
114
|
+
|
|
115
|
+
Tóm tắt context:
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
TÔI HIỂU:
|
|
119
|
+
- Integration: {title}
|
|
120
|
+
- Features touched: {từ frontmatter — F-XXX, ...}
|
|
121
|
+
- Mỗi feature có trong frd.md:
|
|
122
|
+
- F-XXX: {N} Flows, {M} US ({K} AC), {P} VR, {Q} FAC
|
|
123
|
+
- tsd.md hiện tại:
|
|
124
|
+
- F-XXX: tồn tại — max(TS)=NNN, max(TC)=MMM (cho operation=update)
|
|
125
|
+
- F-YYY: chưa tồn tại (cho operation=create)
|
|
126
|
+
- tech.md: {tồn tại / chưa — nếu có thì có hint gì cho env/data/perf}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Nếu frd.md của feature nào không tồn tại → báo lỗi và dừng (lỗi cascade từ spec.md trước đó):
|
|
130
|
+
> ⛔ `specs/main/feature/{F-XXX}-{slug}/frd.md` không tồn tại nhưng feature có trong `features:` của spec.md. Cascade từ spec.md có thể đã fail. Kiểm tra lại.
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### Bước 3: Auto-derive draft
|
|
135
|
+
|
|
136
|
+
**Nguyên tắc:** agent derive **1:1 mechanically** từ frd.md. KHÔNG sáng tạo TC ngoài frd. Phần creative (extra edge cases, exploratory testing) thuộc về QC khi review.
|
|
137
|
+
|
|
138
|
+
#### 3.1 ID assignment
|
|
139
|
+
|
|
140
|
+
Với mỗi feature trong `features:`:
|
|
141
|
+
|
|
142
|
+
- Đọc `feature/{F-XXX}/tsd.md` hiện tại (nếu có) để lấy `max(TS-F{NNN}-seq)` và `max(TC-F{NNN}-seq)`
|
|
143
|
+
- ID mới = `max(seq) + 1`, format 3 chữ số
|
|
144
|
+
- TC dùng **chung sequence** cho Functional / Validation / Feature AC — không reset theo loại
|
|
145
|
+
- ID **stable** — không tái sử dụng khi [REMOVE], không renumber khi [MODIFY]
|
|
146
|
+
- Operation=create (tsd.md chưa tồn tại) → bắt đầu từ `001`
|
|
147
|
+
|
|
148
|
+
#### 3.2 Derivation rules
|
|
149
|
+
|
|
150
|
+
Áp dụng cho mỗi feature, sinh ra Changes block tương ứng:
|
|
151
|
+
|
|
152
|
+
**A. Test Scenarios** — mỗi Flow trong `frd.md > User Flows` → 1 Test Scenario.
|
|
153
|
+
|
|
154
|
+
- TS ID mới = `TS-F{NNN}-{next_seq}`
|
|
155
|
+
- Flow ref: `frd.md > Flow {N}: {name}`
|
|
156
|
+
- Preconditions: derive từ điểm bắt đầu của Mermaid flow
|
|
157
|
+
- Postconditions: derive từ điểm kết thúc happy
|
|
158
|
+
- Paths: liệt kê happy + mỗi edge case trong Mermaid
|
|
159
|
+
- Test cases: list các TC ID sẽ cover TS này (cross-reference TC sinh ở bước B/D)
|
|
160
|
+
|
|
161
|
+
**B. Functional Test Cases** — mỗi AC trong mỗi US → 1 Functional TC.
|
|
162
|
+
|
|
163
|
+
- TC ID mới = `TC-F{NNN}-{next_seq}`
|
|
164
|
+
- Type: `Functional — positive` (mặc định cho AC happy), `Functional — negative` nếu AC mô tả nhánh fail
|
|
165
|
+
- Priority: derive từ US Priority (xem 3.3)
|
|
166
|
+
- Covers: `US-{F_ID}-{seq}`, `AC-{F_ID}-{seq}`
|
|
167
|
+
- Scenario: TS ID của Flow tương ứng (nếu AC nằm trong flow)
|
|
168
|
+
- Preconditions/Steps/Expected: dịch 1:1 từ Given/When/Then của AC
|
|
169
|
+
|
|
170
|
+
**C. Validation Test Cases** — mỗi VR → tối thiểu 2 TC.
|
|
171
|
+
|
|
172
|
+
- 1 positive: input hợp lệ → accept
|
|
173
|
+
- 1+ negative: mỗi nhánh fail là 1 TC riêng (vd VR "email format" → 1 case missing `@`, 1 case missing domain, 1 case có space). Agent infer các nhánh fail từ rule text.
|
|
174
|
+
- TC ID mới = `TC-F{NNN}-{next_seq}` (chung sequence với Functional)
|
|
175
|
+
- Form bảng theo template gốc
|
|
176
|
+
- Covers: `VR-{F_ID}-{seq}`
|
|
177
|
+
- Priority: P1 mặc định (xem 3.3)
|
|
178
|
+
|
|
179
|
+
**D. Feature AC Test Cases** — mỗi FAC → 1 Feature AC TC.
|
|
180
|
+
|
|
181
|
+
- TC ID mới = `TC-F{NNN}-{next_seq}`
|
|
182
|
+
- Type: derive từ nhóm FAC (`e2e` / `consistency` / `NFR` / `data & migration`) — đọc context FAC để phân loại
|
|
183
|
+
- Priority: theo bảng ở 3.3
|
|
184
|
+
- Covers: `FAC-{F_ID}-{seq}`
|
|
185
|
+
- Spans: list US IDs mà FAC liên quan (nếu FAC e2e)
|
|
186
|
+
- Preconditions/Steps/Expected: dịch 1:1 từ Given/When/Then của FAC
|
|
187
|
+
|
|
188
|
+
**E. Traceability Matrix** — row per frd item:
|
|
189
|
+
|
|
190
|
+
- 1 row per Flow → cover by TS
|
|
191
|
+
- 1 row per US → cover by TC (Functional)
|
|
192
|
+
- 1 row per Story AC → cover by TC (Functional)
|
|
193
|
+
- 1 row per VR → cover by TC (Validation, list tất cả positive + negative)
|
|
194
|
+
- 1 row per FAC → cover by TC (Feature AC)
|
|
195
|
+
- Mọi item phải có cover ✅ (vì derive 1:1). Nếu agent không thể derive một item nào → đánh dấu ❌ + ghi lý do ở Gaps section, KHÔNG silent skip.
|
|
196
|
+
|
|
197
|
+
#### 3.3 Priority defaults
|
|
198
|
+
|
|
199
|
+
Mọi TC đều có priority deterministic. QC override khi review (Bước 4).
|
|
200
|
+
|
|
201
|
+
**TC cover US/AC** — inherit từ US Priority:
|
|
202
|
+
|
|
203
|
+
| US Priority (frd) | TC Priority |
|
|
204
|
+
| --- | --- |
|
|
205
|
+
| Must | P0 |
|
|
206
|
+
| Should | P1 |
|
|
207
|
+
| Could | P2 |
|
|
208
|
+
|
|
209
|
+
**TC cover VR** — inherit max priority của các US trong `Refs` column của VR. Nếu Refs trống → P1 default.
|
|
210
|
+
|
|
211
|
+
**TC cover FAC** — theo nhóm FAC:
|
|
212
|
+
|
|
213
|
+
| FAC group | TC Priority |
|
|
214
|
+
| --- | --- |
|
|
215
|
+
| End-to-end liên story | P0 |
|
|
216
|
+
| Cross-story consistency | P1 |
|
|
217
|
+
| NFR — security / data integrity | P0 |
|
|
218
|
+
| NFR — performance / a11y / i18n / browser | P1 |
|
|
219
|
+
| Data & migration | P0 |
|
|
220
|
+
|
|
221
|
+
#### 3.4 Diff vs current tsd.md
|
|
222
|
+
|
|
223
|
+
Với feature có tsd.md hiện tại (operation=update):
|
|
224
|
+
|
|
225
|
+
- Item đã có TC cover → KHÔNG sinh TC mới, giữ nguyên TC cũ
|
|
226
|
+
- Item trong frd nhưng chưa có TC cover → sinh TC mới với marker `[NEW]`
|
|
227
|
+
- TC hiện tại cover item đã bị xóa khỏi frd (orphan) → đánh dấu `[REMOVE]` + ghi lý do (vd: "AC-F001-005 không còn trong frd")
|
|
228
|
+
- Item trong frd đã đổi nội dung mà TC cũ không còn match (vd AC đổi expected outcome) → đánh dấu TC cũ là `[MODIFY {field}]` với field cụ thể
|
|
229
|
+
|
|
230
|
+
Agent compute diff tự động — KHÔNG hỏi user "field nào đã đổi"; đọc 2 file rồi đối chiếu.
|
|
231
|
+
|
|
232
|
+
**No-delta case:** nếu diff giữa frd hiện tại và tsd.md hiện tại = empty cho 1 feature (frd không thêm/đổi item nào mà tsd chưa cover) → **bỏ Changes block của feature đó hoàn toàn**, ghi `no-op` trong Cascade Summary để minh bạch.
|
|
233
|
+
|
|
234
|
+
#### 3.5 Placeholders cần QC fill
|
|
235
|
+
|
|
236
|
+
Agent **không suy đoán** các field sau, dùng placeholder rõ ràng để QC điền ở Bước 4:
|
|
237
|
+
|
|
238
|
+
| Field | Placeholder | Vì sao agent không tự fill |
|
|
239
|
+
| --- | --- | --- |
|
|
240
|
+
| Environments table | Row mặc định: `dev / staging / prod-like` với `data set: TBD`, `mục đích: TBD` | Phụ thuộc setup CI/CD và availability — QC owns |
|
|
241
|
+
| Test Data table | Row `{TBD — fixture}` cho mỗi seed/boundary dataset agent thấy cần | QC chọn fixture source thực tế |
|
|
242
|
+
| Out of Scope | Để trống với note `<!-- QC fill -->` | Quyết định business của QC |
|
|
243
|
+
| Test Strategy > Approach | Bullet generic theo template gốc | Strategy đặc thù integration QC fill |
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
### Bước 4: Write — sinh draft
|
|
248
|
+
|
|
249
|
+
Tổng hợp và viết draft `test.md` theo `templates/integrations/test-template.md`:
|
|
250
|
+
|
|
251
|
+
- **Context** — tóm tắt từ Bước 2
|
|
252
|
+
- **Test Strategy** — placeholder + Environments table với placeholder rows
|
|
253
|
+
- **Changes** — 1 block per feature *có delta*, mỗi block có operation + content theo template gốc `templates/main/feature/tsd-template.md`. Feature no-delta → bỏ block.
|
|
254
|
+
- **Out of Scope** — empty với note QC fill
|
|
255
|
+
- **Open Questions** — list các item mà agent không thể derive deterministic (vd: FAC có wording vague, VR không rõ nhánh fail nào)
|
|
256
|
+
- **Cascade Summary** — table liệt kê **tất cả** feature trong `features:` (kể cả no-delta — ghi `no-op`)
|
|
257
|
+
|
|
258
|
+
Hiển thị **toàn bộ draft** cho QC xem — **chưa ghi file, chưa cascade**.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
262
|
+
### Bước 5: Review — xác nhận với user
|
|
263
|
+
|
|
264
|
+
> Draft trên đã đúng chưa? QC điểm cần check:
|
|
265
|
+
>
|
|
266
|
+
> 1. **Mechanical derivation** — mỗi Flow / US / AC / VR / FAC trong frd đã có TC cover chưa? (xem Traceability Matrix)
|
|
267
|
+
> 2. **Priority defaults** — có TC nào cần override khỏi default không?
|
|
268
|
+
> 3. **Placeholders** — fill Environments / Test Data / Out of Scope / Strategy Approach.
|
|
269
|
+
> 4. **Extra edge cases** — ngoài AC/VR có scenario nào QC muốn thêm? (vd: exploratory, security boundary, race condition không có trong AC)
|
|
270
|
+
> 5. **Changes markers** — `[NEW]/[MODIFY]/[REMOVE]` có đúng không?
|
|
271
|
+
> 6. **No-delta features** — Cascade Summary có ghi `no-op` đúng cho feature không có delta không?
|
|
272
|
+
>
|
|
273
|
+
> **Sau khi confirm, agent sẽ auto-apply tất cả Changes blocks lên feature tsd.md(s).**
|
|
274
|
+
|
|
275
|
+
Nếu QC yêu cầu chỉnh sửa:
|
|
276
|
+
- Override priority → update draft
|
|
277
|
+
- Add extra TC → assign next ID, mark `[NEW]`
|
|
278
|
+
- Fill placeholder → update draft
|
|
279
|
+
- Remove TC khỏi draft → bỏ block hoặc đổi marker
|
|
280
|
+
|
|
281
|
+
Chỉ tiến hành Bước 6 sau khi QC confirm.
|
|
282
|
+
|
|
283
|
+
---
|
|
284
|
+
|
|
285
|
+
### Bước 6: Save + Auto-cascade
|
|
286
|
+
|
|
287
|
+
**[6.1] Ghi `specs/integrations/{slug}/test.md`** với status `approved` (không phải `draft` — human đã confirm ở Bước 5 chính là approval). Frontmatter `features` mirror từ `spec.md`.
|
|
288
|
+
|
|
289
|
+
**[6.2] Auto-apply mỗi Changes block** vào `feature/{F-XXX}/tsd.md` tương ứng. Thứ tự apply: theo thứ tự xuất hiện trong frontmatter `features` (deterministic, không có forward reference giữa các feature tsd.md). Bỏ qua feature có operation `no-op` trong Cascade Summary.
|
|
290
|
+
|
|
291
|
+
Cho từng block:
|
|
292
|
+
|
|
293
|
+
- **Operation=create:**
|
|
294
|
+
- Tạo file `specs/main/feature/{F-XXX}-{slug}/tsd.md`
|
|
295
|
+
- Nội dung = nội dung của Changes block (theo format `templates/main/feature/tsd-template.md`)
|
|
296
|
+
- Frontmatter của tsd.md mới: status `draft` (separate lifecycle với integration test.md)
|
|
297
|
+
|
|
298
|
+
- **Operation=update:**
|
|
299
|
+
- Đọc tsd.md hiện tại
|
|
300
|
+
- Với mỗi TS/TC trong Changes block:
|
|
301
|
+
- `[NEW]` → append/insert vào section tương ứng (giữ thứ tự numeric của ID)
|
|
302
|
+
- `[MODIFY {field}]` → tìm TS/TC bằng ID, update field đã chỉ định, giữ nguyên field khác
|
|
303
|
+
- `[REMOVE]` → xóa TS/TC khỏi tsd.md (ID retire, không tái sử dụng)
|
|
304
|
+
- Cập nhật Traceability Matrix: thêm row cho item mới, update row của item bị MODIFY, KHÔNG xóa row của REMOVE (đánh dấu retire)
|
|
305
|
+
- Ghi lại tsd.md
|
|
306
|
+
|
|
307
|
+
**[6.3] Atomic rollback:** Nếu apply block nào fail (vd `[MODIFY TC-F001-005]` nhưng ID không tồn tại):
|
|
308
|
+
1. Rollback các block đã apply trước đó về state ban đầu
|
|
309
|
+
2. **Không** ghi integration test.md
|
|
310
|
+
3. Báo lỗi cụ thể cho QC fix draft hoặc feature tsd.md hiện tại
|
|
311
|
+
|
|
312
|
+
**[6.4] Thông báo kết quả:**
|
|
313
|
+
|
|
314
|
+
```
|
|
315
|
+
✓ specs/integrations/{slug}/test.md đã được tạo (status: approved)
|
|
316
|
+
|
|
317
|
+
Auto-cascade applied:
|
|
318
|
+
✓ feature/F-XXX-{slug}/tsd.md — {created | updated: +N TS, +M TC, modify K TC, remove L TC}
|
|
319
|
+
✓ feature/F-YYY-{slug}/tsd.md — no-op (frd không đổi)
|
|
320
|
+
|
|
321
|
+
Bước tiếp theo:
|
|
322
|
+
- QC: review feature tsd.md đã cascade, fill remaining TBD nếu có
|
|
323
|
+
- DEV: có thể run /plan nếu chưa có plan.md (plan.md hiện chưa consume tsd.md — test tasks tự QC manage trong test framework)
|
|
324
|
+
```
|
|
325
|
+
|
|
326
|
+
---
|
|
327
|
+
|
|
328
|
+
## Common Rationalizations
|
|
329
|
+
|
|
330
|
+
| Rationalization | Reality |
|
|
331
|
+
| --- | --- |
|
|
332
|
+
| "TC có thể nghĩ ra khi chạy test" | Không document = không có traceability. AC pass/fail không kiểm tra được nếu không có TC mapping. |
|
|
333
|
+
| "VR positive đủ rồi, negative skip" | Negative case là nơi bug ẩn. Mỗi nhánh fail của VR phải có TC riêng. |
|
|
334
|
+
| "Priority để default hết P1 cho nhanh" | Priority decorative thì cũng phải đúng — derive deterministic từ US Priority/FAC group. P1 hàng loạt = QC chưa nhìn frd. |
|
|
335
|
+
| "Out of Scope để trống cũng được" | Mọi integration đều có thứ không test. Trống = scope creep hoặc gap không kiểm soát. |
|
|
336
|
+
|
|
337
|
+
## Red Flags
|
|
338
|
+
|
|
339
|
+
- Traceability Matrix có item ❌ mà không có lý do ở Gaps section → agent silent skip
|
|
340
|
+
- TC có Covers trống → không trace được lên frd
|
|
341
|
+
- VR có ít hơn 2 TC (1 positive + 1+ negative) → coverage thiếu
|
|
342
|
+
- Priority hàng loạt giống nhau cho mọi TC → QC chưa override default
|
|
343
|
+
- Test Data toàn `TBD` sau khi QC review → chưa thật sự confirm
|
|
344
|
+
- Changes block có marker `[NEW]` cho TC trùng ID với TC đã có trong tsd.md hiện tại → diff bug
|
|
345
|
+
- Cascade Summary thiếu row cho feature trong `features:` (kể cả no-op) → không minh bạch
|
|
346
|
+
|
|
347
|
+
## Verification
|
|
348
|
+
|
|
349
|
+
Trước khi QC confirm (Bước 5), kiểm tra:
|
|
350
|
+
|
|
351
|
+
- [ ] Mỗi Flow trong frd có 1 TS tương ứng
|
|
352
|
+
- [ ] Mỗi US AC có TC Functional cover
|
|
353
|
+
- [ ] Mỗi VR có ≥1 positive + ≥1 negative TC
|
|
354
|
+
- [ ] Mỗi FAC có TC Feature AC cover
|
|
355
|
+
- [ ] Traceability Matrix đầy đủ (không ❌ mà không giải thích)
|
|
356
|
+
- [ ] Priority deterministic theo bảng 3.3 (default), QC override visible
|
|
357
|
+
- [ ] ID assignment từ max(seq)+1, không tái sử dụng, không renumber
|
|
358
|
+
- [ ] Markers `[NEW]/[MODIFY {field}]/[REMOVE]` khớp diff vs current tsd.md
|
|
359
|
+
- [ ] Feature no-delta được ghi `no-op` trong Cascade Summary, KHÔNG có Changes block
|
|
360
|
+
|
|
361
|
+
Sau khi QC confirm (Bước 6):
|
|
362
|
+
|
|
363
|
+
- [ ] Auto-apply theo thứ tự features trong frontmatter
|
|
364
|
+
- [ ] Fail-safe: nếu apply fail thì không ghi integration test.md
|
|
365
|
+
- [ ] Mỗi feature tsd.md mới có status `draft` (separate lifecycle)
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: spec-tsd
|
|
3
|
+
description: Tạo tsd.md (Test Spec Document) trực tiếp tại feature level từ frd.md — mechanical derive Test Scenarios + Test Cases. KHÔNG cần integration, không cascade. Dùng cho brownfield onboarding (sau /spec-brownfield-feature) hoặc greenfield bootstrap khi feature đã có frd.md nhưng chưa có tsd.md.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# spec-tsd
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Tạo `specs/main/feature/{F-XXX}-{slug}/tsd.md` trực tiếp từ frd.md của feature đó — **không qua integration**, không cascade.
|
|
11
|
+
|
|
12
|
+
Skill này song hành với `/spec-prd` và `/spec-sad`: skill có acronym suffix (`prd`/`sad`/`tsd`) → tạo main artifact trực tiếp. Phân biệt với `/spec-test` — skill đó tạo `test.md` integration-level và cascade qua Changes blocks.
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
- **Brownfield onboarding** — sau `/spec-brownfield-feature` đã sinh frd.md, cần bootstrap tsd.md để có test coverage tracking ngay từ đầu.
|
|
17
|
+
- **Greenfield deferred** — feature có frd.md từ lâu nhưng tsd.md chưa được tạo (vd: test design bị defer).
|
|
18
|
+
- **Ad-hoc rebuild** — tsd.md drift quá xa khỏi frd.md, muốn regenerate fresh.
|
|
19
|
+
|
|
20
|
+
## When NOT to Use
|
|
21
|
+
|
|
22
|
+
- Có integration mới và muốn cascade thay đổi frd lên tsd hiện tại → dùng `/spec-test` (changeset patch giữ ID stable)
|
|
23
|
+
- Chỉ muốn sửa vài TC → edit `tsd.md` trực tiếp
|
|
24
|
+
- Feature chưa có frd.md → chạy `/spec-brownfield-feature` (brownfield) hoặc `/spec-new` (greenfield) trước
|
|
25
|
+
|
|
26
|
+
## Cảnh báo về ID stability
|
|
27
|
+
|
|
28
|
+
`/spec-tsd` **regenerate IDs từ 001** mỗi lần chạy. Nếu tsd.md đã tồn tại và đang được reference (vd: test code có `// covers TC-F001-005`), rebuild sẽ làm vỡ những reference đó.
|
|
29
|
+
|
|
30
|
+
Quy tắc:
|
|
31
|
+
- **tsd.md chưa tồn tại** → an toàn, không có reference, regenerate fresh.
|
|
32
|
+
- **tsd.md tồn tại** → skill hỏi confirm rõ ràng trước khi overwrite. Khuyến nghị: dùng `/spec-test` qua integration changeset để preserve ID stable.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Process
|
|
37
|
+
|
|
38
|
+
### Bước 1: Xác định feature
|
|
39
|
+
|
|
40
|
+
**Nếu có ARGUMENT:**
|
|
41
|
+
- Parse argument: có thể là feature ID (`F-001`, `001`) hoặc slug (`F-001-auth`, `auth`)
|
|
42
|
+
- Quét `specs/main/feature/*/frd.md`, tìm feature khớp
|
|
43
|
+
- Nếu không tìm thấy → báo lỗi:
|
|
44
|
+
> Không tìm thấy feature khớp với "{argument}". Kiểm tra `specs/main/feature/`.
|
|
45
|
+
|
|
46
|
+
**Nếu không có ARGUMENT:**
|
|
47
|
+
|
|
48
|
+
Quét `specs/main/feature/`. Liệt kê **tất cả** features có `frd.md`, đánh dấu trạng thái tsd:
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
Features có frd.md:
|
|
52
|
+
|
|
53
|
+
[1] F-001 — auth spec✓ tsd✓
|
|
54
|
+
[2] F-002 — checkout spec✓ tsd—
|
|
55
|
+
[3] F-003 — refund spec✓ tsd— (frd có 5 Flow, 12 US, 8 VR, 3 FAC)
|
|
56
|
+
|
|
57
|
+
Chọn số feature:
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Nếu không có feature nào có frd → thông báo:
|
|
61
|
+
> Chưa có feature nào có frd.md. Hãy chạy `/spec-brownfield-feature` hoặc `/spec-new` trước.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
### Bước 2: Gate check — frd.md tồn tại + warn nếu tsd.md đã có
|
|
66
|
+
|
|
67
|
+
**Check 1 — frd.md tồn tại:**
|
|
68
|
+
|
|
69
|
+
Nếu `specs/main/feature/{F-XXX}-{slug}/frd.md` không tồn tại → dừng:
|
|
70
|
+
> ⛔ `feature/{F-XXX}-{slug}/frd.md` không tồn tại. `/spec-tsd` cần frd làm input.
|
|
71
|
+
|
|
72
|
+
**Check 2 — tsd.md đã tồn tại:**
|
|
73
|
+
|
|
74
|
+
Nếu `specs/main/feature/{F-XXX}-{slug}/tsd.md` đã tồn tại:
|
|
75
|
+
|
|
76
|
+
> ⚠ `tsd.md` đã tồn tại cho feature **{F-XXX} — {slug}**.
|
|
77
|
+
>
|
|
78
|
+
> `/spec-tsd` regenerate IDs từ 001 — nếu có test code đang reference TC-{F_ID}-NNN hoặc TS-{F_ID}-NNN, references sẽ bị vỡ.
|
|
79
|
+
>
|
|
80
|
+
> Khuyến nghị: dùng `/spec-test` qua integration changeset để giữ ID stable.
|
|
81
|
+
>
|
|
82
|
+
> Tiếp tục overwrite? (yes / no — default no)
|
|
83
|
+
|
|
84
|
+
Nếu user chọn no → dừng, suggest `/spec-test`.
|
|
85
|
+
Nếu user chọn yes → backup tsd.md cũ thành `tsd.md.bak.{timestamp}` rồi proceed.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
### Bước 3: Load context
|
|
90
|
+
|
|
91
|
+
Load các file sau:
|
|
92
|
+
|
|
93
|
+
- `specs/main/feature/{F-XXX}-{slug}/frd.md` — **bắt buộc**, source của TC
|
|
94
|
+
- `specs/main/feature/{F-XXX}-{slug}/fdd.md` — optional, đọc nếu tồn tại để hint Components Used (cho Dependencies section của tsd)
|
|
95
|
+
|
|
96
|
+
Tóm tắt context:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
TÔI HIỂU:
|
|
100
|
+
- Feature: {F-XXX} — {slug}
|
|
101
|
+
- Trong frd.md:
|
|
102
|
+
- {N} Flows
|
|
103
|
+
- {M} User Stories ({K} Acceptance Criteria)
|
|
104
|
+
- {P} Verification Rules
|
|
105
|
+
- {Q} Feature Acceptance Criteria
|
|
106
|
+
- tsd.md hiện tại: {chưa có / sẽ overwrite — backup tại tsd.md.bak.{timestamp}}
|
|
107
|
+
- fdd.md: {tồn tại — Components Used: C-XXX, C-YYY / chưa có}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
### Bước 4: Auto-derive draft
|
|
113
|
+
|
|
114
|
+
**Nguyên tắc:** mechanical derive 1:1 từ frd.md — same algorithm như `/spec-test` (xem [skills/spec-test/SKILL.md](../spec-test/SKILL.md) Bước 3.1-3.3). Tóm lại:
|
|
115
|
+
|
|
116
|
+
#### 4.1 ID assignment
|
|
117
|
+
|
|
118
|
+
- IDs bắt đầu từ `001` (vì tạo mới hoặc regenerate). TS và TC cùng feature ID `F{NNN}`, TC dùng chung sequence cho Functional / Validation / Feature AC.
|
|
119
|
+
- ID sẽ stable kể từ thời điểm này — lần edit tiếp theo qua `/spec-test` integration phải preserve.
|
|
120
|
+
|
|
121
|
+
#### 4.2 Derivation rules
|
|
122
|
+
|
|
123
|
+
| frd item | tsd output |
|
|
124
|
+
| --- | --- |
|
|
125
|
+
| Mỗi `Flow {N}` trong User Flows | 1 Test Scenario `TS-F{NNN}-{seq}` |
|
|
126
|
+
| Mỗi `AC-F{NNN}-{seq}` trong US | 1 Functional TC `TC-F{NNN}-{seq}` |
|
|
127
|
+
| Mỗi `VR-F{NNN}-{seq}` | 1 positive + 1+ negative Validation TC |
|
|
128
|
+
| Mỗi `FAC-F{NNN}-{seq}` | 1 Feature AC TC |
|
|
129
|
+
|
|
130
|
+
Detail dịch G/W/T → Preconditions/Steps/Expected, infer negative VR branches từ rule text — xem `/spec-test` Bước 3.2.
|
|
131
|
+
|
|
132
|
+
#### 4.3 Priority defaults
|
|
133
|
+
|
|
134
|
+
| Source | Priority |
|
|
135
|
+
| --- | --- |
|
|
136
|
+
| TC cover US Must | P0 |
|
|
137
|
+
| TC cover US Should | P1 |
|
|
138
|
+
| TC cover US Could | P2 |
|
|
139
|
+
| TC cover VR | inherit max priority của Refs (P1 default nếu Refs trống) |
|
|
140
|
+
| TC cover FAC e2e | P0 |
|
|
141
|
+
| TC cover FAC consistency | P1 |
|
|
142
|
+
| TC cover FAC NFR security/data | P0 |
|
|
143
|
+
| TC cover FAC NFR perf/a11y/i18n/browser | P1 |
|
|
144
|
+
| TC cover FAC data & migration | P0 |
|
|
145
|
+
|
|
146
|
+
#### 4.4 Traceability Matrix
|
|
147
|
+
|
|
148
|
+
Row per frd item — Flow / US / Story AC / VR / FAC. Mọi item phải có cover ✅. Item không thể derive → ❌ + ghi lý do ở Gaps section.
|
|
149
|
+
|
|
150
|
+
#### 4.5 Placeholders cần QC fill
|
|
151
|
+
|
|
152
|
+
Agent **không suy đoán**:
|
|
153
|
+
|
|
154
|
+
| Field | Placeholder |
|
|
155
|
+
| --- | --- |
|
|
156
|
+
| Environments table | Row mặc định `dev / staging / prod-like` với data set `TBD`, mục đích `TBD` |
|
|
157
|
+
| Test Data table | Row `{TBD — fixture}` cho mỗi dataset thấy cần |
|
|
158
|
+
| Out of Scope | Để trống với note `<!-- QC fill -->` |
|
|
159
|
+
| Test Strategy > Approach | Bullet generic theo template gốc |
|
|
160
|
+
| Overview | 2-3 câu mô tả feature scope từ frd Overview |
|
|
161
|
+
|
|
162
|
+
#### 4.6 Dependencies section
|
|
163
|
+
|
|
164
|
+
- **FRD reference**: path tới `frd.md` của feature này
|
|
165
|
+
- **Components Used**: copy từ `frd.md > Components Used`. Nếu fdd.md tồn tại → cross-reference C-XXX để đảm bảo đúng.
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### Bước 5: Review — xác nhận với QC
|
|
170
|
+
|
|
171
|
+
Hiển thị draft đầy đủ — chưa ghi file.
|
|
172
|
+
|
|
173
|
+
> Draft tsd.md trên đã đúng chưa? Check:
|
|
174
|
+
>
|
|
175
|
+
> 1. **Coverage** — Traceability Matrix có đủ row cho mỗi Flow / US / AC / VR / FAC trong frd?
|
|
176
|
+
> 2. **Priority** — defaults theo bảng 4.3, có TC nào cần override?
|
|
177
|
+
> 3. **Placeholders** — fill Environments / Test Data / Out of Scope / Strategy Approach.
|
|
178
|
+
> 4. **Extra edge cases** — ngoài AC/VR có scenario QC muốn thêm?
|
|
179
|
+
>
|
|
180
|
+
> Confirm để ghi file. Reject để revise.
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### Bước 6: Save
|
|
185
|
+
|
|
186
|
+
Ghi `specs/main/feature/{F-XXX}-{slug}/tsd.md` với status `draft` (feature-level artifact có lifecycle riêng, không phải `approved` — QC còn fill placeholders nên status `draft` cho đến khi đầy đủ).
|
|
187
|
+
|
|
188
|
+
Nếu overwrite — file backup `tsd.md.bak.{timestamp}` đã tạo ở Bước 2.
|
|
189
|
+
|
|
190
|
+
Thông báo kết quả:
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
✓ specs/main/feature/{F-XXX}-{slug}/tsd.md đã được tạo (status: draft)
|
|
194
|
+
Coverage: N Flows → N TS, M US/AC → M Functional TC, P VR → ~2P Validation TC, Q FAC → Q Feature AC TC
|
|
195
|
+
{nếu overwrite: backup tại tsd.md.bak.{timestamp}}
|
|
196
|
+
|
|
197
|
+
Bước tiếp theo:
|
|
198
|
+
- QC: fill remaining placeholders (Environments, Test Data, Out of Scope, Strategy)
|
|
199
|
+
- Đổi status: draft → approved khi sẵn sàng
|
|
200
|
+
- Sau này: nếu frd thay đổi → dùng /spec-test qua integration changeset để giữ ID stable
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## Common Rationalizations
|
|
206
|
+
|
|
207
|
+
| Rationalization | Reality |
|
|
208
|
+
| --- | --- |
|
|
209
|
+
| "Có frd rồi, viết tsd sau cũng được" | Test coverage không tracked = không biết feature đóng được chưa. tsd làm song song với frd, không sau. |
|
|
210
|
+
| "Rebuild tsd nhanh hơn cập nhật manual" | Đúng cho lần đầu. Lần sau khi đã có test code reference → rebuild sẽ break references. Lúc đó dùng `/spec-test`. |
|
|
211
|
+
| "Brownfield không cần tsd, đã có test code" | Test code là HOW. tsd là WHAT — declarative TC list để track coverage vs frd. Hai layer khác nhau. |
|
|
212
|
+
|
|
213
|
+
## Red Flags
|
|
214
|
+
|
|
215
|
+
- Traceability Matrix có ❌ mà không có Gaps section giải thích
|
|
216
|
+
- Priority hàng loạt P1 — chưa override theo defaults
|
|
217
|
+
- Test Strategy / Test Data toàn `TBD` sau khi QC review xong
|
|
218
|
+
- Overwrite tsd.md hiện có mà không cảnh báo về ID break
|
|
219
|
+
|
|
220
|
+
## Verification
|
|
221
|
+
|
|
222
|
+
Trước khi ghi file:
|
|
223
|
+
|
|
224
|
+
- [ ] Mỗi Flow trong frd có 1 TS
|
|
225
|
+
- [ ] Mỗi US AC có TC Functional cover
|
|
226
|
+
- [ ] Mỗi VR có ≥1 positive + ≥1 negative TC
|
|
227
|
+
- [ ] Mỗi FAC có TC Feature AC cover
|
|
228
|
+
- [ ] Priority deterministic theo bảng 4.3
|
|
229
|
+
- [ ] Nếu overwrite: tsd.md.bak.{timestamp} đã được tạo
|
|
230
|
+
- [ ] QC đã confirm draft
|
package/skills-overview.md
CHANGED
|
@@ -65,13 +65,14 @@ Nếu `prd.md` chưa có → dừng, yêu cầu chạy `/spec-prd` trước.
|
|
|
65
65
|
|
|
66
66
|
Dùng khi onboarding một project đã có code vào SDD. Mục tiêu: extract main artifacts từ codebase hiện có, sau đó chuyển vào **Integration Pipeline** để implement.
|
|
67
67
|
|
|
68
|
-
**Thứ tự bắt buộc:** `init` → `component` → `feature`
|
|
68
|
+
**Thứ tự bắt buộc:** `init` → `component` → `feature` → `tsd` *(tùy chọn — bootstrap test coverage tracking)*
|
|
69
69
|
|
|
70
70
|
| Command | Scan | Reads | Writes |
|
|
71
71
|
| --- | --- | --- | --- |
|
|
72
72
|
| `/spec-brownfield-init [path]` | tech stack, README, auth, infra | attachments | `prd.md` *(no indexes)*, `domain.md` *(glossary only)*, `sad.md` |
|
|
73
73
|
| `/spec-brownfield-component [path]` | module dirs, service/controller/entity files | `prd.md`, `domain.md` | `component/{C-XXX}-*/crd.md + cdd.md`; update `prd.md` Component Index; cascade Shared Entities → `domain.md` |
|
|
74
74
|
| `/spec-brownfield-feature [path]` | use cases, routes, test files | `prd.md`, `domain.md`, `component/*/crd.md` | `feature/{F-XXX}-*/frd.md + fdd.md`; update `prd.md` Feature Index |
|
|
75
|
+
| `/spec-tsd [F-XXX]` | — *(không scan code, derive 100% từ frd)* | `feature/{F-XXX}-*/frd.md`, `fdd.md` *(optional)* | `feature/{F-XXX}-*/tsd.md` |
|
|
75
76
|
|
|
76
77
|
### Phân chia trách nhiệm
|
|
77
78
|
|
|
@@ -143,6 +144,24 @@ Component Index và Feature Index **để placeholder** — sẽ được điề
|
|
|
143
144
|
|
|
144
145
|
---
|
|
145
146
|
|
|
147
|
+
### `/spec-tsd [F-XXX]`
|
|
148
|
+
|
|
149
|
+
**Mục tiêu:** Bootstrap `tsd.md` (Test Spec Document) cho một feature trực tiếp từ frd.md — mechanical derive Test Scenarios + Test Cases. KHÔNG cần integration.
|
|
150
|
+
|
|
151
|
+
**Khi nào dùng:**
|
|
152
|
+
- **Brownfield onboarding** — sau `/spec-brownfield-feature` đã sinh frd.md, chạy `/spec-tsd` cho từng feature để có test coverage tracking từ ngày 1.
|
|
153
|
+
- **Greenfield deferred** — feature đã có frd.md từ lâu nhưng tsd.md chưa được tạo.
|
|
154
|
+
- **Ad-hoc rebuild** — tsd drift khỏi frd, regenerate fresh.
|
|
155
|
+
|
|
156
|
+
**Khi nào KHÔNG dùng:**
|
|
157
|
+
- Có integration cascade từ spec.md → frd → muốn cập nhật tsd theo changeset → dùng `/spec-test` (preserve ID stable).
|
|
158
|
+
|
|
159
|
+
**Derivation:** mechanical 1:1 từ frd — mỗi Flow → TS, mỗi US/AC → Functional TC, mỗi VR → ≥1 positive + 1+ negative Validation TC, mỗi FAC → Feature AC TC. Priority deterministic theo US Priority + FAC group. KHÔNG interview.
|
|
160
|
+
|
|
161
|
+
**Cảnh báo overwrite:** nếu tsd.md đã tồn tại, skill hỏi confirm rõ ràng — regenerate sẽ reassign IDs từ 001 và làm vỡ test code references nếu có.
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
146
165
|
### Thứ tự thực hiện
|
|
147
166
|
|
|
148
167
|
```
|
|
@@ -155,6 +174,9 @@ Component Index và Feature Index **để placeholder** — sẽ được điề
|
|
|
155
174
|
/spec-brownfield-feature [path]
|
|
156
175
|
│
|
|
157
176
|
▼
|
|
177
|
+
/spec-tsd [F-XXX] (tùy chọn — chạy cho mỗi feature để bootstrap tsd.md)
|
|
178
|
+
│
|
|
179
|
+
▼
|
|
158
180
|
(fill in NEEDS_CLARIFY items khi có thêm context)
|
|
159
181
|
│
|
|
160
182
|
▼
|
|
@@ -171,6 +193,7 @@ Sau khi main artifacts đã sẵn sàng (từ greenfield hoặc brownfield), m
|
|
|
171
193
|
| --- | --- | --- |
|
|
172
194
|
| `/spec-new [requirement]` | `prd.md`, `domain.md`, frd(s), crd(s) | `specs/integrations/{slug}/spec.md` |
|
|
173
195
|
| `/spec-tech [number]` | `sad.md`, `domain.md`, cdd(s), fdd(s), `spec.md` | `specs/integrations/{slug}/tech.md` |
|
|
196
|
+
| `/spec-test [number]` | `spec.md`, frd(s), tsd(s), `tech.md` *(optional)* | `specs/integrations/{slug}/test.md`, `feature/{F-XXX}/tsd.md` |
|
|
174
197
|
| `/plan` | `spec.md`, `tech.md`, `domain.md` | `plan.md`, `todo.md` |
|
|
175
198
|
| `/build` | `plan.md`, `todo.md` | *(source code)* |
|
|
176
199
|
| `/review-integration` | `spec.md`, `tech.md`, `plan.md`, `todo.md`, *(source code)* | *(findings report)* |
|
|
@@ -212,6 +235,30 @@ Context load: `spec.md` + `sad.md` + `domain.md` + `cdd.md` (cho mỗi component
|
|
|
212
235
|
|
|
213
236
|
---
|
|
214
237
|
|
|
238
|
+
### `/spec-test [number]`
|
|
239
|
+
|
|
240
|
+
Tạo `specs/integrations/{slug}/test.md` cho một integration. Chạy bởi **QC** sau khi `spec.md` đã được approve. **Song song / độc lập** với `/spec-tech` — cả hai chỉ phụ thuộc `spec.md`. Không có thứ tự bắt buộc giữa chúng.
|
|
241
|
+
|
|
242
|
+
**Luôn hiển thị danh sách tất cả integrations** trong `specs/integrations/`, đánh dấu `✓` những cái đã có `test.md`. Nếu có argument → chọn luôn không cần hiển thị.
|
|
243
|
+
|
|
244
|
+
**Gate check:** spec.md phải `approved` + `features:` non-empty. Integration có `features: []` (thuần component) → dừng vì component-level `tsd` không tồn tại trong kit này.
|
|
245
|
+
|
|
246
|
+
Context load: `spec.md` + `frd.md` (cho mỗi feature — source của TC) + `tsd.md` (cho mỗi feature nếu tồn tại, để diff và assign next ID) + `tech.md` *(optional, hint env / data set / NFR threshold)*.
|
|
247
|
+
|
|
248
|
+
**KHÔNG interview** — agent **mechanical derive** TC từ frd.md:
|
|
249
|
+
- mỗi Flow → 1 Test Scenario (`TS-F{NNN}-{seq}`)
|
|
250
|
+
- mỗi US AC → 1 Functional TC
|
|
251
|
+
- mỗi VR → 1 positive + 1+ negative Validation TC
|
|
252
|
+
- mỗi FAC → 1 Feature AC TC (theo nhóm e2e / consistency / NFR / data & migration)
|
|
253
|
+
|
|
254
|
+
Priority deterministic: US Priority Must/Should/Could → P0/P1/P2 (TC cover US/AC); VR → inherit max priority của Refs; FAC e2e/security/data → P0, consistency/perf/a11y → P1.
|
|
255
|
+
|
|
256
|
+
**Cascade Proposals** đề xuất delta cho mỗi `feature/{F-XXX}/tsd.md` qua Changes blocks với markers `[NEW]/[MODIFY {field}]/[REMOVE]`. Feature no-delta → **bỏ block hoàn toàn**, ghi `no-op` trong Cascade Summary.
|
|
257
|
+
|
|
258
|
+
QC review: override priority defaults, fill placeholders (env / data / OOS / strategy), add extra edge cases ngoài AC/VR nếu thấy cần. Sau confirm → auto-cascade ghi tsd.md.
|
|
259
|
+
|
|
260
|
+
---
|
|
261
|
+
|
|
215
262
|
### `/plan`
|
|
216
263
|
|
|
217
264
|
Tạo `plan.md` và `todo.md` từ `spec.md` + `tech.md`. Là SDD wrapper quanh `planning-and-task-breakdown`.
|
|
@@ -288,23 +335,33 @@ Di chuyển integration đã hoàn thành hoặc không còn active từ `specs/
|
|
|
288
335
|
|
|
289
336
|
```
|
|
290
337
|
/spec-new [requirement]
|
|
291
|
-
(human review +
|
|
292
|
-
│
|
|
293
|
-
/spec-tech
|
|
294
|
-
(human review + apply cascade proposals + approve)
|
|
338
|
+
(human review + auto-cascade → frd / crd / prd / domain / sad)
|
|
295
339
|
│
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
340
|
+
▼ (spec.md approved)
|
|
341
|
+
┌───────────────────────┬───────────────────────┐
|
|
342
|
+
│ DEV branch │ QC branch (song song) │
|
|
343
|
+
▼ ▼
|
|
344
|
+
/spec-tech /spec-test
|
|
345
|
+
(review + cascade (review + cascade
|
|
346
|
+
→ cdd / fdd / sad) → tsd)
|
|
347
|
+
│ │
|
|
348
|
+
└───────────┬───────────┘
|
|
349
|
+
│ (tech.md approved — /plan KHÔNG đợi test.md)
|
|
350
|
+
▼
|
|
351
|
+
/plan
|
|
352
|
+
(human approve)
|
|
353
|
+
│
|
|
354
|
+
/build ←──────────────┐
|
|
355
|
+
│ │
|
|
356
|
+
/review-integration │ (nếu Critical/Important)
|
|
357
|
+
│ │
|
|
358
|
+
[approve] ─────────────────┘ (nếu Suggestion only)
|
|
359
|
+
│
|
|
360
|
+
/archive
|
|
306
361
|
```
|
|
307
362
|
|
|
363
|
+
> **Lưu ý:** `/spec-tech` (DEV) và `/spec-test` (QC) chạy song song / độc lập — cả hai chỉ phụ thuộc `spec.md` approved. `/plan` chỉ chờ `tech.md` (test tasks tự QC manage trong test framework, không phải plan.md).
|
|
364
|
+
|
|
308
365
|
---
|
|
309
366
|
|
|
310
367
|
## Project-level review
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: "{id}"
|
|
3
|
+
slug: "{slug}"
|
|
4
|
+
title: "{title}"
|
|
5
|
+
features: []
|
|
6
|
+
status: draft
|
|
7
|
+
created: {YYYY-MM-DD}
|
|
8
|
+
referenced_by:
|
|
9
|
+
- conventions.md > 4. Integration Artifacts > 4.7 test.md > Cấu trúc
|
|
10
|
+
- skills/spec-test/SKILL.md > Process > Bước 4: Write — sinh draft
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Context
|
|
14
|
+
|
|
15
|
+
<!-- Tóm tắt ngắn các thông tin quan trọng từ context đã load (spec.md, tech.md, frd.md, current tsd.md của các feature touched), để file self-contained. -->
|
|
16
|
+
|
|
17
|
+
## Test Strategy
|
|
18
|
+
|
|
19
|
+
<!--
|
|
20
|
+
Strategy cho integration này — KHÔNG lặp lại Strategy chung của feature.
|
|
21
|
+
Chỉ ghi delta hoặc nhấn mạnh phần đặc thù integration:
|
|
22
|
+
- Loại test ưu tiên (functional / validation / FAC / cross-story consistency / NFR).
|
|
23
|
+
- Environments / data set / fixture đặc thù.
|
|
24
|
+
- Risk areas (vd: data migration cần backfill verify, integration đụng auth flow → security regression).
|
|
25
|
+
-->
|
|
26
|
+
|
|
27
|
+
### Approach
|
|
28
|
+
|
|
29
|
+
- {bullet ngắn}
|
|
30
|
+
|
|
31
|
+
### Environments
|
|
32
|
+
|
|
33
|
+
| Env | Mục đích | Data set | Ghi chú |
|
|
34
|
+
| --- | --- | --- | --- |
|
|
35
|
+
| {dev / staging / prod-like} | {functional / E2E / load} | {seed / anonymized prod} | ... |
|
|
36
|
+
|
|
37
|
+
## Changes
|
|
38
|
+
|
|
39
|
+
<!--
|
|
40
|
+
test.md = changeset patch áp lên feature tsd.md(s). Mỗi block dưới đây tương ứng 1 feature bị touched.
|
|
41
|
+
Lặp block cho mỗi feature trong `features:` frontmatter mà có delta TC.
|
|
42
|
+
|
|
43
|
+
**Khi nào BỎ block của 1 feature:**
|
|
44
|
+
- Diff giữa frd hiện tại và tsd.md hiện tại của feature đó = empty (frd không thêm/đổi item nào mà tsd chưa cover).
|
|
45
|
+
- Bỏ block hoàn toàn, ghi `no-op` cho feature đó trong Cascade Summary để minh bạch.
|
|
46
|
+
|
|
47
|
+
**Operation:**
|
|
48
|
+
- `create` — feature/{F-XXX}/tsd.md chưa tồn tại. Nội dung đầy đủ theo template gốc, mọi TS/TC implicit [NEW] (không cần marker).
|
|
49
|
+
- `update` — feature/{F-XXX}/tsd.md đã tồn tại. Chỉ liệt kê TS/TC bị ảnh hưởng. Mỗi item có marker:
|
|
50
|
+
- `[NEW]` — TS/TC chưa có trong tsd hiện tại
|
|
51
|
+
- `[MODIFY {field}]` — TS/TC đã có, đang đổi field cụ thể (ví dụ `[MODIFY steps]`, `[MODIFY expected]`, `[MODIFY priority]`, `[MODIFY covers]`)
|
|
52
|
+
- `[REMOVE]` — TS/TC đã có, sẽ bị xóa (ID retire — không tái sử dụng)
|
|
53
|
+
|
|
54
|
+
**Format reference:** dùng đúng format của template gốc — KHÔNG duplicate skeleton ở đây. `templates/main/feature/tsd-template.md` là single source of truth cho format.
|
|
55
|
+
|
|
56
|
+
**ID assignment:** agent đọc tsd.md hiện tại của feature để xác định next ID:
|
|
57
|
+
- `TS-F{NNN}-{seq}` cho Test Scenarios
|
|
58
|
+
- `TC-F{NNN}-{seq}` cho Test Cases (Functional, Validation, Feature AC dùng chung sequence — không reset theo loại)
|
|
59
|
+
- ID **stable** — không tái sử dụng khi [REMOVE], không renumber khi [MODIFY].
|
|
60
|
+
|
|
61
|
+
**Auto-cascade:** sau khi human approve test.md, agent tự apply tất cả Changes blocks vào feature tsd.md. Integration test.md được giữ như PR record bất biến.
|
|
62
|
+
-->
|
|
63
|
+
|
|
64
|
+
### feature/{F-XXX}-{feature-slug}/tsd.md *(lặp block cho mỗi feature trong `features:` mà có delta TC; bỏ block nếu no-delta)*
|
|
65
|
+
|
|
66
|
+
**Operation:** create | update
|
|
67
|
+
**Format reference:** [tsd-template.md](../../templates/main/feature/tsd-template.md)
|
|
68
|
+
|
|
69
|
+
<!--
|
|
70
|
+
operation=create → nội dung đầy đủ theo tsd-template.md (Overview, Test Strategy, Test Scenarios, Functional TCs, Validation TCs, Feature AC TCs, Test Data, Traceability Matrix, Out of Scope, Dependencies).
|
|
71
|
+
operation=update → chỉ liệt kê TS/TC bị ảnh hưởng, mỗi item có marker, và **bắt buộc update Traceability Matrix** rows tương ứng.
|
|
72
|
+
|
|
73
|
+
Ví dụ operation=update:
|
|
74
|
+
|
|
75
|
+
#### Test Scenarios
|
|
76
|
+
|
|
77
|
+
##### TS-F001-003 [NEW]: Refund flow — happy + edge
|
|
78
|
+
|
|
79
|
+
- **Flow ref:** `frd.md > Flow 3: Refund`
|
|
80
|
+
- **Preconditions:** order đã thanh toán xong, refund window còn hạn
|
|
81
|
+
- **Postconditions:** số tiền hoàn về phương thức thanh toán gốc
|
|
82
|
+
- **Paths:**
|
|
83
|
+
- Happy: order paid → refund click → confirm → refunded
|
|
84
|
+
- Edge: order paid → refund click → past window → blocked
|
|
85
|
+
- **Test cases:** `TC-F001-022`, `TC-F001-023`
|
|
86
|
+
|
|
87
|
+
#### Functional Test Cases
|
|
88
|
+
|
|
89
|
+
##### TC-F001-022 [NEW]: Refund order trong window
|
|
90
|
+
|
|
91
|
+
| Field | Value |
|
|
92
|
+
| --- | --- |
|
|
93
|
+
| **Type** | Functional — positive |
|
|
94
|
+
| **Priority** | P0 |
|
|
95
|
+
| **Covers** | `US-F001-005`, `AC-F001-012` |
|
|
96
|
+
| **Scenario** | `TS-F001-003` |
|
|
97
|
+
| **Preconditions** | order paid 1h trước |
|
|
98
|
+
|
|
99
|
+
**Steps:**
|
|
100
|
+
|
|
101
|
+
1. Login customer
|
|
102
|
+
2. Vào order detail
|
|
103
|
+
3. Click "Refund"
|
|
104
|
+
4. Confirm refund
|
|
105
|
+
|
|
106
|
+
**Expected:**
|
|
107
|
+
|
|
108
|
+
- Refund record được tạo với status `processing`
|
|
109
|
+
- Email notification gửi tới customer
|
|
110
|
+
|
|
111
|
+
##### TC-F001-008 [MODIFY expected]
|
|
112
|
+
- Expected: 2-3 phút → 30s (sau khi tech.md tối ưu queue)
|
|
113
|
+
|
|
114
|
+
##### TC-F001-015 [REMOVE]
|
|
115
|
+
- Lý do: superseded by TC-F001-022 (cover same AC, scope hẹp hơn)
|
|
116
|
+
|
|
117
|
+
#### Validation Test Cases
|
|
118
|
+
|
|
119
|
+
| TC ID | Covers VR | Field | Input | Expected | Polarity | Op |
|
|
120
|
+
| --- | --- | --- | --- | --- | --- | --- |
|
|
121
|
+
| `TC-F001-030` | `VR-F001-008` | `refund_reason` | `"Customer changed mind"` | accept | positive | NEW |
|
|
122
|
+
| `TC-F001-031` | `VR-F001-008` | `refund_reason` | `"abc"` | reject — min length | negative | NEW |
|
|
123
|
+
|
|
124
|
+
#### Feature AC Test Cases
|
|
125
|
+
|
|
126
|
+
##### TC-F001-040 [NEW]: E2E checkout + refund
|
|
127
|
+
|
|
128
|
+
| Field | Value |
|
|
129
|
+
| --- | --- |
|
|
130
|
+
| **Type** | Feature AC — e2e |
|
|
131
|
+
| **Priority** | P0 |
|
|
132
|
+
| **Covers** | `FAC-F001-004` |
|
|
133
|
+
| **Spans** | `US-F001-001`, `US-F001-005` |
|
|
134
|
+
|
|
135
|
+
**Steps:** ...
|
|
136
|
+
**Expected:** ...
|
|
137
|
+
|
|
138
|
+
#### Traceability Matrix
|
|
139
|
+
|
|
140
|
+
Bổ sung row cho mọi item mới + cập nhật row cho item bị [MODIFY]. KHÔNG xóa row của [REMOVE] — đánh dấu retire.
|
|
141
|
+
|
|
142
|
+
| FRD Item | Type | Covered by | Status | Op |
|
|
143
|
+
| --- | --- | --- | --- | --- |
|
|
144
|
+
| `US-F001-005` | US | `TC-F001-022` | ✅ | NEW |
|
|
145
|
+
| `AC-F001-012` | Story AC | `TC-F001-022` | ✅ | NEW |
|
|
146
|
+
| `VR-F001-008` | VR | `TC-F001-030`, `TC-F001-031` | ✅ | NEW |
|
|
147
|
+
| `FAC-F001-004` | Feature AC | `TC-F001-040` | ✅ | NEW |
|
|
148
|
+
| Flow 3 | Flow | `TS-F001-003` | ✅ | NEW |
|
|
149
|
+
-->
|
|
150
|
+
|
|
151
|
+
## Out of Scope
|
|
152
|
+
|
|
153
|
+
<!-- Những gì KHÔNG được test trong integration này và lý do (vd: thuộc layer khác như infra audit, NFR đã verify ở integration trước, ...) -->
|
|
154
|
+
|
|
155
|
+
## Open Questions
|
|
156
|
+
|
|
157
|
+
<!-- Các điểm còn mơ hồ cần clarify trước khi proceed. Xóa section nếu không có. -->
|
|
158
|
+
|
|
159
|
+
## Cascade Summary
|
|
160
|
+
|
|
161
|
+
<!-- Bảng tóm tắt để reviewer scan nhanh trước khi approve. Liệt kê **tất cả** feature trong `features:` — feature no-delta ghi operation `no-op`. -->
|
|
162
|
+
|
|
163
|
+
| Artifact | Operation | Summary |
|
|
164
|
+
| --- | --- | --- |
|
|
165
|
+
| `feature/F-XXX-{slug}/tsd.md` | create / update | {ngắn: +N TS, +M TC, modify TC-F001-008, remove TC-F001-015} |
|
|
166
|
+
| `feature/F-YYY-{slug}/tsd.md` | no-op | frd không đổi, tsd hiện tại đã cover full |
|
|
@@ -27,6 +27,8 @@ Mọi thay đổi structure ở file này tự động propagate qua Changes blo
|
|
|
27
27
|
{Mô tả các luồng thao tác của user để hoàn thành mục tiêu của feature này.}
|
|
28
28
|
{Mỗi flow là một Mermaid flowchart riêng, bao gồm happy case và tất cả edge cases quan trọng.}
|
|
29
29
|
|
|
30
|
+
Flow numbering **stable** — không renumber khi xóa flow. Nếu xóa Flow 1, Flow 2 giữ nguyên số (không tái sử dụng số 1).
|
|
31
|
+
|
|
30
32
|
### Flow 1: {Tên luồng chính}
|
|
31
33
|
|
|
32
34
|
```mermaid
|
|
@@ -46,19 +48,32 @@ flowchart TD
|
|
|
46
48
|
A(["Điểm bắt đầu"]) --> B["..."]
|
|
47
49
|
```
|
|
48
50
|
|
|
49
|
-
## Feature
|
|
51
|
+
## Feature Acceptance Criteria
|
|
50
52
|
|
|
51
|
-
Criteria áp dụng cho toàn bộ feature — không
|
|
52
|
-
AC ID format: `AC-F{NNN}-{seq}` — đánh số tăng dần toàn feature (không reset giữa sections).
|
|
53
|
+
Criteria áp dụng cho **toàn bộ feature** — phần Story AC không cover được. Mọi Feature AC phải test được pass/fail.
|
|
53
54
|
|
|
54
|
-
|
|
55
|
-
|
|
55
|
+
Thường gồm 4 nhóm:
|
|
56
|
+
- **End-to-end liên story** — full happy path đi qua nhiều story.
|
|
57
|
+
- **Cross-story consistency** — UI/behavior đồng nhất giữa các màn trong feature.
|
|
58
|
+
- **Non-functional** — performance, accessibility, browser support, i18n, security.
|
|
59
|
+
- **Data & migration** — backfill, schema migration, không mất data cũ.
|
|
60
|
+
|
|
61
|
+
> Out of scope: release readiness (runbook/rollout/legal sign-off) và success metric/KPI post-release — đặt ở artifact khác (`tech.md`, `sad.md`, hoặc PMO checklist).
|
|
62
|
+
|
|
63
|
+
Feature AC ID format: `FAC-F{NNN}-{seq}` — counter **độc lập** với Story AC (`AC-F{NNN}-{seq}`). ID **stable** — không tái sử dụng seq khi xóa, không renumber.
|
|
64
|
+
|
|
65
|
+
Format: **Given/When/Then bắt buộc** — kể cả NFR / consistency. **Then phải đo được**: ngưỡng cụ thể HOẶC danh sách item so sánh.
|
|
66
|
+
|
|
67
|
+
- `FAC-{F_ID}-001`
|
|
68
|
+
- **Given** {precondition đo được}
|
|
56
69
|
- **When** {action}
|
|
57
|
-
- **Then** {
|
|
70
|
+
- **Then** {outcome có threshold hoặc danh sách cụ thể, không vague}
|
|
58
71
|
|
|
59
72
|
## User Stories
|
|
60
73
|
|
|
61
|
-
US ID format: `US-F{NNN}-{seq}` — đánh số tăng dần toàn feature.
|
|
74
|
+
US ID format: `US-F{NNN}-{seq}` — đánh số tăng dần toàn feature. ID **stable** — không tái sử dụng seq khi xóa, không renumber.
|
|
75
|
+
|
|
76
|
+
Story AC ID format: `AC-F{NNN}-{seq}` — đánh số tăng dần toàn feature (không reset giữa các story). ID **stable** — không tái sử dụng seq khi xóa, không renumber.
|
|
62
77
|
|
|
63
78
|
### US-{F_ID}-001: {Story title}
|
|
64
79
|
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
---
|
|
2
|
+
id: tsd-{feature}
|
|
3
|
+
type: tsd
|
|
4
|
+
status: draft
|
|
5
|
+
owner: "{QC}"
|
|
6
|
+
feature_id: "{Feature ID — match frd.md}"
|
|
7
|
+
frd_ref: "feature/{F-XXX}-{slug}/frd.md"
|
|
8
|
+
referenced_by:
|
|
9
|
+
- conventions.md > 3. Main Artifacts > 3.3 Feature level > tsd.md > Cấu trúc
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
<!--
|
|
13
|
+
Canonical format cho feature/{F-XXX}-{slug}/tsd.md.
|
|
14
|
+
Sinh từ frd.md — mỗi AC / VR / Flow phải có ít nhất 1 test case cover.
|
|
15
|
+
Traceability Matrix ở cuối là source of truth để kiểm tra coverage trước khi đóng feature.
|
|
16
|
+
|
|
17
|
+
TSD chỉ tồn tại ở FEATURE level — không tách tsd riêng cho component.
|
|
18
|
+
Component là internal building block; contract của component được verify gián tiếp qua TC ở đây
|
|
19
|
+
và qua unit test trong code (không phải spec artifact).
|
|
20
|
+
-->
|
|
21
|
+
|
|
22
|
+
# Test Spec: {Feature Name}
|
|
23
|
+
|
|
24
|
+
## Overview
|
|
25
|
+
|
|
26
|
+
{Phạm vi tsd này — feature gì, các luồng / AC / VR chính cần verify, trong 2-3 câu.}
|
|
27
|
+
|
|
28
|
+
## Test Strategy
|
|
29
|
+
|
|
30
|
+
### Approach
|
|
31
|
+
|
|
32
|
+
- **Functional**: verify từng US / Story AC theo happy + edge.
|
|
33
|
+
- **Validation**: derive 1:1 từ Verification Rules.
|
|
34
|
+
- **Flow-based (E2E)**: chạy theo Mermaid flows trong frd.
|
|
35
|
+
- **Feature AC**: cover các Feature AC — e2e liên story, cross-story consistency, NFR, data & migration.
|
|
36
|
+
|
|
37
|
+
### Environments
|
|
38
|
+
|
|
39
|
+
| Env | Mục đích | Data set | Ghi chú |
|
|
40
|
+
| --- | --- | --- | --- |
|
|
41
|
+
| {dev / staging / prod-like} | {functional / E2E / load} | {seed / anonymized prod} | ... |
|
|
42
|
+
|
|
43
|
+
## Test Scenarios
|
|
44
|
+
|
|
45
|
+
Mỗi scenario gắn với 1 flow trong `frd.md > User Flows`. Scenario mô tả end-to-end path; test case chi tiết liệt kê ở section bên dưới.
|
|
46
|
+
|
|
47
|
+
TS ID format: `TS-F{NNN}-{seq}` — đánh số tăng dần toàn feature. ID **stable** — đã assign rồi giữ nguyên kể cả khi xóa (không tái sử dụng seq, không renumber).
|
|
48
|
+
|
|
49
|
+
### TS-{F_ID}-001: {Tên — match Flow 1 trong frd}
|
|
50
|
+
|
|
51
|
+
- **Flow ref:** `frd.md > Flow 1: {tên}`
|
|
52
|
+
- **Preconditions:** {state trước khi chạy}
|
|
53
|
+
- **Postconditions:** {state sau khi pass}
|
|
54
|
+
- **Paths:**
|
|
55
|
+
- Happy: A → B → C(happy) → D → F
|
|
56
|
+
- Edge: A → B → C(edge) → E → G
|
|
57
|
+
- **Test cases:** `TC-{F_ID}-001`, `TC-{F_ID}-002`, ...
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### TS-{F_ID}-002: {Tên — match Flow 2 nếu có}
|
|
62
|
+
|
|
63
|
+
...
|
|
64
|
+
|
|
65
|
+
## Functional Test Cases
|
|
66
|
+
|
|
67
|
+
Cover User Stories và Acceptance Criteria trong frd.
|
|
68
|
+
|
|
69
|
+
TC ID format: `TC-F{NNN}-{seq}` — đánh số tăng dần toàn feature. ID **stable** (không tái sử dụng seq khi xóa, không renumber). Nếu xóa TC → ID đó retire, seq mới tiếp tục tăng từ max.
|
|
70
|
+
|
|
71
|
+
### TC-{F_ID}-001: {Title ngắn — verb-first}
|
|
72
|
+
|
|
73
|
+
| Field | Value |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| **Type** | Functional — positive / negative |
|
|
76
|
+
| **Priority** | P0 / P1 / P2 |
|
|
77
|
+
| **Covers** | `US-{F_ID}-001`, `AC-{F_ID}-001` |
|
|
78
|
+
| **Scenario** | `TS-{F_ID}-001` |
|
|
79
|
+
| **Preconditions** | ... |
|
|
80
|
+
|
|
81
|
+
**Steps:**
|
|
82
|
+
|
|
83
|
+
1. {action}
|
|
84
|
+
2. {action}
|
|
85
|
+
3. {action}
|
|
86
|
+
|
|
87
|
+
**Expected:**
|
|
88
|
+
|
|
89
|
+
- {observable outcome 1}
|
|
90
|
+
- {observable outcome 2}
|
|
91
|
+
|
|
92
|
+
**Test data:** {ref Test Data section hoặc inline literal}
|
|
93
|
+
|
|
94
|
+
---
|
|
95
|
+
|
|
96
|
+
### TC-{F_ID}-002: ...
|
|
97
|
+
|
|
98
|
+
## Validation Test Cases
|
|
99
|
+
|
|
100
|
+
Derive 1:1 từ Verification Rules trong frd. Mỗi `VR-F{NNN}-{seq}` cần ít nhất:
|
|
101
|
+
- 1 positive (rule pass)
|
|
102
|
+
- 1+ negative — mỗi nhánh fail là 1 case riêng (vd VR "email format" → 1 case cho missing `@`, 1 case cho missing domain, ...)
|
|
103
|
+
|
|
104
|
+
Form bảng để dễ scan; case phức tạp có thể tách ra block riêng như Functional TC.
|
|
105
|
+
|
|
106
|
+
| TC ID | Covers VR | Field | Input | Expected | Polarity |
|
|
107
|
+
| --- | --- | --- | --- | --- | --- |
|
|
108
|
+
| `TC-{F_ID}-010` | `VR-{F_ID}-001` | `email` | `"user@example.com"` | accept | positive |
|
|
109
|
+
| `TC-{F_ID}-011` | `VR-{F_ID}-001` | `email` | `""` | reject — required | negative |
|
|
110
|
+
| `TC-{F_ID}-012` | `VR-{F_ID}-001` | `email` | `"abc"` | reject — invalid format | negative |
|
|
111
|
+
|
|
112
|
+
## Feature AC Test Cases
|
|
113
|
+
|
|
114
|
+
Cover Feature Acceptance Criteria (`FAC-*`) trong frd. Feature AC trong frd đã ở format G/W/T → TC ở đây dịch 1:1: Given → Preconditions, When → Steps, Then → Expected.
|
|
115
|
+
|
|
116
|
+
### TC-{F_ID}-040: {Title — e2e liên story}
|
|
117
|
+
|
|
118
|
+
| Field | Value |
|
|
119
|
+
| --- | --- |
|
|
120
|
+
| **Type** | Feature AC — e2e |
|
|
121
|
+
| **Priority** | P0 / P1 / P2 |
|
|
122
|
+
| **Covers** | `FAC-{F_ID}-001` |
|
|
123
|
+
| **Spans** | `US-{F_ID}-001`, `US-{F_ID}-002`, `US-{F_ID}-003` |
|
|
124
|
+
| **Preconditions** | account mới chưa onboard |
|
|
125
|
+
|
|
126
|
+
**Steps:**
|
|
127
|
+
|
|
128
|
+
1. Đăng ký account mới
|
|
129
|
+
2. Verify email qua link
|
|
130
|
+
3. Hoàn thành onboarding form
|
|
131
|
+
4. Thực hiện first transaction
|
|
132
|
+
|
|
133
|
+
**Expected:**
|
|
134
|
+
|
|
135
|
+
- Toàn bộ flow chạy trong 1 session, không cần support intervene
|
|
136
|
+
- State persist đúng giữa các step (refresh không mất tiến độ)
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
### TC-{F_ID}-041: {Title — consistency}
|
|
141
|
+
|
|
142
|
+
| Field | Value |
|
|
143
|
+
| --- | --- |
|
|
144
|
+
| **Type** | Feature AC — consistency |
|
|
145
|
+
| **Priority** | P1 |
|
|
146
|
+
| **Covers** | `FAC-{F_ID}-002` |
|
|
147
|
+
| **Preconditions** | feature đã deploy lên test env, 3 màn Register / Profile / Admin Create accessible |
|
|
148
|
+
|
|
149
|
+
**Steps:**
|
|
150
|
+
|
|
151
|
+
1. Trigger empty `email` validation ở Register
|
|
152
|
+
2. Trigger empty `email` validation ở Profile
|
|
153
|
+
3. Trigger empty `email` validation ở Admin Create
|
|
154
|
+
4. Trigger invalid format `"abc"` ở cả 3 màn
|
|
155
|
+
|
|
156
|
+
**Expected:**
|
|
157
|
+
|
|
158
|
+
- 3 message ở step 1-3 identical (cùng text, cùng style)
|
|
159
|
+
- 3 message ở step 4 identical
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
### TC-{F_ID}-050: {Title — NFR perf}
|
|
164
|
+
|
|
165
|
+
| Field | Value |
|
|
166
|
+
| --- | --- |
|
|
167
|
+
| **Type** | Feature AC — performance |
|
|
168
|
+
| **Priority** | P0 |
|
|
169
|
+
| **Covers** | `FAC-{F_ID}-003` |
|
|
170
|
+
| **Preconditions** | env perf-test, dataset baseline đã load |
|
|
171
|
+
|
|
172
|
+
**Steps:**
|
|
173
|
+
|
|
174
|
+
1. Chạy load test (k6 / JMeter) profile 100 RPS sustained 5 phút lên `/login`
|
|
175
|
+
2. Đọc p95 latency từ summary report
|
|
176
|
+
|
|
177
|
+
**Expected:**
|
|
178
|
+
|
|
179
|
+
- p95 ≤ 500ms
|
|
180
|
+
- Error rate ≤ 0.1%
|
|
181
|
+
|
|
182
|
+
## Test Data
|
|
183
|
+
|
|
184
|
+
| Data set | Mục đích | Nguồn | Refresh |
|
|
185
|
+
| --- | --- | --- | --- |
|
|
186
|
+
| `seed_users` | functional positive | fixture / factory | mỗi run |
|
|
187
|
+
| `boundary_inputs` | validation edges | inline trong TC | n/a |
|
|
188
|
+
|
|
189
|
+
## Traceability Matrix
|
|
190
|
+
|
|
191
|
+
**Source of truth** để verify coverage trước khi đóng feature. Mỗi item từ frd phải xuất hiện. Gap → đánh ❌ và mô tả rõ ở phần "Gaps" bên dưới.
|
|
192
|
+
|
|
193
|
+
| FRD Item | Type | Covered by | Status |
|
|
194
|
+
| --- | --- | --- | --- |
|
|
195
|
+
| Flow 1 | Flow | `TS-{F_ID}-001` | ✅ |
|
|
196
|
+
| `US-{F_ID}-001` | US | `TC-{F_ID}-001`, `TC-{F_ID}-002` | ✅ |
|
|
197
|
+
| `AC-{F_ID}-001` | Story AC | `TC-{F_ID}-001` | ✅ |
|
|
198
|
+
| `VR-{F_ID}-001` | VR | `TC-{F_ID}-010`, `TC-{F_ID}-011`, `TC-{F_ID}-012` | ✅ |
|
|
199
|
+
| `FAC-{F_ID}-001` | Feature AC | `TC-{F_ID}-040` | ✅ |
|
|
200
|
+
| `FAC-{F_ID}-002` | Feature AC | `TC-{F_ID}-041` | ✅ |
|
|
201
|
+
| `FAC-{F_ID}-003` | Feature AC | `TC-{F_ID}-050` | ✅ |
|
|
202
|
+
| `AC-{F_ID}-00X` | Story AC | — | ❌ chưa có TC |
|
|
203
|
+
|
|
204
|
+
### Gaps
|
|
205
|
+
|
|
206
|
+
{Liệt kê item ❌ kèm lý do tạm hoãn / blocker — empty nếu coverage đầy đủ.}
|
|
207
|
+
|
|
208
|
+
## Out of Scope
|
|
209
|
+
|
|
210
|
+
- {những gì tsd này KHÔNG cover — lý do (vd: thuộc layer khác như infra/security audit, đã verify ở môi trường khác, ...)}
|
|
211
|
+
|
|
212
|
+
## Dependencies
|
|
213
|
+
|
|
214
|
+
### FRD reference
|
|
215
|
+
|
|
216
|
+
- `frd.md` của feature này — mọi ID (`US-`, `AC-`, `VR-`, Flow) phải match.
|
|
217
|
+
|
|
218
|
+
### Components Used (input only)
|
|
219
|
+
|
|
220
|
+
Tham chiếu `frd.md > Components Used` để hiểu contract của các component được feature này dùng. Behavior của component được verify **gián tiếp** qua các TC ở đây — không tách tsd riêng cho component.
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
id: "003-assign-todo"
|
|
3
|
-
slug: "assign-todo"
|
|
4
|
-
title: "Assign Todo — Test Plan"
|
|
5
|
-
features: ["F-004"]
|
|
6
|
-
status: draft
|
|
7
|
-
created: 2026-04-21
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
## Test Strategy
|
|
11
|
-
|
|
12
|
-
Approach tổng quan: test pyramid distribution, environment setup, fixtures.
|
|
13
|
-
|
|
14
|
-
## AC Coverage Matrix
|
|
15
|
-
|
|
16
|
-
| AC ID | Primary Level | Test Case ID(s) | Status |
|
|
17
|
-
|-------|--------------|-----------------|--------|
|
|
18
|
-
| AC-F004-001 | Component | TC-001 | draft |
|
|
19
|
-
| AC-F004-002 | Component | TC-002 | draft |
|
|
20
|
-
| ... |
|
|
21
|
-
|
|
22
|
-
## Verification Rules Coverage
|
|
23
|
-
|
|
24
|
-
Mỗi rule trong `frd.md > Verification Rules` của feature phải có **≥ 1 positive test case** (input hợp lệ pass) và **≥ 1 negative test case** (input vi phạm rule bị reject). Nếu rule áp dụng ở nhiều layer (client + gateway, xem `fdd.md > Verification Implementation`) → cover từng layer.
|
|
25
|
-
|
|
26
|
-
| Rule ID | Layer (từ FDD) | Test Case ID(s) | Status |
|
|
27
|
-
|---------|----------------|-----------------|--------|
|
|
28
|
-
| VR-F004-001 | service | TC-010 (pos), TC-011 (neg) | draft |
|
|
29
|
-
| VR-F004-002 | gateway | TC-012 (neg) | draft |
|
|
30
|
-
| ... |
|
|
31
|
-
|
|
32
|
-
## Test Cases
|
|
33
|
-
|
|
34
|
-
### TC-001: Non-owner không thấy assign control
|
|
35
|
-
**Verifies:** AC-F004-001 (primary)
|
|
36
|
-
**Level:** Component test (TodoModal)
|
|
37
|
-
**Setup:**
|
|
38
|
-
- Render TodoModal với prop `isOwner: false`
|
|
39
|
-
**Steps:**
|
|
40
|
-
1. Mở modal
|
|
41
|
-
2. Query assign control
|
|
42
|
-
**Expected:**
|
|
43
|
-
- Assign control không có trong DOM
|
|
44
|
-
**Negative variants:** —
|
|
45
|
-
|
|
46
|
-
### TC-006: Happy path assign
|
|
47
|
-
**Verifies:** AC-F004-006, AC-F004-007 (primary), AC-F004-008 (supporting)
|
|
48
|
-
**Level:** E2E (Playwright)
|
|
49
|
-
**Setup:**
|
|
50
|
-
- Seed: userA, userB
|
|
51
|
-
- userA login, tạo todo
|
|
52
|
-
**Steps:**
|
|
53
|
-
1. userA mở task detail
|
|
54
|
-
2. Click assign, chọn userB
|
|
55
|
-
3. Confirm
|
|
56
|
-
**Expected:**
|
|
57
|
-
- Modal hiển thị owner = userB
|
|
58
|
-
- Refresh dashboard → card hiển thị userB
|
|
59
|
-
**Verification queries:**
|
|
60
|
-
- DB: `SELECT * FROM todo_history WHERE todo_id=? AND event_type='ASSIGNED'` → 1 row, payload đúng
|