@educa-corp/sdd-framework 0.9.2 → 0.9.4
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/bin/build.js +11 -0
- package/bin/qc-base-map.json +119 -49
- package/bin/self-check.js +30 -0
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/qc-analyze.md +85 -75
- package/core/commands/qc-design-test.md +144 -25
- package/core/commands/qc-plan.md +40 -7
- package/core/commands/qc-review.md +74 -7
- package/core/commands/qc-run-test.md +21 -1
- package/core/commands/setup-ai-first.md +5 -5
- package/core/commands/update-framework.md +1 -1
- package/core/commands/validate-traces.md +1 -1
- package/core/modules/qc-playwright/stack-profile.yaml +3 -3
- package/core/rules/workflow.md +1 -1
- package/core/skills/qc/qa-analyst/DOC_GAP.template.md +47 -17
- package/core/skills/qc/qa-analyst/acceptance-criteria.md +1 -1
- package/core/skills/qc/qa-analyst/business-rules.md +2 -2
- package/core/skills/qc/qa-analyst/data-flow.md +2 -2
- package/core/skills/qc/qa-analyst/spec-breakdown.md +4 -4
- package/core/skills/qc/qa-analyst/spec-issue-reporter.md +14 -2
- package/core/skills/qc/qa-designer/api/auth-chain.md +155 -0
- package/core/skills/qc/qa-designer/api/auth-sequence.md +75 -0
- package/core/skills/qc/qa-designer/api/common-headers.md +61 -0
- package/core/skills/qc/qa-designer/api/crud-sequence.md +122 -0
- package/core/skills/qc/qa-designer/api/endpoint.md +231 -0
- package/core/skills/qc/qa-designer/api/http-status-codes.md +102 -0
- package/core/skills/qc/qa-designer/e2e/journey.md +13 -8
- package/core/skills/qc/qa-designer/exploratory/charter.md +2 -0
- package/core/skills/qc/qa-designer/exploratory/explore-to-functional.md +7 -4
- package/core/skills/qc/qa-designer/functional/api.md +87 -18
- package/core/skills/qc/qa-designer/functional/gui-feature.md +12 -9
- package/core/skills/qc/qa-designer/functional/gui-screen.md +12 -10
- package/core/skills/qc/qa-designer/integration/api.md +12 -5
- package/core/skills/qc/qa-designer/integration/db.md +12 -6
- package/core/skills/qc/qa-designer/integration/gui.md +12 -5
- package/core/skills/qc/qa-designer/integration/kafka.md +12 -5
- package/core/skills/qc/qa-designer/non-functional.md +12 -5
- package/core/skills/qc/qa-designer/shared/action-keywords-glossary.md +91 -0
- package/core/skills/qc/qa-designer/shared/duplicate-check-procedure.md +105 -0
- package/core/skills/qc/qa-designer/shared/implicit-scenarios.md +22 -0
- package/core/skills/qc/qa-designer/shared/precision-rules.md +198 -0
- package/core/skills/qc/qa-designer/shared/read-doc-gap-inputs.md +25 -0
- package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +93 -0
- package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +243 -0
- package/core/skills/qc/qa-planner/risk-model.md +1 -1
- package/core/skills/qc/qa-planner/test-plan.md +24 -13
- package/core/skills/qc/qa-reviewer/script/e2e.md +9 -1
- package/core/skills/qc/qa-reviewer/script/exploratory.md +9 -1
- package/core/skills/qc/qa-reviewer/script/functional.md +9 -1
- package/core/skills/qc/qa-reviewer/script/integration.md +9 -1
- package/core/skills/qc/qa-reviewer/script/non-functional.md +9 -1
- package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +26 -0
- package/core/skills/qc/qa-reviewer/shared/review-check-groups.md +207 -0
- package/core/skills/qc/qa-reviewer/shared/review-file-template.md +228 -0
- package/core/skills/qc/qa-reviewer/test-case/e2e.md +71 -13
- package/core/skills/qc/qa-reviewer/test-case/exploratory.md +53 -4
- package/core/skills/qc/qa-reviewer/test-case/functional.md +63 -15
- package/core/skills/qc/qa-reviewer/test-case/integration.md +64 -12
- package/core/skills/qc/qa-reviewer/test-case/non-functional.md +72 -13
- package/core/skills/qc/qa-runner/e2e.md +1 -1
- package/core/skills/qc/qa-runner/exploratory/session.md +1 -1
- package/core/steps/context-loader.md +1 -1
- package/core/steps/qc-scope.md +119 -0
- package/core/templates/project-context.yaml +3 -1
- package/docs/02-concepts/pipeline-steps/08-qc-automation.md +1 -1
- package/docs/02-concepts/pipeline-steps/09-validate-traces.md +1 -1
- package/docs/04-reference/configuration.md +146 -146
- package/docs/04-reference/trace-schema.md +1 -1
- package/docs/explain/00-setup-ai-first.md +1 -1
- package/docs/explain/15-qc-analyze.md +1 -1
- package/docs/explain/16-qc-plan.md +1 -1
- package/docs/explain/17-qc-design-test.md +1 -1
- package/docs/plans/qc-implementation-log.md +288 -5
- package/docs/plans/qc-sync-command.md +2 -1
- package/package.json +1 -1
- package/scripts/migrate-qc-docs.js +261 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
version: 1.0
|
|
3
|
-
updated: 2026-
|
|
3
|
+
updated: 2026-09-04
|
|
4
4
|
ported_from: ai-automation-qc-base
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -9,6 +9,9 @@ ported_from: ai-automation-qc-base
|
|
|
9
9
|
> Stage 3 của QC automation pipeline native (qc-analyze → qc-plan → qc-design-test → qc-review → qc-run-test → qc-report). Port từ qa-designer của team QC. Sinh test case Markdown (`.Test.md`) — Python đến sau ở /qc-run-test.
|
|
10
10
|
|
|
11
11
|
## Gate
|
|
12
|
+
|
|
13
|
+
*Checkpoint: **chặn thường** — lệnh ghi file test-case. `--yes` bỏ qua được (gate Bước 3a).*
|
|
14
|
+
|
|
12
15
|
# Gate — Quy trình vào chuẩn cho mọi lệnh
|
|
13
16
|
|
|
14
17
|
Mọi lệnh PHẢI chạy gate này trước khi thực thi phần logic riêng của nó.
|
|
@@ -162,7 +165,7 @@ Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader
|
|
|
162
165
|
🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
|
|
163
166
|
|
|
164
167
|
|
|
165
|
-
*Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID.
|
|
168
|
+
*Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID. Đọc output của qc-analyze + qc-plan (`REQUIREMENT_ANALYSIS.md`, `DOC_GAP.md`, `TEST_PLAN.md`) từ `{qc_artifact_dir}` — **cả ba đều ở cấp PRD, lọc theo cột `UC`** để lấy phần của UC này — và file `.feature` của đúng platform đó (với `@trace.scenario` mỗi scenario). Với layer GUI, cũng đọc bảng **Test Selectors** §4.5.6 (block platform) của tech-doc gộp tại `{paths.tech_docs_dir}/{domain}/{prd-slug}/tech-docs/{TICKET-ID}-tech-design.md` (nếu có — bảng gộp mọi UC của platform, **lọc theo cột "Serves SC" khớp SC của UC này**) — các test-id ổn định mà QC sẽ định vị theo.*
|
|
166
169
|
|
|
167
170
|
## Context
|
|
168
171
|
**BẮT BUỘC — đọc `.agent/steps/context-loader.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
@@ -172,6 +175,76 @@ Bỏ qua bước này thì `{paths.*}`, `{tech_stack.*}`, `{conventions.*}`, gua
|
|
|
172
175
|
`project-lessons`, và routing service (chế độ umbrella) đều **chưa được phân giải** — mọi
|
|
173
176
|
placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
|
|
174
177
|
|
|
178
|
+
## Phạm vi QC
|
|
179
|
+
|
|
180
|
+
**BẮT BUỘC — đọc `.agent/steps/qc-scope.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
181
|
+
rồi mới tiếp tục phần bên dưới.
|
|
182
|
+
|
|
183
|
+
Nó chốt bốn thứ mà mọi trạm QC đều cần: `TICKET-ID` · `active_platform` ·
|
|
184
|
+
`qc_artifact_dir` · `uc_list` (kèm trạng thái BDD từng UC, và cờ `--include-draft`).
|
|
185
|
+
Bỏ qua thì artifact QC ghi vào **sai thư mục** và `qc_status` ghi vào **sai sổ trace** —
|
|
186
|
+
cả hai đều xảy ra trong im lặng, không có bước nào phía sau bắt được.
|
|
187
|
+
|
|
188
|
+
> **Trạm này vẫn gọi theo TỪNG UC** *(B11)* — thiết kế và chạy test **thật sự** làm tăng dần
|
|
189
|
+
> theo UC, nên giữ khả năng làm UC1 khi UC3 chưa xong là đúng. Chỉ **chỗ đọc/ghi** đổi: mọi
|
|
190
|
+
> artifact nằm chung ở `{qc_artifact_dir}` cấp PRD, không còn một thư mục mỗi UC.
|
|
191
|
+
>
|
|
192
|
+
> Nên `DOC_GAP.md` / `TEST_PLAN.md` đọc được ở đây phủ **cả PRD**: **lọc theo cột `UC`** để lấy
|
|
193
|
+
> phần của UC đang làm. Đừng coi toàn bộ bảng gap là của UC này — sẽ chặn oan.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Cờ — chọn tầng nào, tách mịn đến đâu
|
|
198
|
+
|
|
199
|
+
| Cờ | Ghi file | Nhóm |
|
|
200
|
+
|---|---|---|
|
|
201
|
+
| *(không cờ)* | `TC_<FEATURE>.Test.md` | 1 GUI · 2 Validation · 3 Functional · 4 Integration (qua UI) · 5 NFR · 6 E2E |
|
|
202
|
+
| `--api` | `TC_<FEATURE>_API.Test.md` | 1 Endpoint · 2 Integration API/DB/Kafka |
|
|
203
|
+
| `--all` | **cả hai file** | như trên, hai file riêng biệt |
|
|
204
|
+
| `--atomic-max` | — | bật chế độ tách tối đa (xem dưới) |
|
|
205
|
+
|
|
206
|
+
**Câu hỏi phân file:** *"TC này verify được mà **không cần UI** không?"* → **có** = file API ·
|
|
207
|
+
**không** = file giao diện. Đây đúng là Bước 2 của
|
|
208
|
+
`{paths.qc_skills_dir}/qa-designer/shared/skill-decision-tree.md`.
|
|
209
|
+
|
|
210
|
+
> **Vì sao hai file riêng chứ không một file rồi ghi từng nhóm** *(B12)*. `--api` chạy sau khi
|
|
211
|
+
> file giao diện đã tồn tại là chuyện thường. Nếu chung một file, lần chạy `--api` phải **giữ
|
|
212
|
+
> nguyên** năm nhóm kia — mà viết-lại-cả-file là đúng thứ agent hay làm. Hai file thì hai chế
|
|
213
|
+
> độ **không bao giờ chạm nhau**, và không cần tin vào việc agent nhớ giữ phần cũ.
|
|
214
|
+
|
|
215
|
+
### `--atomic-max` — tách tới mức nhỏ nhất
|
|
216
|
+
|
|
217
|
+
Mặc định đã là ATOMIC (mỗi TC đúng một kết cục), nhưng **cho phép** bullet compound khi cả hai
|
|
218
|
+
vế nói về **cùng một** kết cục — ví dụ *"form hiển thị đủ 3 trường"* vẫn là 1 TC.
|
|
219
|
+
|
|
220
|
+
`--atomic-max` **nổ danh sách completeness thành từng thành phần**: thẻ hiển thị đủ 5 thông tin
|
|
221
|
+
→ **5 TC**. Ở đội QC, một tính năng đi từ 82 lên 130 TC.
|
|
222
|
+
|
|
223
|
+
**⛔ Thủ tục bắt buộc TRƯỚC khi ghi** *(theo `shared/precision-rules.md` §2.1)*:
|
|
224
|
+
|
|
225
|
+
1. **Chốt ranh giới completeness** — hai mức có quy mô rất khác nhau:
|
|
226
|
+
| Giá trị | Nghĩa |
|
|
227
|
+
|---|---|
|
|
228
|
+
| `--atomic-max=keep-completeness` | giữ danh sách completeness là 1 TC (~95 TC ở ví dụ thật) |
|
|
229
|
+
| `--atomic-max=explode` | nổ từng thành phần (~130 TC) |
|
|
230
|
+
|
|
231
|
+
Không nêu giá trị → **HỎI** trước khi ghi, vì đây là quyết định quy mô của người chủ, không
|
|
232
|
+
phải của agent. **Có `--yes`:** không hỏi — **DỪNG** với lỗi rõ ràng:
|
|
233
|
+
```
|
|
234
|
+
❌ --atomic-max cần nêu ranh giới ở chế độ headless (quy mô chênh ~35%).
|
|
235
|
+
Chạy: /qc-design-test {UC-ID} --atomic-max=explode --yes
|
|
236
|
+
hoặc --atomic-max=keep-completeness --yes
|
|
237
|
+
```
|
|
238
|
+
*(Một cổng chỉ chặn được khi có người ngồi đó thì ở chế độ headless nó không phải cổng, nó
|
|
239
|
+
là treo — cùng bài học với `steps/qc-scope.md` §2.)*
|
|
240
|
+
|
|
241
|
+
2. **Dựng bản đồ tách trước khi ghi** — mỗi TC cha tách ra mấy mảnh. Đừng để agent con tự suy
|
|
242
|
+
trong lúc ghi; đó là chỗ sinh ra TC cắt cụt.
|
|
243
|
+
3. **GIỮ 1 TC** cho bốn loại này kể cả ở chế độ tối đa: *predicate đa-điều-kiện định-nghĩa-một-
|
|
244
|
+
khái-niệm* · *ngưỡng* (`≥44pt`, `WCAG AA ≥4.5:1`) · *exclusivity* chọn-một · *qualifier*.
|
|
245
|
+
4. **Verify bằng DIFF, không tin lời đếm của agent** — ID liên tục · mỗi Expected 1 bullet ·
|
|
246
|
+
0 ký tự `|` · Trace matrix không còn ID chết · P0/P1 khớp tag.
|
|
247
|
+
|
|
175
248
|
---
|
|
176
249
|
|
|
177
250
|
## Role
|
|
@@ -180,38 +253,78 @@ Bạn là **QC Designer** — stage 3. Sinh/bảo trì các file test-case Markd
|
|
|
180
253
|
(`.Test.md`) từ requirement đã phân tích + plan. Output feed vào qc-run-test (Python) và
|
|
181
254
|
qc-review. Bạn **không** viết Python.
|
|
182
255
|
|
|
183
|
-
## Skills
|
|
256
|
+
## Skills (`{paths.qc_skills_dir}/qa-designer/`)
|
|
257
|
+
|
|
258
|
+
**Luật dùng chung — nạp theo tầng, không nạp hết mỗi lần:**
|
|
184
259
|
|
|
185
|
-
|
|
|
260
|
+
| Khi nào | Nạp |
|
|
186
261
|
|---|---|
|
|
187
|
-
|
|
|
188
|
-
|
|
|
189
|
-
|
|
|
190
|
-
|
|
|
191
|
-
|
|
|
192
|
-
|
|
|
193
|
-
|
|
|
262
|
+
| **Luôn** | `shared/tc-metadata-format.md` — khuôn TC · luật ATOMIC · phân nhóm · hai file `.Test.md` · Trace · `🚫 Block` · `Test-ID attribute` |
|
|
263
|
+
| **Luôn** | `shared/precision-rules.md` — cấm 9 cụm mơ hồ · đơn vị theo domain · toán tử · BVA 3-hay-4 giá trị · phủ đủ ô decision table · 3 mức teardown |
|
|
264
|
+
| **Luôn** | `shared/action-keywords-glossary.md` — một hành động một từ (Click/Tap/Enter/Select…) |
|
|
265
|
+
| **Luôn** | `shared/implicit-scenarios.md` — 7 tình huống bắt buộc nghĩ tới, áp cho mọi nhóm |
|
|
266
|
+
| Đầu phiên, một lần | `shared/read-doc-gap-inputs.md` — đọc **đủ** mọi file trong bảng *Tài liệu đầu vào đã đọc* của `DOC_GAP.md`, không chỉ đọc bản tóm tắt gap |
|
|
267
|
+
| Không chắc chọn tầng nào | `shared/skill-decision-tree.md` — cây quyết định UI / Integration-GUI / E2E / Integration |
|
|
268
|
+
| Thêm TC vào file đã có | `shared/duplicate-check-procedure.md` — grep trước khi viết; và **trùng chéo UC** giờ mới thực sự xảy ra vì mọi UC dùng chung một thư mục |
|
|
269
|
+
| `--api` / `--all` | `api/endpoint.md` · `api/auth-chain.md` · `api/http-status-codes.md` · `api/common-headers.md` · `api/crud-sequence.md` · `api/auth-sequence.md` |
|
|
270
|
+
|
|
271
|
+
**Rồi chọn tầng, nạp MỘT file:**
|
|
272
|
+
|
|
273
|
+
| Layer | File | Ghi vào |
|
|
274
|
+
|---|---|---|
|
|
275
|
+
| 1 màn hình | `functional/gui-screen.md` | file giao diện |
|
|
276
|
+
| Feature đa-màn | `functional/gui-feature.md` | file giao diện |
|
|
277
|
+
| API endpoint | `functional/api.md` | **file API** |
|
|
278
|
+
| Integration qua UI | `integration/gui.md` | file giao diện |
|
|
279
|
+
| Integration API/DB/Kafka | `integration/{api,db,kafka}.md` | **file API** |
|
|
280
|
+
| End-to-end journey | `e2e/journey.md` | file giao diện |
|
|
281
|
+
| Non-functional | `non-functional.md` | theo câu hỏi phân file |
|
|
282
|
+
| Exploratory | `exploratory/{charter,explore-to-functional}.md` | file giao diện |
|
|
194
283
|
|
|
195
284
|
## Conventions
|
|
196
285
|
|
|
286
|
+
*Khuôn TC, luật ATOMIC, phân nhóm, không-dùng-bảng, Trace, `🚫 Block`, `Test-ID attribute` —
|
|
287
|
+
đều ở `shared/tc-metadata-format.md`. **Đừng lặp lại ở đây.** Dưới đây chỉ là thứ riêng của trạm:*
|
|
288
|
+
|
|
197
289
|
- Markdown-first; đừng design khi requirement chưa rõ — đẩy ngược về qc-plan/qc-analyze.
|
|
198
|
-
- TC ID `TC_<FEATURE>_<NNN>`; tách happy/negative; mỗi TC một mối quan tâm assertion; giá trị expected cụ thể.
|
|
199
|
-
- Priority `P0/P1/P2`; Tags (`smoke regression happy-path negative ui …`); Status `Draft → In Progress → Pass/Fail/Skip`.
|
|
200
|
-
- Một TC bị block bởi gap vẫn được viết + đánh dấu `🚫 Block: GAP-xx`.
|
|
201
290
|
- **Tham chiếu test-id, không phải gợi ý hình ảnh.** Với mỗi step GUI tác động lên một element, trích test-id ổn định từ bảng §4.5.6 của tech-doc gộp (vd "click `ft001-login-submit-btn`") để qc-run-test dựng locator từ contract. Nếu một element có action không có test-id trong §4.5.6, ghi chú lại (qc-run-test sẽ fallback về locator role/text chậm hơn).
|
|
202
|
-
-
|
|
203
|
-
-
|
|
291
|
+
- **Đọc `@trace.testid_attr` từ header tech-doc gộp** (do `/map-testids` ghi) và ghi lại một
|
|
292
|
+
dòng `Test-ID attribute: {attr}` ở metadata đầu file `.Test.md`. §4.5.6 chỉ cho **giá trị**
|
|
293
|
+
test-id; `@trace.testid_attr` là **tên thuộc tính** chứa chúng — `/qc-run-test` cần nó để cấu
|
|
294
|
+
hình locator, `/qc-review` cần nó để biết selector trong script có đúng contract không.
|
|
295
|
+
Không đọc được `@trace.testid_attr` → ghi
|
|
296
|
+
`Test-ID attribute: — (thiếu @trace.testid_attr, chạy /map-testids)`; **đừng bỏ trống, đừng
|
|
297
|
+
tự đoán theo platform** — đoán sai thì mọi locator trượt 100%, vì một lý do không liên quan
|
|
298
|
+
gì tới thứ đang được test. *(Dạng dòng metadata: `shared/tc-metadata-format.md`.)*
|
|
299
|
+
- Một TC bị block bởi gap **vẫn viết đủ** + `🚫 Block: [GAP-UC{N}-{nnn}](../DOC_GAP.md) — lý do`.
|
|
300
|
+
Chặn theo **UC ở cột `UC` của hàng gap đó**, không chặn cả PRD.
|
|
204
301
|
|
|
205
302
|
## Trace mapping (bắt buộc)
|
|
206
303
|
|
|
207
|
-
Ngoài trace `BR-xx`, mỗi TC ghi scenario framework mà nó verify
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
304
|
+
Ngoài trace `BR-xx`, mỗi TC ghi scenario framework mà nó verify — **dạng trường danh sách,
|
|
305
|
+
không phải cột bảng** (file TC không có ký tự `|`):
|
|
306
|
+
|
|
307
|
+
```
|
|
308
|
+
- **@trace.verifies:** {UC-ID}-SC{N}
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
Lấy từ `@trace.scenario` của `.feature`. Một SC map được nhiều TC. Đây là **join key** cho phép
|
|
312
|
+
qc-run-test ghi `qc_status` theo từng scenario vào sổ trace — **thiếu nó thì test vẫn chạy,
|
|
313
|
+
vẫn pass/fail, nhưng kết quả không vào được sổ và không ai biết nó phủ kịch bản nào.**
|
|
314
|
+
|
|
315
|
+
Cuối file: **Trace matrix** (BR ↔ TC ↔ SC) + **danh sách TC bị block** — cả hai dạng danh sách.
|
|
211
316
|
|
|
212
317
|
## Output
|
|
213
318
|
|
|
214
|
-
Ghi
|
|
319
|
+
Ghi dưới `{qc_artifact_dir}test-cases/`
|
|
320
|
+
(= `{paths.qc_dir}/{TICKET-ID}/{active_platform}/test-cases/`) — **một thư mục dùng chung cho cả
|
|
321
|
+
PRD**. Tên file mang `<FEATURE>` nên các UC không đâm nhau; `@trace.verifies` là chỗ phân biệt
|
|
322
|
+
TC thuộc UC nào.
|
|
323
|
+
|
|
324
|
+
**Đuôi bắt buộc là `.Test.md`.** `/qc-run-test` và `/qc-review` tìm `*.Test.md`; ghi ra
|
|
325
|
+
`TC_<FEATURE>.md` là ghi ra thứ **không trạm nào tìm thấy**, và **không có gì báo lỗi**.
|
|
326
|
+
|
|
327
|
+
`🚫 Block` trỏ `../DOC_GAP.md` — lên một cấp, vì file gap ở thư mục cha của `test-cases/`.
|
|
215
328
|
|
|
216
329
|
## Report
|
|
217
330
|
|
|
@@ -219,8 +332,14 @@ Ghi các file `.Test.md` dưới `{paths.qc_dir}/{UC-ID}/{active_platform}/test-
|
|
|
219
332
|
Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
|
|
220
333
|
|
|
221
334
|
```
|
|
222
|
-
/qc-design-test Hoàn tất — {UC-ID}
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
335
|
+
/qc-design-test Hoàn tất — {UC-ID} ({active_platform})
|
|
336
|
+
Chế độ: {giao diện | API | cả hai}{nếu --atomic-max: " · tách tối đa ({explode|keep-completeness})"}
|
|
337
|
+
Files: {qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md — {n} TC
|
|
338
|
+
{nếu có: "…_API.Test.md — {m} TC"}
|
|
339
|
+
Nhóm : GUI {a} · Validation {b} · Functional {c} · Integration {d} · NFR {e} · E2E {f}
|
|
340
|
+
{nếu file API: "Endpoint {g} · Integration API/DB/Kafka {h}"}
|
|
341
|
+
Trùng: {k} TC bỏ vì trùng ({j} trùng chéo UC — trỏ trace về UC nguồn thay vì viết lại)
|
|
342
|
+
Block: {blocked} TC bị chặn bởi gap — theo UC: {UC1: n · UC2: n}
|
|
343
|
+
Trace: {N} TC map tới {K}/{total} scenario của {UC-ID}
|
|
344
|
+
Next : /qc-review {UC-ID} ← review test case trước khi sinh script
|
|
226
345
|
```
|
package/core/commands/qc-plan.md
CHANGED
|
@@ -162,7 +162,7 @@ Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader
|
|
|
162
162
|
🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
|
|
163
163
|
|
|
164
164
|
|
|
165
|
-
*Lưu ý: Với lệnh này, target ở Bước 1 là một
|
|
165
|
+
*Lưu ý: Với lệnh này, target ở Bước 1 là một **TICKET-ID** (mã PRD) — hoặc UC-ID / file feature, cả hai quy về TICKET-ID ở §Phạm vi QC. Đọc output của qc-analyze (`REQUIREMENT_ANALYSIS.md` + `DOC_GAP.md`) từ `{qc_artifact_dir}` và file `.feature` của đúng nền đó.*
|
|
166
166
|
|
|
167
167
|
## Context
|
|
168
168
|
**BẮT BUỘC — đọc `.agent/steps/context-loader.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
@@ -174,6 +174,27 @@ placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
|
|
|
174
174
|
|
|
175
175
|
---
|
|
176
176
|
|
|
177
|
+
## Phạm vi QC
|
|
178
|
+
|
|
179
|
+
**BẮT BUỘC — đọc `.agent/steps/qc-scope.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
180
|
+
rồi mới tiếp tục phần bên dưới.
|
|
181
|
+
|
|
182
|
+
Nó chốt bốn thứ mà mọi trạm QC đều cần: `TICKET-ID` · `active_platform` ·
|
|
183
|
+
`qc_artifact_dir` · `uc_list` (kèm trạng thái BDD từng UC, và cờ `--include-draft`).
|
|
184
|
+
Bỏ qua thì artifact QC ghi vào **sai thư mục** và `qc_status` ghi vào **sai sổ trace** —
|
|
185
|
+
cả hai đều xảy ra trong im lặng, không có bước nào phía sau bắt được.
|
|
186
|
+
|
|
187
|
+
> **Trạm này chạy CẢ PRD, đúng như trạm 1** *(B11)* — một `TEST_PLAN.md` cho mỗi (PRD × nền).
|
|
188
|
+
> `qa-planner/test-plan.md` vốn viết *"Test Plan cho một **feature**"* và template của nó là
|
|
189
|
+
> `# Test Plan – <Feature>` với metadata `Feature / Project / Module`: đây là quay về đúng
|
|
190
|
+
> tầng mà skill gốc được viết cho.
|
|
191
|
+
>
|
|
192
|
+
> `uc_list` ở đây **phải khớp** bảng *Phạm vi phân tích* trong `DOC_GAP.md`. Lệch nhau nghĩa là
|
|
193
|
+
> BDD đã đổi trạng thái sau lần chạy trạm 1 → nêu ra và khuyên chạy lại `/qc-analyze`, đừng
|
|
194
|
+
> âm thầm lập plan cho một tập UC khác với tập đã phân tích.
|
|
195
|
+
|
|
196
|
+
---
|
|
197
|
+
|
|
177
198
|
## Role
|
|
178
199
|
|
|
179
200
|
Bạn là **QC Planner** — stage 2. Từ output của qc-analyze, tạo TEST PLAN:
|
|
@@ -192,9 +213,18 @@ thiết kế test case cụ thể (đó là qc-design-test).
|
|
|
192
213
|
|
|
193
214
|
## Output
|
|
194
215
|
|
|
195
|
-
Ghi test plan vào `{
|
|
196
|
-
|
|
197
|
-
|
|
216
|
+
Ghi **đúng MỘT** test plan cho cả PRD vào `{qc_artifact_dir}TEST_PLAN.md`
|
|
217
|
+
(= `{paths.qc_dir}/{TICKET-ID}/{active_platform}/TEST_PLAN.md`). Giới hạn plan trong các
|
|
218
|
+
scenario của **các UC trong phạm vi** (`{UC-ID}-SC{N}` từ `.feature` của nền này) để
|
|
219
|
+
qc-design-test thiết kế case theo từng scenario.
|
|
220
|
+
|
|
221
|
+
Bắt buộc:
|
|
222
|
+
- **Bảng `§3 Test items` có cột `UC`** — một plan giờ phủ nhiều UC, không có cột đó thì không
|
|
223
|
+
ai biết vùng test nào thuộc UC nào.
|
|
224
|
+
- **`§2 Phạm vi`** liệt kê rõ UC `⏸ Chưa xét` ở phần *Out of scope*, kèm lý do (BDD chưa
|
|
225
|
+
approved). *Không có dòng này thì một UC bị bỏ trông giống một UC không có gì để test.*
|
|
226
|
+
- **`§5 Entry criteria` chặn theo từng UC**, không chặn cả PRD: gap 🔴 Blocker ở UC3 không
|
|
227
|
+
dừng việc thiết kế test cho UC1. Ghi `Ready` / `Blocked` cho **mỗi** UC.
|
|
198
228
|
|
|
199
229
|
## Report
|
|
200
230
|
|
|
@@ -202,8 +232,11 @@ case theo từng scenario.
|
|
|
202
232
|
Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
|
|
203
233
|
|
|
204
234
|
```
|
|
205
|
-
/qc-plan Hoàn tất — {
|
|
235
|
+
/qc-plan Hoàn tất — {TICKET-ID} ({active_platform})
|
|
236
|
+
Phạm vi: {n} UC trong plan{nếu có: " · ⏸ {m} chưa xét"}
|
|
206
237
|
Plan: {risks} rủi ro · {questions} câu hỏi mở cho dev · layers: {list}
|
|
207
|
-
|
|
208
|
-
|
|
238
|
+
File: {paths.qc_dir}/{TICKET-ID}/{active_platform}/TEST_PLAN.md
|
|
239
|
+
Sẵn sàng: {danh sách UC Ready} | Chặn: {danh sách UC Blocked + GAP-ID chặn nó}
|
|
240
|
+
Next: /qc-design-test {UC-ID} ← thiết kế test case, chạy cho từng UC đã Ready
|
|
241
|
+
(gửi questions-for-dev cho PO/Dev cho các UC còn Blocked)
|
|
209
242
|
```
|
|
@@ -162,7 +162,7 @@ Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader
|
|
|
162
162
|
🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
|
|
163
163
|
|
|
164
164
|
|
|
165
|
-
*Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID
|
|
165
|
+
*Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID (`active_platform` + `qc_artifact_dir` do §Phạm vi QC phân giải). Phát hiện review mode từ `$ARGUMENTS`/context: review test-case `.Test.md` (sau design) hoặc review Python script (sau run). Đọc artifact từ `{qc_artifact_dir}` và source test/page-object đã sinh.*
|
|
166
166
|
|
|
167
167
|
## Context
|
|
168
168
|
**BẮT BUỘC — đọc `.agent/steps/context-loader.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
@@ -172,6 +172,26 @@ Bỏ qua bước này thì `{paths.*}`, `{tech_stack.*}`, `{conventions.*}`, gua
|
|
|
172
172
|
`project-lessons`, và routing service (chế độ umbrella) đều **chưa được phân giải** — mọi
|
|
173
173
|
placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
|
|
174
174
|
|
|
175
|
+
## Phạm vi QC
|
|
176
|
+
|
|
177
|
+
**BẮT BUỘC — đọc `.agent/steps/qc-scope.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
178
|
+
rồi mới tiếp tục phần bên dưới.
|
|
179
|
+
|
|
180
|
+
Nó chốt bốn thứ mà mọi trạm QC đều cần: `TICKET-ID` · `active_platform` ·
|
|
181
|
+
`qc_artifact_dir` · `uc_list` (kèm trạng thái BDD từng UC, và cờ `--include-draft`).
|
|
182
|
+
Bỏ qua thì artifact QC ghi vào **sai thư mục** và `qc_status` ghi vào **sai sổ trace** —
|
|
183
|
+
cả hai đều xảy ra trong im lặng, không có bước nào phía sau bắt được.
|
|
184
|
+
|
|
185
|
+
> **Trạm này vẫn gọi theo TỪNG UC** *(B11)* — thiết kế và chạy test **thật sự** làm tăng dần
|
|
186
|
+
> theo UC, nên giữ khả năng làm UC1 khi UC3 chưa xong là đúng. Chỉ **chỗ đọc/ghi** đổi: mọi
|
|
187
|
+
> artifact nằm chung ở `{qc_artifact_dir}` cấp PRD, không còn một thư mục mỗi UC.
|
|
188
|
+
>
|
|
189
|
+
> Nên `DOC_GAP.md` / `TEST_PLAN.md` đọc được ở đây phủ **cả PRD**: **lọc theo cột `UC`** để lấy
|
|
190
|
+
> phần của UC đang làm. Đừng coi toàn bộ bảng gap là của UC này — sẽ chặn oan.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
|
|
175
195
|
---
|
|
176
196
|
|
|
177
197
|
## Role
|
|
@@ -185,16 +205,61 @@ tồn tại cho UC và mới hơn → review script. Nếu mơ hồ, hỏi.
|
|
|
185
205
|
|
|
186
206
|
## Skills (`{paths.qc_skills_dir}/qa-reviewer/`)
|
|
187
207
|
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
208
|
+
**Nạp trước — nhưng đúng vai:**
|
|
209
|
+
|
|
210
|
+
| File | Vai nào | Cho gì |
|
|
211
|
+
|---|---|---|
|
|
212
|
+
| `shared/read-doc-gap-inputs.md` | **cả hai** | Nạp **đủ** mọi tài liệu nguồn theo bảng *Tài liệu đầu vào đã đọc* của `DOC_GAP.md` — soát mù thì kết luận "0 lỗi" là vô nghĩa |
|
|
213
|
+
| `shared/review-file-template.md` | **cả hai** | Khuôn file kết quả · thang điểm `XX/100` · luật ghi file · nguyên tắc *mặc định hoài nghi* |
|
|
214
|
+
| ↳ §*Kiểm tra cấu trúc TC* của file đó | **chỉ vai 1** | Tầng kiểm các luật của trạm 3: ATOMIC 1-bullet · không ký tự `\|` · cụm từ mơ hồ · teardown đúng chỗ · marker ≠ oracle |
|
|
215
|
+
| `shared/review-check-groups.md` | **chỉ vai 1** | **7 nhóm kiểm tra** chạy tuần tự · registry 46 nhãn lỗi · **7 mẫu-hay-thiếu** của Nhóm 6 · nền tảng ISTQB · anti-pattern |
|
|
216
|
+
|
|
217
|
+
> ⚠️ **Vai 2 (soát code) KHÔNG nạp 7 nhóm kiểm tra.** Chúng kiểm **cấu trúc file test case** —
|
|
218
|
+
> áp vào file Python là bảo reviewer đi tìm `#### Expected Result` trong một Page Object, rồi
|
|
219
|
+
> gắn nhãn lỗi cho thứ đáng lẽ không có ở đó. Vai 2 dùng bộ tiêu chí riêng ở `script/*.md`.
|
|
220
|
+
|
|
221
|
+
**Rồi chọn theo vai + tầng, nạp MỘT file:**
|
|
222
|
+
- Soát test-case: `test-case/{functional,e2e,integration,non-functional,exploratory}.md`
|
|
223
|
+
- Soát script: `script/{functional,e2e,integration,non-functional,exploratory}.md`
|
|
191
224
|
|
|
192
225
|
## Review focus
|
|
193
226
|
|
|
194
227
|
- **Test-case:** mọi `{UC-ID}-SC{N}` đã phủ? happy + negative + boundary? expected cụ thể? trace (`BR-xx` + `@trace.verifies` SC) có mặt? không có TC orphan?
|
|
195
228
|
- **Script:** khớp `.Test.md` 1-1? Page Object 3 lớp + BasePage gọn? `expect()` không phải bare assert? không hard-code URL/cred/timeout, không `time.sleep`, không Allure? selector theo priority (data-testid→role→…)? 100% TC đã script (không còn Draft)?
|
|
196
229
|
|
|
197
|
-
Sinh findings (
|
|
230
|
+
Sinh findings (mức độ + vị trí + cách sửa), chấm điểm, ra verdict.
|
|
231
|
+
|
|
232
|
+
**KHÔNG tự sửa** file TC hay code. Chỉ nhận xét và chấm điểm — người sửa là `/qc-design-test`
|
|
233
|
+
(vai 1) hoặc `/qc-run-test` (vai 2). *Reviewer tự sửa rồi tự duyệt là bỏ mất cái cổng.*
|
|
234
|
+
|
|
235
|
+
## Output
|
|
236
|
+
|
|
237
|
+
Ghi vào **`{qc_artifact_dir}test-cases/REVIEW_<FEATURE>.md`** — đứng **cạnh** file TC vừa soát:
|
|
238
|
+
|
|
239
|
+
```
|
|
240
|
+
{qc_artifact_dir}test-cases/
|
|
241
|
+
├── TC_<FEATURE>.Test.md
|
|
242
|
+
├── REVIEW_<FEATURE>.md ← soát file trên
|
|
243
|
+
├── TC_<FEATURE>_API.Test.md
|
|
244
|
+
└── REVIEW_<FEATURE>_API.md ← soát file trên
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
⚠️ **Tên file review KHÔNG có đuôi `.Test.md`.** Đuôi đó là của file test case; gắn vào file
|
|
248
|
+
review sẽ làm `/qc-run-test` nhặt nó lên như một file test case rồi cố sinh script từ một bảng điểm.
|
|
249
|
+
|
|
250
|
+
Khuôn đầy đủ + quy tắc ghi: `shared/review-file-template.md`. Ba điều bắt buộc:
|
|
251
|
+
|
|
252
|
+
- **Điểm `XX/100`** — trừ 5đ mỗi `FAIL`, 2đ mỗi `WARN`. Verdict **suy ra được**:
|
|
253
|
+
`≥80` VÀ không còn `FAIL` chặn → `APPROVED`; ngược lại `NEEDS_FIX`.
|
|
254
|
+
- **Bảng Tổng quan THÊM một hàng mỗi vòng**, không ghi đè — đó là cách duy nhất thấy được điểm
|
|
255
|
+
có tăng không. Các bảng chi tiết thì ghi đè phần của tầng mình.
|
|
256
|
+
- **Hai vai ghi vào CÙNG một file**, phân biệt bằng cột `Tầng`. Chúng cách nhau một trạm, nên
|
|
257
|
+
hàng của vai sau **không được ghi đè** hàng của vai trước.
|
|
258
|
+
|
|
259
|
+
> **Vì sao cổng này phải ghi ra file** *(B13)*. Trước đây lệnh chỉ nói *"sinh findings"* — không
|
|
260
|
+
> nói ghi đâu, dạng gì, và điểm là `A/B/C/D` **không có luật chấm**. Hệ quả: hai người soát ra
|
|
261
|
+
> hai kết quả, và **vòng 2 không so được với vòng 1** — tức không ai biết sửa xong có tốt lên
|
|
262
|
+
> không. Một cổng không để lại dấu vết đo được thì không phải cổng, nó là một lượt đọc.
|
|
198
263
|
|
|
199
264
|
## Report
|
|
200
265
|
|
|
@@ -202,8 +267,10 @@ Sinh findings (severity + vị trí + fix). Verdict APPROVED hoặc NEEDS_FIX.
|
|
|
202
267
|
Output Artifacts · Next) cho report cuối, kèm khối bên dưới.
|
|
203
268
|
|
|
204
269
|
```
|
|
205
|
-
/qc-review Hoàn tất — {UC-ID} ({test-case | script}
|
|
206
|
-
|
|
270
|
+
/qc-review Hoàn tất — {UC-ID} ({soát test-case | soát script}) vòng #{N}
|
|
271
|
+
Điểm : {XX}/100 ({fail} FAIL × −5đ · {warn} WARN × −2đ){nếu có vòng trước: " ← vòng #{N-1}: {YY}/100"}
|
|
272
|
+
Verdict: {APPROVED | NEEDS_FIX} — {n} findings ({crit} chặn)
|
|
273
|
+
File : {qc_artifact_dir}test-cases/REVIEW_<FEATURE>.md (thêm 1 hàng vào bảng Tổng quan)
|
|
207
274
|
Next (test-case APPROVED): /qc-run-test {UC-ID}
|
|
208
275
|
Next (script APPROVED) : /qc-report {UC-ID} rồi tạo PR
|
|
209
276
|
(NEEDS_FIX → fix artifact bị gắn cờ, rồi chạy lại /qc-review {UC-ID})
|
|
@@ -162,7 +162,7 @@ Mỗi dòng ⚠️/🔴 phải ứng với một trạng thái **context-loader
|
|
|
162
162
|
🔴/⚠️ (không chặn ≠ không báo — người đọc log sau này vẫn cần thấy).
|
|
163
163
|
|
|
164
164
|
|
|
165
|
-
*Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID
|
|
165
|
+
*Lưu ý: Với lệnh này, target ở Bước 1 là một UC-ID (`active_platform` + `qc_artifact_dir` do §Phạm vi QC phân giải). `active_platform` này CHÍNH LÀ platform của sổ trace sẽ ghi `qc_status` (`{UC-ID}-{active_platform}.tsv`) — nên `@trace.verifies={UC-ID}-SC{N}` resolve không nhập nhằng. Đọc `.Test.md` đã review từ `{qc_artifact_dir}test-cases/`. Lệnh này dùng stack module **qc-playwright** (`.agent/modules/qc-playwright/stack-profile.yaml`) — Python + pytest-playwright + Page Object — độc lập với module implementation của dev.*
|
|
166
166
|
|
|
167
167
|
## Context
|
|
168
168
|
**BẮT BUỘC — đọc `.agent/steps/context-loader.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
@@ -172,6 +172,26 @@ Bỏ qua bước này thì `{paths.*}`, `{tech_stack.*}`, `{conventions.*}`, gua
|
|
|
172
172
|
`project-lessons`, và routing service (chế độ umbrella) đều **chưa được phân giải** — mọi
|
|
173
173
|
placeholder bên dưới sẽ rỗng và lệnh sẽ đọc/ghi sai chỗ.
|
|
174
174
|
|
|
175
|
+
## Phạm vi QC
|
|
176
|
+
|
|
177
|
+
**BẮT BUỘC — đọc `.agent/steps/qc-scope.md` và thực thi TOÀN BỘ quy trình trong đó**,
|
|
178
|
+
rồi mới tiếp tục phần bên dưới.
|
|
179
|
+
|
|
180
|
+
Nó chốt bốn thứ mà mọi trạm QC đều cần: `TICKET-ID` · `active_platform` ·
|
|
181
|
+
`qc_artifact_dir` · `uc_list` (kèm trạng thái BDD từng UC, và cờ `--include-draft`).
|
|
182
|
+
Bỏ qua thì artifact QC ghi vào **sai thư mục** và `qc_status` ghi vào **sai sổ trace** —
|
|
183
|
+
cả hai đều xảy ra trong im lặng, không có bước nào phía sau bắt được.
|
|
184
|
+
|
|
185
|
+
> **Trạm này vẫn gọi theo TỪNG UC** *(B11)* — thiết kế và chạy test **thật sự** làm tăng dần
|
|
186
|
+
> theo UC, nên giữ khả năng làm UC1 khi UC3 chưa xong là đúng. Chỉ **chỗ đọc/ghi** đổi: mọi
|
|
187
|
+
> artifact nằm chung ở `{qc_artifact_dir}` cấp PRD, không còn một thư mục mỗi UC.
|
|
188
|
+
>
|
|
189
|
+
> Nên `DOC_GAP.md` / `TEST_PLAN.md` đọc được ở đây phủ **cả PRD**: **lọc theo cột `UC`** để lấy
|
|
190
|
+
> phần của UC đang làm. Đừng coi toàn bộ bảng gap là của UC này — sẽ chặn oan.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
|
|
175
195
|
---
|
|
176
196
|
|
|
177
197
|
## Role & stack (theo module qc-playwright)
|
|
@@ -448,13 +448,13 @@ Hướng dẫn: "Mở `specs/domain-knowledge/core-entities.md` và định ngh
|
|
|
448
448
|
|
|
449
449
|
## Step 6 — Cài VS Code Extension (Khuyến nghị)
|
|
450
450
|
|
|
451
|
-
Khuyến nghị user cài extension VS Code **
|
|
451
|
+
Khuyến nghị user cài extension VS Code **SDD Board** — nó cung cấp panel Review Board + Living Documentation tích hợp với workflow này.
|
|
452
452
|
|
|
453
453
|
```bash
|
|
454
|
-
code --install-extension
|
|
454
|
+
code --install-extension EducaCorp.sdd-board
|
|
455
455
|
```
|
|
456
456
|
|
|
457
|
-
Hoặc: VS Code → `Ctrl+Shift+P` → **"Extensions: Install from Marketplace"** → tìm **
|
|
457
|
+
Hoặc: VS Code → `Ctrl+Shift+P` → **"Extensions: Install from Marketplace"** → tìm **SDD Board**.
|
|
458
458
|
|
|
459
459
|
**Nó làm gì:**
|
|
460
460
|
- 📋 **Review Board** — UI trực quan để review findings từ `/refine-prd`, `/review-context`, `/review-tech-docs`
|
|
@@ -557,7 +557,7 @@ Next:
|
|
|
557
557
|
4. Điền specs/domain-knowledge/core-entities.md
|
|
558
558
|
5. git add và commit 4 file đó
|
|
559
559
|
6. Cài VS Code extension:
|
|
560
|
-
code --install-extension
|
|
560
|
+
code --install-extension EducaCorp.sdd-board
|
|
561
561
|
7. /define-product để bắt đầu feature đầu tiên
|
|
562
562
|
```
|
|
563
563
|
|
|
@@ -591,7 +591,7 @@ Next:
|
|
|
591
591
|
3. Điền specs/domain-knowledge/core-entities.md ← entity glossary
|
|
592
592
|
4. git add và commit các file đó
|
|
593
593
|
5. Cài VS Code extension:
|
|
594
|
-
code --install-extension
|
|
594
|
+
code --install-extension EducaCorp.sdd-board
|
|
595
595
|
6. /define-product để bắt đầu feature đầu tiên
|
|
596
596
|
|
|
597
597
|
⚠️ Nhắc handoff team dev:
|
|
@@ -193,7 +193,7 @@ Your content was preserved:
|
|
|
193
193
|
Review & commit:
|
|
194
194
|
git diff .agent/
|
|
195
195
|
git add .agent/ .claude/commands/
|
|
196
|
-
git commit -m "chore: upgrade
|
|
196
|
+
git commit -m "chore: upgrade sdd-framework v{current} → v{latest}"
|
|
197
197
|
{umbrella mode: this is the umbrella root — service submodules need no framework update}
|
|
198
198
|
|
|
199
199
|
---
|
|
@@ -1223,7 +1223,7 @@ Schema:
|
|
|
1223
1223
|
- `test_classes`: dùng `[]` (không phải `"—"`) khi không có test class
|
|
1224
1224
|
- `tech_doc_revision` / `fe_tech_doc_revision`: dùng integer; `0` nếu chưa sinh
|
|
1225
1225
|
- `code_coverage_pct` / `test_coverage_pct`: làm tròn về integer gần nhất (0–100)
|
|
1226
|
-
- **`status` trong JSON CỐ TÌNH chỉ có 4 giá trị** `OK`/`DRIFT`/`GAP`/`UNTRACKED` — KHÔNG ghi `ORPHANED` vào field này. VS Code extension "
|
|
1226
|
+
- **`status` trong JSON CỐ TÌNH chỉ có 4 giá trị** `OK`/`DRIFT`/`GAP`/`UNTRACKED` — KHÔNG ghi `ORPHANED` vào field này. VS Code extension "SDD Board" (sống **ngoài** repo này) switch trên `status`; thêm giá trị thứ 5 sẽ rơi vào nhánh không khớp và có thể làm row mất khỏi panel.
|
|
1227
1227
|
Row `ORPHANED` xuất ra JSON là: `"status": "DRIFT"` + `"orphaned": true`. Panel chưa hỗ trợ vẫn hiện nó như `DRIFT` — đủ đúng về nghĩa ("code không khớp spec, cần xử lý") và **không im lặng**; panel có đọc `orphaned` thì hiện nhãn riêng. Chi tiết đầy đủ luôn có ở `orphaned[]` và ở report terminal.
|
|
1228
1228
|
**TSV giữ nguyên chữ `ORPHANED`** trong cột `status` — TSV là nguồn-sự-thật, JSON chỉ là bản xuất cho panel.
|
|
1229
1229
|
- `orphaned` (boolean): `true` chỉ khi cột `status` của TSV là `ORPHANED`; mọi row khác ghi `false` (đừng bỏ trống — panel đọc field vắng dễ ra `undefined`).
|
|
@@ -19,11 +19,11 @@ architecture:
|
|
|
19
19
|
- "Each test independent via pytest-playwright fixtures (page / logged_in_page / …)"
|
|
20
20
|
- "Page Object extends slim BasePage; split 3 layers: locators _x(), actions verb_noun(), assertions assert_x() using expect()"
|
|
21
21
|
- "Locator priority: data-testid → role → label/text → CSS → avoid XPath"
|
|
22
|
-
- "test-id values come from the FE tech-design §2b Test Selectors contract ({
|
|
22
|
+
- "test-id values come from the FE tech-design §2b Test Selectors contract (tech-doc gộp cấp PRD: {TICKET-ID}-tech-design.md, bảng Test Selectors §4.5.6 — lọc theo cột "Serves SC") — prefer them (no runtime scan); fall back to role/text only when an actionable element has no test-id there, and note the gap"
|
|
23
23
|
- "Group tests by (role, account) so login/logout never interleaves across roles"
|
|
24
24
|
- "Cover 100% of TCs in the .Test.md — every TC ends Pass/Fail/Skip, none left Draft"
|
|
25
25
|
folder_structure: |
|
|
26
|
-
{
|
|
26
|
+
{qc_artifact_dir}test-cases/ ← test-case Markdown (.Test.md) — source of truth (mặc định docs/, lộ ra ngoài)
|
|
27
27
|
pages/ ← Page Object Model
|
|
28
28
|
│ ├── base_page.py ← slim BasePage (click/fill/wait/screenshot)
|
|
29
29
|
│ └── <feature>_page.py
|
|
@@ -42,7 +42,7 @@ coding_standards:
|
|
|
42
42
|
test_function: "test_TC<NNN>_<snake_case>"
|
|
43
43
|
page_object: "<feature>_page.py with <Feature>Page class extending BasePage"
|
|
44
44
|
files:
|
|
45
|
-
test_case_md: "{
|
|
45
|
+
test_case_md: "{qc_artifact_dir}test-cases/TC_<FEATURE>.Test.md"
|
|
46
46
|
page_object: "pages/<feature>_page.py"
|
|
47
47
|
test_script: "tests/<project>/test_<feature>.py"
|
|
48
48
|
patterns:
|