spec-lite 1.5.1 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -8
- package/package.json +1 -1
- package/skills/ado-create/SKILL.md +1 -1
- package/skills/artifact-audit/SKILL.md +3 -3
- package/skills/artifact-migrate/SKILL.md +3 -3
- package/skills/spec-brownfield-feature/SKILL.md +1 -1
- package/skills/spec-frd/SKILL.md +44 -11
- package/skills/spec-new/SKILL.md +43 -11
- package/skills/spec-test/SKILL.md +60 -59
- package/skills/spec-test-design/SKILL.md +243 -0
- package/skills-overview.md +23 -22
- package/templates/integrations/test-template.md +47 -25
- package/templates/main/feature/frd-template.md +43 -8
- package/templates/main/feature/{tsd-template.md → test-design-template.md} +73 -34
- package/templates/main/prd-template.md +2 -0
- package/skills/spec-tsd/SKILL.md +0 -241
package/skills-overview.md
CHANGED
|
@@ -62,14 +62,14 @@ Nhận F-XXX từ argument (hoặc chọn từ prd Feature Index) + tùy chọn
|
|
|
62
62
|
- **Create-only**: frd.md của feature mục tiêu **chưa tồn tại**. Đã tồn tại → **dừng, redirect `/spec-new`** (thay đổi feature đã spec phải đi qua integration để delta cascade + kéo theo `/spec-tech`/`/spec-test`).
|
|
63
63
|
- Feature mới **đơn lẻ** chưa có trong Index → offer **register một row vào `prd.md > Features`** rồi author.
|
|
64
64
|
|
|
65
|
-
**Sections template
|
|
65
|
+
**Sections template**: Overview · User Flows · Feature Acceptance Criteria (end-to-end) · Non-Functional Requirements · Data & Migration *(nếu có)* · User Stories · Verification Rules · Scope · Dependencies
|
|
66
66
|
|
|
67
67
|
**Phạm vi hẹp — chủ yếu `frd.md`:**
|
|
68
68
|
- Reference component frd phụ thuộc (Components Used → C-XXX có sẵn).
|
|
69
69
|
- Component cần-nhưng-chưa-có → ghi *candidate* + Open Question cho `/spec-sad`/architect chốt boundary.
|
|
70
70
|
- Có thể register **một** feature row vào prd (side-effect lên prd).
|
|
71
71
|
- **Cascade vocabulary lên `domain.md`** (pha mô tả/WHAT): glossary term + **định nghĩa shared entity** (attributes), `Owner: TBD` để `/spec-sad` gán ở pha thiết kế (HOW). BA define entity, KHÔNG carve/gán Owner.
|
|
72
|
-
- **KHÔNG** tạo `crd.md`/`cdd.md` (sinh ở integration time qua `/spec-new` cascade), không tạo `fdd.md`/`
|
|
72
|
+
- **KHÔNG** tạo `crd.md`/`cdd.md` (sinh ở integration time qua `/spec-new` cascade), không tạo `fdd.md`/`test-design.md`, không đổi status feature đã có, không đụng sad.
|
|
73
73
|
- Change History operation = `manual` (cả frd lẫn domain). Verification Rules dùng quy ước option-suggester của `/spec-new` (BA owns).
|
|
74
74
|
|
|
75
75
|
Bỏ qua bước này cũng được — `/spec-new` sẽ tự tạo frd làm fallback khi integration đầu tiên chạm tới feature.
|
|
@@ -94,14 +94,14 @@ Bỏ qua bước này cũng được — `/spec-new` sẽ tự tạo frd làm fa
|
|
|
94
94
|
|
|
95
95
|
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.
|
|
96
96
|
|
|
97
|
-
**Thứ tự bắt buộc:** `init` → `component` → `feature` → `
|
|
97
|
+
**Thứ tự bắt buộc:** `init` → `component` → `feature` → `test-design` *(tùy chọn — bootstrap test coverage tracking)*
|
|
98
98
|
|
|
99
99
|
| Command | Scan | Reads | Writes |
|
|
100
100
|
| --- | --- | --- | --- |
|
|
101
101
|
| `/spec-brownfield-init [path]` | tech stack, README, auth, infra | attachments | `prd.md` *(no indexes)*, `domain.md` *(glossary only)*, `sad.md` |
|
|
102
102
|
| `/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` |
|
|
103
103
|
| `/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 |
|
|
104
|
-
| `/spec-
|
|
104
|
+
| `/spec-test-design [F-XXX]` | — *(không scan code, derive 100% từ frd)* | `feature/{F-XXX}-*/frd.md`, `fdd.md` *(optional)* | `feature/{F-XXX}-*/test-design.md` |
|
|
105
105
|
|
|
106
106
|
### Phân chia trách nhiệm
|
|
107
107
|
|
|
@@ -173,21 +173,21 @@ Component Index và Feature Index **để placeholder** — sẽ được điề
|
|
|
173
173
|
|
|
174
174
|
---
|
|
175
175
|
|
|
176
|
-
### `/spec-
|
|
176
|
+
### `/spec-test-design [F-XXX]`
|
|
177
177
|
|
|
178
|
-
**Mục tiêu:** Bootstrap `
|
|
178
|
+
**Mục tiêu:** Bootstrap `test-design.md` (Test Design Document) cho một feature trực tiếp từ frd.md — mechanical derive Test Scenarios + Test Cases. KHÔNG cần integration.
|
|
179
179
|
|
|
180
180
|
**Khi nào dùng:**
|
|
181
|
-
- **Brownfield onboarding** — sau `/spec-brownfield-feature` đã sinh frd.md, chạy `/spec-
|
|
182
|
-
- **Greenfield deferred** — feature đã có frd.md từ lâu nhưng
|
|
183
|
-
- **Ad-hoc rebuild** —
|
|
181
|
+
- **Brownfield onboarding** — sau `/spec-brownfield-feature` đã sinh frd.md, chạy `/spec-test-design` cho từng feature để có test coverage tracking từ ngày 1.
|
|
182
|
+
- **Greenfield deferred** — feature đã có frd.md từ lâu nhưng test-design.md chưa được tạo.
|
|
183
|
+
- **Ad-hoc rebuild** — test-design drift khỏi frd, regenerate fresh.
|
|
184
184
|
|
|
185
185
|
**Khi nào KHÔNG dùng:**
|
|
186
|
-
- Có integration cascade từ spec.md → frd → muốn cập nhật
|
|
186
|
+
- Có integration cascade từ spec.md → frd → muốn cập nhật test-design theo changeset → dùng `/spec-test` (preserve ID stable).
|
|
187
187
|
|
|
188
|
-
**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 →
|
|
188
|
+
**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 → E2E TC, mỗi NFR → Non-functional TC, mỗi DM → Data & Migration TC. Priority deterministic theo US Priority + loại requirement. KHÔNG interview.
|
|
189
189
|
|
|
190
|
-
**Cảnh báo overwrite:** nếu
|
|
190
|
+
**Cảnh báo overwrite:** nếu test-design.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ó.
|
|
191
191
|
|
|
192
192
|
---
|
|
193
193
|
|
|
@@ -203,7 +203,7 @@ Component Index và Feature Index **để placeholder** — sẽ được điề
|
|
|
203
203
|
/spec-brownfield-feature [path]
|
|
204
204
|
│
|
|
205
205
|
▼
|
|
206
|
-
/spec-
|
|
206
|
+
/spec-test-design [F-XXX] (tùy chọn — chạy cho mỗi feature để bootstrap test-design.md)
|
|
207
207
|
│
|
|
208
208
|
▼
|
|
209
209
|
(fill in NEEDS_CLARIFY items khi có thêm context)
|
|
@@ -225,7 +225,7 @@ Nhóm skill dọn dẹp / migrate artifacts hiện có sau khi template được
|
|
|
225
225
|
|
|
226
226
|
### `/artifact-audit [type]`
|
|
227
227
|
|
|
228
|
-
Phát hiện **main artifact** lỗi thời so với template (xem `conventions.md` §7 Template Versioning). So `template_version` của artifact với `template_version` đọc thẳng từ template tại `.claude/templates/main/` — không manifest, không cache. **Chỉ main artifacts** (`prd`/`domain`/`sad`/`frd`/`fdd`/`
|
|
228
|
+
Phát hiện **main artifact** lỗi thời so với template (xem `conventions.md` §7 Template Versioning). So `template_version` của artifact với `template_version` đọc thẳng từ template tại `.claude/templates/main/` — không manifest, không cache. **Chỉ main artifacts** (`prd`/`domain`/`sad`/`frd`/`fdd`/`test-design`/`crd`/`cdd`); integration artifacts ngoài scope.
|
|
229
229
|
|
|
230
230
|
**Scope:** argument là 1 main type (`/artifact-audit frd`) hoặc list (`frd,crd`); không có arg → audit mọi main type. Type resolve theo **filename**.
|
|
231
231
|
|
|
@@ -260,7 +260,7 @@ Sau khi main artifacts đã sẵn sàng (từ greenfield hoặc brownfield), m
|
|
|
260
260
|
| --- | --- | --- |
|
|
261
261
|
| `/spec-new [requirement]` | `prd.md`, `domain.md`, frd(s), crd(s) | `.specs/integrations/{slug}/spec.md` |
|
|
262
262
|
| `/spec-tech [number]` | `sad.md`, `domain.md`, cdd(s), fdd(s), `spec.md` | `.specs/integrations/{slug}/tech.md` |
|
|
263
|
-
| `/spec-test [number]` | `spec.md`, frd(s),
|
|
263
|
+
| `/spec-test [number]` | `spec.md`, frd(s), test-design(s), `tech.md` *(optional)* | `.specs/integrations/{slug}/test.md`, `feature/{F-XXX}/test-design.md` |
|
|
264
264
|
| `/plan` | `spec.md`, `tech.md`, `domain.md` | `plan.md`, `todo.md` |
|
|
265
265
|
| `/build` | `plan.md`, `todo.md` | *(source code)* |
|
|
266
266
|
| `/review-integration` | `spec.md`, `tech.md`, `plan.md`, `todo.md`, *(source code)* | *(findings report)* |
|
|
@@ -308,21 +308,22 @@ Tạo `.specs/integrations/{slug}/test.md` cho một integration. Chạy bởi *
|
|
|
308
308
|
|
|
309
309
|
**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ị.
|
|
310
310
|
|
|
311
|
-
**Gate check:** spec.md phải `approved` + `features:` non-empty. Integration có `features: []` (thuần component) → dừng vì component-level `
|
|
311
|
+
**Gate check:** spec.md phải `approved` + `features:` non-empty. Integration có `features: []` (thuần component) → dừng vì component-level `test-design` không tồn tại trong kit này.
|
|
312
312
|
|
|
313
|
-
Context load: `spec.md` + `frd.md` (cho mỗi feature — source của TC) + `
|
|
313
|
+
Context load: `spec.md` + `frd.md` (cho mỗi feature — source của TC) + `test-design.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)*.
|
|
314
314
|
|
|
315
315
|
**KHÔNG interview** — agent **mechanical derive** TC từ frd.md:
|
|
316
316
|
- mỗi Flow → 1 Test Scenario (`TS-F{NNN}-{seq}`)
|
|
317
317
|
- mỗi US AC → 1 Functional TC
|
|
318
318
|
- mỗi VR → 1 positive + 1+ negative Validation TC
|
|
319
|
-
- mỗi FAC → 1
|
|
319
|
+
- mỗi FAC → 1 E2E TC (Type e2e / consistency)
|
|
320
|
+
- mỗi NFR → 1 Non-functional TC; mỗi DM → 1 Data & Migration TC
|
|
320
321
|
|
|
321
|
-
Priority deterministic: US Priority Must/Should/Could → P0/P1/P2 (TC cover US/AC); VR → inherit max priority của Refs; FAC e2e
|
|
322
|
+
Priority deterministic: US Priority Must/Should/Could → P0/P1/P2 (TC cover US/AC); VR → inherit max priority của Refs; FAC e2e + NFR security + DM → P0, FAC consistency + NFR perf/a11y → P1.
|
|
322
323
|
|
|
323
|
-
**Cascade Proposals** đề xuất delta cho mỗi `feature/{F-XXX}/
|
|
324
|
+
**Cascade Proposals** đề xuất delta cho mỗi `feature/{F-XXX}/test-design.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.
|
|
324
325
|
|
|
325
|
-
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
|
|
326
|
+
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 test-design.md.
|
|
326
327
|
|
|
327
328
|
---
|
|
328
329
|
|
|
@@ -410,7 +411,7 @@ Di chuyển integration đã hoàn thành hoặc không còn active từ `.specs
|
|
|
410
411
|
▼ ▼
|
|
411
412
|
/spec-tech /spec-test
|
|
412
413
|
(review + cascade (review + cascade
|
|
413
|
-
→ cdd / fdd / sad) →
|
|
414
|
+
→ cdd / fdd / sad) → test-design)
|
|
414
415
|
│ │
|
|
415
416
|
└───────────┬───────────┘
|
|
416
417
|
│ (tech.md approved — /plan KHÔNG đợi test.md)
|
|
@@ -12,15 +12,15 @@ referenced_by:
|
|
|
12
12
|
|
|
13
13
|
## Context
|
|
14
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
|
|
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 test-design.md của các feature touched), để file self-contained. -->
|
|
16
16
|
|
|
17
17
|
## Test Strategy
|
|
18
18
|
|
|
19
19
|
<!--
|
|
20
20
|
Strategy cho integration này — KHÔNG lặp lại Strategy chung của feature.
|
|
21
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 /
|
|
23
|
-
-
|
|
22
|
+
- Loại test ưu tiên (functional / validation / FAC e2e: journey / consistency / integrity / NFR / data & migration).
|
|
23
|
+
- Yêu cầu data đặc thù integration (shape) — nguồn/refresh/env assignment thuộc execution layer, KHÔNG ở đây.
|
|
24
24
|
- Risk areas (vd: data migration cần backfill verify, integration đụng auth flow → security regression).
|
|
25
25
|
-->
|
|
26
26
|
|
|
@@ -28,46 +28,40 @@ Chỉ ghi delta hoặc nhấn mạnh phần đặc thù integration:
|
|
|
28
28
|
|
|
29
29
|
- {bullet ngắn}
|
|
30
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
31
|
## Changes
|
|
38
32
|
|
|
39
33
|
<!--
|
|
40
|
-
test.md = changeset patch áp lên feature
|
|
34
|
+
test.md = changeset patch áp lên feature test-design.md(s). Mỗi block dưới đây tương ứng 1 feature bị touched.
|
|
41
35
|
Lặp block cho mỗi feature trong `features:` frontmatter mà có delta TC.
|
|
42
36
|
|
|
43
37
|
**Khi nào BỎ block của 1 feature:**
|
|
44
|
-
- Diff giữa frd hiện tại và
|
|
38
|
+
- Diff giữa frd hiện tại và test-design.md hiện tại của feature đó = empty (frd không thêm/đổi item nào mà test-design chưa cover).
|
|
45
39
|
- Bỏ block hoàn toàn, ghi `no-op` cho feature đó trong Cascade Summary để minh bạch.
|
|
46
40
|
|
|
47
41
|
**Operation:**
|
|
48
|
-
- `create` — feature/{F-XXX}/
|
|
49
|
-
- `update` — feature/{F-XXX}/
|
|
50
|
-
- `[NEW]` — TS/TC chưa có trong
|
|
42
|
+
- `create` — feature/{F-XXX}/test-design.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).
|
|
43
|
+
- `update` — feature/{F-XXX}/test-design.md đã tồn tại. Chỉ liệt kê TS/TC bị ảnh hưởng. Mỗi item có marker:
|
|
44
|
+
- `[NEW]` — TS/TC chưa có trong test-design hiện tại
|
|
51
45
|
- `[MODIFY {field}]` — TS/TC đã có, đang đổi field cụ thể (ví dụ `[MODIFY steps]`, `[MODIFY expected]`, `[MODIFY priority]`, `[MODIFY covers]`)
|
|
52
46
|
- `[REMOVE]` — TS/TC đã có, sẽ bị xóa (ID retire — không tái sử dụng)
|
|
53
47
|
|
|
54
|
-
**Format reference:** dùng đúng format của template gốc — KHÔNG duplicate skeleton ở đây. `templates/main/feature/
|
|
48
|
+
**Format reference:** dùng đúng format của template gốc — KHÔNG duplicate skeleton ở đây. `templates/main/feature/test-design-template.md` là single source of truth cho format.
|
|
55
49
|
|
|
56
|
-
**ID assignment:** agent đọc
|
|
50
|
+
**ID assignment:** agent đọc test-design.md hiện tại của feature để xác định next ID:
|
|
57
51
|
- `TS-F{NNN}-{seq}` cho Test Scenarios
|
|
58
|
-
- `TC-F{NNN}-{seq}` cho Test Cases (Functional, Validation,
|
|
52
|
+
- `TC-F{NNN}-{seq}` cho Test Cases (Functional, Validation, E2E dùng chung sequence — không reset theo loại)
|
|
59
53
|
- ID **stable** — không tái sử dụng khi [REMOVE], không renumber khi [MODIFY].
|
|
60
54
|
|
|
61
|
-
**Auto-cascade:** sau khi human approve test.md, agent tự apply tất cả Changes blocks vào feature
|
|
55
|
+
**Auto-cascade:** sau khi human approve test.md, agent tự apply tất cả Changes blocks vào feature test-design.md. Integration test.md được giữ như PR record bất biến.
|
|
62
56
|
-->
|
|
63
57
|
|
|
64
|
-
### feature/{F-XXX}-{feature-slug}/
|
|
58
|
+
### feature/{F-XXX}-{feature-slug}/test-design.md *(lặp block cho mỗi feature trong `features:` mà có delta TC; bỏ block nếu no-delta)*
|
|
65
59
|
|
|
66
60
|
**Operation:** create | update
|
|
67
|
-
**Format reference:** [
|
|
61
|
+
**Format reference:** [test-design-template.md](../../templates/main/feature/test-design-template.md)
|
|
68
62
|
|
|
69
63
|
<!--
|
|
70
|
-
operation=create → nội dung đầy đủ theo
|
|
64
|
+
operation=create → nội dung đầy đủ theo test-design-template.md (Overview, Test Strategy, Test Scenarios, Functional TCs, Validation TCs, E2E TCs, Non-Functional TCs, Data & Migration TCs, Test Data Requirements, Traceability Matrix, Out of Scope, Dependencies).
|
|
71
65
|
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
66
|
|
|
73
67
|
Ví dụ operation=update:
|
|
@@ -121,13 +115,13 @@ Ví dụ operation=update:
|
|
|
121
115
|
| `TC-F001-030` | `VR-F001-008` | `refund_reason` | `"Customer changed mind"` | accept | positive | NEW |
|
|
122
116
|
| `TC-F001-031` | `VR-F001-008` | `refund_reason` | `"abc"` | reject — min length | negative | NEW |
|
|
123
117
|
|
|
124
|
-
####
|
|
118
|
+
#### E2E Test Cases
|
|
125
119
|
|
|
126
120
|
##### TC-F001-040 [NEW]: E2E checkout + refund
|
|
127
121
|
|
|
128
122
|
| Field | Value |
|
|
129
123
|
| --- | --- |
|
|
130
|
-
| **Type** |
|
|
124
|
+
| **Type** | E2E — journey |
|
|
131
125
|
| **Priority** | P0 |
|
|
132
126
|
| **Covers** | `FAC-F001-004` |
|
|
133
127
|
| **Spans** | `US-F001-001`, `US-F001-005` |
|
|
@@ -135,6 +129,32 @@ Ví dụ operation=update:
|
|
|
135
129
|
**Steps:** ...
|
|
136
130
|
**Expected:** ...
|
|
137
131
|
|
|
132
|
+
#### Non-Functional Test Cases
|
|
133
|
+
|
|
134
|
+
##### TC-F001-045 [NEW]: Refund endpoint chịu tải
|
|
135
|
+
|
|
136
|
+
| Field | Value |
|
|
137
|
+
| --- | --- |
|
|
138
|
+
| **Type** | Non-functional — performance |
|
|
139
|
+
| **Priority** | P1 |
|
|
140
|
+
| **Covers** | `NFR-F001-002` |
|
|
141
|
+
|
|
142
|
+
**Steps:** ...
|
|
143
|
+
**Expected:** ...
|
|
144
|
+
|
|
145
|
+
#### Data & Migration Test Cases
|
|
146
|
+
|
|
147
|
+
##### TC-F001-048 [NEW]: Backfill refund_reason cho order cũ
|
|
148
|
+
|
|
149
|
+
| Field | Value |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| **Type** | Data migration |
|
|
152
|
+
| **Priority** | P0 |
|
|
153
|
+
| **Covers** | `DM-F001-001` |
|
|
154
|
+
|
|
155
|
+
**Steps:** ...
|
|
156
|
+
**Expected:** ...
|
|
157
|
+
|
|
138
158
|
#### Traceability Matrix
|
|
139
159
|
|
|
140
160
|
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.
|
|
@@ -145,6 +165,8 @@ Bổ sung row cho mọi item mới + cập nhật row cho item bị [MODIFY]. KH
|
|
|
145
165
|
| `AC-F001-012` | Story AC | `TC-F001-022` | ✅ | NEW |
|
|
146
166
|
| `VR-F001-008` | VR | `TC-F001-030`, `TC-F001-031` | ✅ | NEW |
|
|
147
167
|
| `FAC-F001-004` | Feature AC | `TC-F001-040` | ✅ | NEW |
|
|
168
|
+
| `NFR-F001-002` | NFR | `TC-F001-045` | ✅ | NEW |
|
|
169
|
+
| `DM-F001-001` | Data & Migration | `TC-F001-048` | ✅ | NEW |
|
|
148
170
|
| Flow 3 | Flow | `TS-F001-003` | ✅ | NEW |
|
|
149
171
|
-->
|
|
150
172
|
|
|
@@ -162,5 +184,5 @@ Bổ sung row cho mọi item mới + cập nhật row cho item bị [MODIFY]. KH
|
|
|
162
184
|
|
|
163
185
|
| Artifact | Operation | Summary |
|
|
164
186
|
| --- | --- | --- |
|
|
165
|
-
| `feature/F-XXX-{slug}/
|
|
166
|
-
| `feature/F-YYY-{slug}/
|
|
187
|
+
| `feature/F-XXX-{slug}/test-design.md` | create / update | {ngắn: +N TS, +M TC, modify TC-F001-008, remove TC-F001-015} |
|
|
188
|
+
| `feature/F-YYY-{slug}/test-design.md` | no-op | frd không đổi, test-design hiện tại đã cover full |
|
|
@@ -4,10 +4,15 @@ type: frd
|
|
|
4
4
|
status: draft
|
|
5
5
|
owner: "{BA}"
|
|
6
6
|
feature_id: "{Feature ID từ PRD Feature Index}"
|
|
7
|
-
template_version:
|
|
7
|
+
template_version: 2
|
|
8
8
|
migrations:
|
|
9
9
|
- to: 1
|
|
10
10
|
note: "baseline"
|
|
11
|
+
- to: 2
|
|
12
|
+
note: "Tách FAC theo type/execution-mode: FAC rescope còn end-to-end (journey + consistency + integrity); tách entries loại NFR → section 'Non-Functional Requirements' và loại data/migration → section 'Data & Migration', cả hai required-emptyable (heading luôn hiện, để trống nếu không có). NFR-F* tham chiếu NFR-* của PRD nếu có thể. Test case downstream giữ prefix TC-F*."
|
|
13
|
+
add: ["Non-Functional Requirements", "Data & Migration"]
|
|
14
|
+
update:
|
|
15
|
+
- { section: "Feature Acceptance Criteria", change: "rescope còn end-to-end (e2e liên story + cross-story consistency + integrity); tách entries loại NFR → section 'Non-Functional Requirements' (required-emptyable), loại data/migration → section 'Data & Migration' (required-emptyable); relocate tương tác, e2e/consistency giữ nguyên" }
|
|
11
16
|
referenced_by:
|
|
12
17
|
- conventions.md > 3. Main Artifacts > 3.3 Feature level > frd.md > Cấu trúc
|
|
13
18
|
- skills/spec-frd/SKILL.md > Process > Bước 5: Write — sinh draft
|
|
@@ -55,25 +60,55 @@ flowchart TD
|
|
|
55
60
|
|
|
56
61
|
## Feature Acceptance Criteria
|
|
57
62
|
|
|
58
|
-
Criteria áp
|
|
63
|
+
Criteria **end-to-end** áp cho toàn feature mà Story AC lẻ không cover được — verify sự **kết nối giữa các phần** (emergent), không phải behavior từng story. Mọi Feature AC phải test được pass/fail.
|
|
59
64
|
|
|
60
|
-
|
|
61
|
-
- **
|
|
62
|
-
- **
|
|
63
|
-
- **
|
|
64
|
-
- **Data & migration** — backfill, schema migration, không mất data cũ.
|
|
65
|
+
Gồm 3 shape (đều functional, scope rộng — trục phân chia + lý do xem `terms/001-frd-fac-pillars.md`; nền tảng type/scope xem `terms/002-functional-test-vs-e2e-test.md`):
|
|
66
|
+
- **Journey (liên story)** — full happy path đi *tuần tự* qua nhiều story trong 1 session; verify state persist + không đứt giữa các bước.
|
|
67
|
+
- **Consistency (đa màn)** — UI/behavior đồng nhất khi *so* nhiều màn trong feature với nhau.
|
|
68
|
+
- **Integrity (bất biến liên story)** — business invariant phải đúng khi *kết hợp* nhiều story, **không nhất thiết theo trình tự** (vd: xóa account → cascade xóa mọi order ở mọi module; tổng/đối soát khớp sau nhiều thao tác). Verify *trạng thái nhất quán cuối cùng*, không phải hành trình tuần tự — đây là nhà cho cross-story functional rule mà journey/consistency không ôm.
|
|
65
69
|
|
|
70
|
+
> NFR (performance, a11y, security, browser, i18n) và Data & Migration **KHÔNG** thuộc đây — chúng có section riêng bên dưới (khác type / execution-mode).
|
|
66
71
|
> 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).
|
|
67
72
|
|
|
68
73
|
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.
|
|
69
74
|
|
|
70
|
-
Format: **Given/When/Then bắt buộc** — kể cả
|
|
75
|
+
Format: **Given/When/Then bắt buộc** — kể cả consistency. **Then phải đo được**: ngưỡng cụ thể HOẶC danh sách item so sánh.
|
|
71
76
|
|
|
72
77
|
- `FAC-{F_ID}-001`
|
|
73
78
|
- **Given** {precondition đo được}
|
|
74
79
|
- **When** {action}
|
|
75
80
|
- **Then** {outcome có threshold hoặc danh sách cụ thể, không vague}
|
|
76
81
|
|
|
82
|
+
## Non-Functional Requirements
|
|
83
|
+
|
|
84
|
+
<!-- Required-emptyable: GIỮ heading; để trống (không bullet) nếu feature không có NFR riêng ngoài bar chung của PRD. -->
|
|
85
|
+
|
|
86
|
+
NFR áp cho feature — **non-functional type** (performance, accessibility, security, browser support, i18n). Khác Feature AC ở chỗ verify *chất lượng dưới điều kiện*, không phải *làm đúng việc*.
|
|
87
|
+
|
|
88
|
+
> **Security — phân biệt rõ type:** access-control / authz rules ("role X không được thấy/làm Y") là **functional** → đặt ở Story AC hoặc Verification Rules, KHÔNG vào đây. Chỉ phần **non-functional** của security (pentest, vulnerability scan, security posture / hardening — verify bằng scanner, không phải walk UI) mới là NFR.
|
|
89
|
+
|
|
90
|
+
Quan hệ với PRD: mỗi NFR **tham chiếu `NFR-*` của PRD nếu có thể** (refine/siết bar chung cho feature này); nếu là yêu cầu **đặc thù-feature** mà PRD không có → đứng độc lập (không ref).
|
|
91
|
+
|
|
92
|
+
NFR ID format: `NFR-F{NNN}-{seq}` — counter độc lập. ID **stable** — không tái sử dụng seq khi xóa, không renumber. Format **Given/When/Then bắt buộc**, **Then đo được** (ngưỡng cụ thể).
|
|
93
|
+
|
|
94
|
+
- `NFR-{F_ID}-001` *(refines `NFR-P01` — nếu có)*
|
|
95
|
+
- **Given** {điều kiện đo được — vd: 100 RPS sustained 5 phút}
|
|
96
|
+
- **When** {action}
|
|
97
|
+
- **Then** {ngưỡng cụ thể — vd: p95 ≤ 500ms, error rate ≤ 0.1%}
|
|
98
|
+
|
|
99
|
+
## Data & Migration
|
|
100
|
+
|
|
101
|
+
<!-- Required-emptyable: GIỮ heading; để trống (không bullet) nếu feature không đụng migration / backfill data cũ. -->
|
|
102
|
+
|
|
103
|
+
Yêu cầu về **dữ liệu cũ qua nâng cấp** — backfill, schema migration, không mất/hỏng data hiện hữu. Functional-type nhưng execution-mode riêng (chạy migration trên dataset, không phải UI flow).
|
|
104
|
+
|
|
105
|
+
DM ID format: `DM-F{NNN}-{seq}` — counter độc lập. ID **stable** — không tái sử dụng seq khi xóa, không renumber. Format **Given/When/Then bắt buộc**, **Then đo được** (đếm bản ghi / so khớp cụ thể).
|
|
106
|
+
|
|
107
|
+
- `DM-{F_ID}-001`
|
|
108
|
+
- **Given** {dataset cũ đo được — vd: 10.000 bản ghi địa chỉ format cũ}
|
|
109
|
+
- **When** {chạy migration}
|
|
110
|
+
- **Then** {kết quả đo được — vd: 10.000/10.000 đọc được, 0 bản ghi null, count khớp trước/sau}
|
|
111
|
+
|
|
77
112
|
## User Stories
|
|
78
113
|
|
|
79
114
|
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.
|
|
@@ -1,33 +1,39 @@
|
|
|
1
1
|
---
|
|
2
|
-
id:
|
|
3
|
-
type:
|
|
2
|
+
id: test-design-{feature}
|
|
3
|
+
type: test-design
|
|
4
4
|
status: draft
|
|
5
5
|
owner: "{QC}"
|
|
6
6
|
feature_id: "{Feature ID — match frd.md}"
|
|
7
7
|
frd_ref: "feature/{F-XXX}-{slug}/frd.md"
|
|
8
|
-
template_version:
|
|
8
|
+
template_version: 2
|
|
9
9
|
migrations:
|
|
10
10
|
- to: 1
|
|
11
11
|
note: "baseline"
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
- to: 2
|
|
13
|
+
note: "Mirror frd v2 + trim execution-leakage (giữ vai WHAT). Tách 'Feature AC Test Cases' (v1) theo type/execution-mode: đổi tên → 'E2E Test Cases' (chỉ FAC end-to-end: journey/consistency/integrity), tách TC loại NFR → 'Non-Functional Test Cases' và loại data/migration → 'Data & Migration Test Cases', cả hai required-emptyable. TC giữ prefix TC-F* chung sequence."
|
|
14
|
+
add: ["E2E Test Cases", "Non-Functional Test Cases", "Data & Migration Test Cases"]
|
|
15
|
+
remove:
|
|
16
|
+
- { section: "Feature AC Test Cases", reason: "đổi tên → 'E2E Test Cases' (chỉ cover FAC end-to-end) + tách TC Type=NFR → 'Non-Functional Test Cases' (required-emptyable), Type=data/migration → 'Data & Migration Test Cases' (required-emptyable); carry-over toàn bộ TC theo field Type, không mất nội dung" }
|
|
17
|
+
- { section: "Test Strategy > Environments", reason: "env assignment/scheduling là execution concern — design chỉ cần env requirement ở per-TC Preconditions" }
|
|
18
|
+
update:
|
|
19
|
+
- { section: "Test Data", change: "đổi thành 'Test Data Requirements' — bỏ cột Nguồn (fixture/factory = provisioning) + Refresh (cadence = execution), thêm cột 'Yêu cầu data (shape)'" }
|
|
14
20
|
---
|
|
15
21
|
|
|
16
22
|
<!--
|
|
17
|
-
Canonical format cho feature/{F-XXX}-{slug}/
|
|
23
|
+
Canonical format cho feature/{F-XXX}-{slug}/test-design.md.
|
|
18
24
|
Sinh từ frd.md — mỗi AC / VR / Flow phải có ít nhất 1 test case cover.
|
|
19
25
|
Traceability Matrix ở cuối là source of truth để kiểm tra coverage trước khi đóng feature.
|
|
20
26
|
|
|
21
|
-
|
|
27
|
+
Test Design chỉ tồn tại ở FEATURE level — không tách test-design riêng cho component.
|
|
22
28
|
Component là internal building block; contract của component được verify gián tiếp qua TC ở đây
|
|
23
29
|
và qua unit test trong code (không phải spec artifact).
|
|
24
30
|
-->
|
|
25
31
|
|
|
26
|
-
# Test
|
|
32
|
+
# Test Design: {Feature Name}
|
|
27
33
|
|
|
28
34
|
## Overview
|
|
29
35
|
|
|
30
|
-
{Phạm vi
|
|
36
|
+
{Phạm vi test-design này — feature gì, các luồng / AC / VR chính cần verify, trong 2-3 câu.}
|
|
31
37
|
|
|
32
38
|
## Test Strategy
|
|
33
39
|
|
|
@@ -36,13 +42,11 @@ và qua unit test trong code (không phải spec artifact).
|
|
|
36
42
|
- **Functional**: verify từng US / Story AC theo happy + edge.
|
|
37
43
|
- **Validation**: derive 1:1 từ Verification Rules.
|
|
38
44
|
- **Flow-based (E2E)**: chạy theo Mermaid flows trong frd.
|
|
39
|
-
- **Feature AC**: cover
|
|
45
|
+
- **Feature AC (end-to-end)**: cover `FAC-*` — journey liên story + cross-story consistency.
|
|
46
|
+
- **Non-functional**: cover `NFR-*` — performance / a11y / security (execution-mode riêng: load test, scanner...).
|
|
47
|
+
- **Data & migration** *(nếu có)*: cover `DM-*` — chạy migration trên dataset, verify data cũ không mất/hỏng.
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
| Env | Mục đích | Data set | Ghi chú |
|
|
44
|
-
| --- | --- | --- | --- |
|
|
45
|
-
| {dev / staging / prod-like} | {functional / E2E / load} | {seed / anonymized prod} | ... |
|
|
49
|
+
> Yêu cầu env của mỗi test class ghi inline ở **Preconditions** từng TC (vd "env perf-test", "dataset prod-like đã load"). Gán env tier cụ thể + lịch chạy thuộc **execution layer** — không ở test-design.
|
|
46
50
|
|
|
47
51
|
## Test Scenarios
|
|
48
52
|
|
|
@@ -93,7 +97,7 @@ TC ID format: `TC-F{NNN}-{seq}` — đánh số tăng dần toàn feature. ID **
|
|
|
93
97
|
- {observable outcome 1}
|
|
94
98
|
- {observable outcome 2}
|
|
95
99
|
|
|
96
|
-
**Test data:** {ref Test Data
|
|
100
|
+
**Test data:** {ref Test Data Requirements hoặc inline literal}
|
|
97
101
|
|
|
98
102
|
---
|
|
99
103
|
|
|
@@ -113,15 +117,15 @@ Form bảng để dễ scan; case phức tạp có thể tách ra block riêng n
|
|
|
113
117
|
| `TC-{F_ID}-011` | `VR-{F_ID}-001` | `email` | `""` | reject — required | negative |
|
|
114
118
|
| `TC-{F_ID}-012` | `VR-{F_ID}-001` | `email` | `"abc"` | reject — invalid format | negative |
|
|
115
119
|
|
|
116
|
-
##
|
|
120
|
+
## E2E Test Cases
|
|
117
121
|
|
|
118
|
-
Cover Feature Acceptance Criteria (`FAC-*`) trong frd.
|
|
122
|
+
Cover Feature Acceptance Criteria (`FAC-*`) trong frd — **end-to-end** (journey + consistency + integrity). FAC ở frd đã ở format G/W/T → TC dịch 1:1: Given → Preconditions, When → Steps, Then → Expected. Phân biệt shape bằng field **Type**: `E2E — journey` = tuần tự liên story / `E2E — consistency` = so khớp đa màn / `E2E — integrity` = assert business invariant sau khi kết hợp nhiều story (không nhất thiết tuần tự) (không có TC riêng cho NFR / data ở đây — xem 2 section bên dưới).
|
|
119
123
|
|
|
120
|
-
### TC-{F_ID}-040: {Title — e2e liên story}
|
|
124
|
+
### TC-{F_ID}-040: {Title — e2e journey liên story}
|
|
121
125
|
|
|
122
126
|
| Field | Value |
|
|
123
127
|
| --- | --- |
|
|
124
|
-
| **Type** |
|
|
128
|
+
| **Type** | E2E — journey |
|
|
125
129
|
| **Priority** | P0 / P1 / P2 |
|
|
126
130
|
| **Covers** | `FAC-{F_ID}-001` |
|
|
127
131
|
| **Spans** | `US-{F_ID}-001`, `US-{F_ID}-002`, `US-{F_ID}-003` |
|
|
@@ -145,7 +149,7 @@ Cover Feature Acceptance Criteria (`FAC-*`) trong frd. Feature AC trong frd đã
|
|
|
145
149
|
|
|
146
150
|
| Field | Value |
|
|
147
151
|
| --- | --- |
|
|
148
|
-
| **Type** |
|
|
152
|
+
| **Type** | E2E — consistency |
|
|
149
153
|
| **Priority** | P1 |
|
|
150
154
|
| **Covers** | `FAC-{F_ID}-002` |
|
|
151
155
|
| **Preconditions** | feature đã deploy lên test env, 3 màn Register / Profile / Admin Create accessible |
|
|
@@ -164,13 +168,19 @@ Cover Feature Acceptance Criteria (`FAC-*`) trong frd. Feature AC trong frd đã
|
|
|
164
168
|
|
|
165
169
|
---
|
|
166
170
|
|
|
171
|
+
## Non-Functional Test Cases
|
|
172
|
+
|
|
173
|
+
<!-- Required-emptyable: GIỮ heading; để trống (không TC) nếu section Non-Functional Requirements ở frd rỗng. -->
|
|
174
|
+
|
|
175
|
+
Cover `NFR-*` trong frd. **Non-functional type** — execution-mode riêng (load test / scanner / a11y audit), không phải UI walk. Type = `performance` / `a11y` / `security` / ... TC giữ prefix `TC-F*` chung sequence.
|
|
176
|
+
|
|
167
177
|
### TC-{F_ID}-050: {Title — NFR perf}
|
|
168
178
|
|
|
169
179
|
| Field | Value |
|
|
170
180
|
| --- | --- |
|
|
171
|
-
| **Type** |
|
|
181
|
+
| **Type** | Non-functional — performance |
|
|
172
182
|
| **Priority** | P0 |
|
|
173
|
-
| **Covers** | `
|
|
183
|
+
| **Covers** | `NFR-{F_ID}-001` |
|
|
174
184
|
| **Preconditions** | env perf-test, dataset baseline đã load |
|
|
175
185
|
|
|
176
186
|
**Steps:**
|
|
@@ -183,12 +193,40 @@ Cover Feature Acceptance Criteria (`FAC-*`) trong frd. Feature AC trong frd đã
|
|
|
183
193
|
- p95 ≤ 500ms
|
|
184
194
|
- Error rate ≤ 0.1%
|
|
185
195
|
|
|
186
|
-
## Test
|
|
196
|
+
## Data & Migration Test Cases
|
|
187
197
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
198
|
+
<!-- Required-emptyable: GIỮ heading; để trống (không TC) nếu section Data & Migration ở frd rỗng. -->
|
|
199
|
+
|
|
200
|
+
Cover `DM-*` trong frd. Chạy migration trên dataset prod-like rồi assert data cũ nguyên vẹn. Type = `data migration`. TC giữ prefix `TC-F*` chung sequence.
|
|
201
|
+
|
|
202
|
+
### TC-{F_ID}-060: {Title — migrate data cũ}
|
|
203
|
+
|
|
204
|
+
| Field | Value |
|
|
205
|
+
| --- | --- |
|
|
206
|
+
| **Type** | Data migration |
|
|
207
|
+
| **Priority** | P0 |
|
|
208
|
+
| **Covers** | `DM-{F_ID}-001` |
|
|
209
|
+
| **Preconditions** | env có dataset cũ prod-like (vd: 10.000 bản ghi địa chỉ format cũ) đã load |
|
|
210
|
+
|
|
211
|
+
**Steps:**
|
|
212
|
+
|
|
213
|
+
1. Snapshot count + checksum dataset trước migration
|
|
214
|
+
2. Chạy migration script
|
|
215
|
+
3. Đọc lại toàn bộ bản ghi sau migration
|
|
216
|
+
|
|
217
|
+
**Expected:**
|
|
218
|
+
|
|
219
|
+
- Count sau = count trước (10.000/10.000), không bản ghi nào null
|
|
220
|
+
- Mọi địa chỉ cũ đọc được đúng format mới, 0 lỗi parse
|
|
221
|
+
|
|
222
|
+
## Test Data Requirements
|
|
223
|
+
|
|
224
|
+
Dữ liệu mỗi test **cần** (requirement — KHÔNG phải provisioning/refresh; cách lấy data + cadence thuộc execution layer).
|
|
225
|
+
|
|
226
|
+
| Data set | Mục đích | Yêu cầu data (shape / đặc điểm) |
|
|
227
|
+
| --- | --- | --- |
|
|
228
|
+
| `seed_users` | functional positive | user hợp lệ, đủ field bắt buộc |
|
|
229
|
+
| `boundary_inputs` | validation edges | giá trị biên cho mỗi VR (rỗng, sai format, quá dài...) |
|
|
192
230
|
|
|
193
231
|
## Traceability Matrix
|
|
194
232
|
|
|
@@ -200,9 +238,10 @@ Cover Feature Acceptance Criteria (`FAC-*`) trong frd. Feature AC trong frd đã
|
|
|
200
238
|
| `US-{F_ID}-001` | US | `TC-{F_ID}-001`, `TC-{F_ID}-002` | ✅ |
|
|
201
239
|
| `AC-{F_ID}-001` | Story AC | `TC-{F_ID}-001` | ✅ |
|
|
202
240
|
| `VR-{F_ID}-001` | VR | `TC-{F_ID}-010`, `TC-{F_ID}-011`, `TC-{F_ID}-012` | ✅ |
|
|
203
|
-
| `FAC-{F_ID}-001` | Feature AC | `TC-{F_ID}-040` | ✅ |
|
|
204
|
-
| `FAC-{F_ID}-002` | Feature AC | `TC-{F_ID}-041` | ✅ |
|
|
205
|
-
| `
|
|
241
|
+
| `FAC-{F_ID}-001` | Feature AC (e2e) | `TC-{F_ID}-040` | ✅ |
|
|
242
|
+
| `FAC-{F_ID}-002` | Feature AC (consistency) | `TC-{F_ID}-041` | ✅ |
|
|
243
|
+
| `NFR-{F_ID}-001` | NFR | `TC-{F_ID}-050` | ✅ |
|
|
244
|
+
| `DM-{F_ID}-001` | Data & Migration | `TC-{F_ID}-060` | ✅ |
|
|
206
245
|
| `AC-{F_ID}-00X` | Story AC | — | ❌ chưa có TC |
|
|
207
246
|
|
|
208
247
|
### Gaps
|
|
@@ -211,17 +250,17 @@ Cover Feature Acceptance Criteria (`FAC-*`) trong frd. Feature AC trong frd đã
|
|
|
211
250
|
|
|
212
251
|
## Out of Scope
|
|
213
252
|
|
|
214
|
-
- {những gì
|
|
253
|
+
- {những gì test-design này KHÔNG cover — lý do (vd: thuộc layer khác như infra/security audit, đã verify ở môi trường khác, ...)}
|
|
215
254
|
|
|
216
255
|
## Dependencies
|
|
217
256
|
|
|
218
257
|
### FRD reference
|
|
219
258
|
|
|
220
|
-
- `frd.md` của feature này — mọi ID (`US-`, `AC-`, `VR-`, Flow) phải match.
|
|
259
|
+
- `frd.md` của feature này — mọi ID (`US-`, `AC-`, `VR-`, `FAC-`, `NFR-`, `DM-`, Flow) phải match.
|
|
221
260
|
|
|
222
261
|
### Components Used (input only)
|
|
223
262
|
|
|
224
|
-
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
|
|
263
|
+
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 test-design riêng cho component.
|
|
225
264
|
|
|
226
265
|
## Change History
|
|
227
266
|
|
|
@@ -68,6 +68,8 @@ Chi tiết về vai trò và thiết kế nằm trong `.specs/main/component/{C-
|
|
|
68
68
|
|
|
69
69
|
## Non-Functional Requirements
|
|
70
70
|
|
|
71
|
+
NFR **product-wide** (bar chung cho cả sản phẩm). Feature refine/siết bar này cho ngữ cảnh của nó trong `frd.md > Non-Functional Requirements` bằng `NFR-F{NNN}-{seq}` *(tham chiếu `NFR-*` ở đây)*; NFR đặc thù-feature mà chưa có ở đây → nếu lặp lại ở nhiều feature thì **promote** lên bảng này.
|
|
72
|
+
|
|
71
73
|
| ID | Category | Requirement | Target | Priority |
|
|
72
74
|
| --- | --- | --- | --- | --- |
|
|
73
75
|
| NFR-P01 | Performance | {requirement} | {target đo được} | High/Medium/Low |
|