@educa-corp/sdd-framework 0.9.3 → 0.9.5
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/lint-trace.js +230 -2
- package/bin/qc-base-map.json +119 -49
- package/bin/self-check.js +54 -0
- package/bin/trace-schema.json +58 -4
- package/core/FRAMEWORK_VERSION +1 -1
- package/core/commands/generate-bdd.md +1 -0
- package/core/commands/generate-code.md +39 -2
- package/core/commands/generate-tech-docs.md +21 -2
- package/core/commands/map-testids.md +88 -8
- package/core/commands/qc-analyze.md +429 -472
- package/core/commands/qc-design-test.md +251 -207
- package/core/commands/qc-plan.md +97 -197
- package/core/commands/qc-report.md +76 -60
- package/core/commands/qc-review.md +135 -185
- package/core/commands/qc-run-test.md +235 -274
- package/core/commands/review-tech-docs.md +20 -0
- 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 +1 -1
- package/core/rules/data-protection.md +52 -0
- package/core/rules/workflow.md +1 -1
- package/core/skills/qc/_shared/self-review-principles.md +112 -0
- package/core/skills/qc/qa-analyst/DOC_GAP.template.md +1 -1
- package/core/skills/qc/qa-analyst/spec-breakdown.md +2 -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-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 +3 -3
- package/core/skills/qc/qa-runner/functional/gui-feature.md +9 -3
- package/core/skills/qc/qa-runner/functional/gui-screen.md +9 -3
- package/core/skills/qc/qa-runner/integration.md +1 -1
- package/core/skills/qc/qa-runner/non-functional.md +1 -1
- package/core/skills/spec/SKILL.md +1 -1
- package/core/steps/context-loader.md +7 -2
- package/core/steps/gap-verify.md +67 -0
- package/core/steps/report-footer.md +3 -3
- package/core/templates/feature.template +1 -0
- package/core/templates/tech-design.template.md +1 -0
- package/docs/02-concepts/pipeline-steps/09-validate-traces.md +1 -1
- package/docs/04-reference/commands.md +1 -1
- package/docs/04-reference/trace-schema.md +39 -1
- package/docs/explain/00-setup-ai-first.md +1 -1
- package/docs/explain/11-map-testids.md +70 -69
- package/docs/plans/qc-implementation-log.md +145 -3
- package/docs/plans/qc-surgery/00-nhat-ky.md +497 -0
- package/docs/plans/qc-surgery/01-checklist.md +92 -0
- package/docs/plans/qc-surgery/02-lo-trinh.md +266 -0
- package/docs/plans/qc-surgery/buoc/0-01-testid-attr-co-cho-o.md +157 -0
- package/docs/plans/qc-surgery/buoc/0-02-mot-nguon-cho-testid-attr.md +135 -0
- package/docs/plans/qc-surgery/buoc/0-03-skill-thoi-day-do-dom.md +167 -0
- package/docs/plans/qc-surgery/buoc/0-04-may-canh-hop-dong.md +173 -0
- package/docs/plans/qc-surgery/buoc/0-05-don-nhan-cot-va-2b.md +133 -0
- package/docs/plans/qc-surgery/buoc/0-06-hop-dong-truoc-code.md +226 -0
- package/docs/plans/qc-surgery/buoc/1-01-guard-br-tag.md +156 -0
- package/docs/plans/qc-surgery/buoc/1-02-guard-sc-coverage.md +153 -0
- package/docs/plans/qc-surgery/buoc/1-03-fail-3-nhan.md +176 -0
- package/docs/plans/qc-surgery/buoc/1-04-self-review-dung-chung.md +175 -0
- package/docs/plans/qc-surgery/buoc/1-05-spec-la-du-lieu.md +164 -0
- package/docs/plans/qc-surgery/buoc/1-06-gap-verify-du-bo.md +162 -0
- package/docs/plans/qc-surgery/buoc/README.md +85 -0
- package/docs/plans/qc-surgery/exec-d0-b1-testid-attr-header.md +147 -0
- package/docs/plans/qc-surgery/exec-d0-b2-thong-nhat-nguon-testid-attr.md +152 -0
- package/docs/plans/qc-surgery/exec-d0-b3-sua-skill-probe-dom.md +173 -0
- package/docs/plans/qc-surgery/exec-d0-b4-may-canh-4-5-6.md +168 -0
- package/docs/plans/qc-surgery/exec-d0-b5-don-nhan-lech.md +196 -0
- package/docs/plans/qc-surgery/exec-d0-b6-contract-truoc-code.md +350 -0
- package/docs/plans/qc-surgery/exec-d1-b1-guard-br-tag.md +129 -0
- package/docs/plans/qc-surgery/exec-d1-b2-guard-sc-coverage.md +159 -0
- package/docs/plans/qc-surgery/exec-d1-b3-fail-3-bucket.md +158 -0
- package/docs/plans/qc-surgery/exec-d1-b4-self-review-principles.md +145 -0
- package/docs/plans/qc-surgery/exec-d1-b5-noi-quy-spec-la-du-lieu.md +156 -0
- package/docs/plans/qc-surgery/exec-d1-b6-gap-verify-mo-rong.md +179 -0
- package/docs/plans/qc-surgery/exec-d2-b1-tach-qc-review.md +166 -0
- package/docs/plans/qc-surgery/exec-d2-b2-tach-qc-run-test-atomic.md +267 -0
- package/docs/plans/qc-surgery/exec-d2-b3-qc-automation-assess.md +198 -0
- package/docs/plans/qc-surgery/exec-d3-b1-qc-report-gate-decision.md +209 -0
- package/docs/plans/qc-surgery/exec-d4-b1-qc-design-testdata.md +146 -0
- package/docs/plans/qc-surgery/exec-d4-b2-qc-smoke-test.md +179 -0
- package/docs/plans/qc-surgery/exec-d4-b3-qc-metrics-va-lint.md +198 -0
- package/docs/plans/qc-surgery/exec-d4-b4-lint-spec-injection.md +199 -0
- package/package.json +1 -1
|
@@ -74,7 +74,7 @@ Mọi lệnh chạy chung một **Gate** (model check → target → context-loa
|
|
|
74
74
|
| `/generate-code` | `.feature` approved + tech-design | Code + `.trace/*.tsv` | Dev |
|
|
75
75
|
| `/review-code` | Code | Findings (read-only) | Dev/Lead |
|
|
76
76
|
| `/fix-bug` | Bug report | Fix + regression test | Dev |
|
|
77
|
-
| `/map-testids` | UI code |
|
|
77
|
+
| `/map-testids` | design-spec + BDD (`--from-code`: + UI code) | §4.5.6 Test Selectors + `@trace.testid_attr` | Người viết tech-doc (`--from-code`: Dev) |
|
|
78
78
|
| `/debug` | Mô tả lỗi | Phân tích (read-only) | Dev |
|
|
79
79
|
|
|
80
80
|
## 7 · Dev self-test
|
|
@@ -94,6 +94,44 @@ public ScoreDto calculate(...) { }
|
|
|
94
94
|
| `@trace.revision` | integer, bump mỗi lần sửa — nguồn của `TECHDOC_DRIFT` |
|
|
95
95
|
| `@trace.status` | `draft` / `in-review` / `approved` — cổng của `/generate-code` DS3 |
|
|
96
96
|
| `@trace.api_source` | `existing` → chế độ reverse-document, bỏ cổng T7 |
|
|
97
|
+
| `@trace.testid_attr` | **TÊN THUỘC TÍNH** chứa test-id (`data-testid` · `data-test` · `testID` · `ValueKey`…) — **một** giá trị cho cả doc. Khác **GIÁ TRỊ** test-id từng element, cái đó ở §4.5.6. Ghi bởi `/map-testids`; đọc bởi `/generate-code` (emit lên element) và các lệnh `qc-*` (cấu hình locator). |
|
|
98
|
+
|
|
99
|
+
### Hợp đồng test-id — được máy canh (`testid_contract`)
|
|
100
|
+
|
|
101
|
+
Bảng **§4.5.6 Test Selectors** trong tech-doc là hợp đồng FE↔QC: **3 lệnh đọc**
|
|
102
|
+
(`generate-code`, `qc-run-test`, `qc-design-test`), **2 lệnh ghi** (`generate-tech-docs`,
|
|
103
|
+
`map-testids`). Hai rule của `lint-trace` canh nó:
|
|
104
|
+
|
|
105
|
+
| Rule | Kiểm gì | Mức |
|
|
106
|
+
|---|---|:---:|
|
|
107
|
+
| **T15** | Mọi SC ở cột *"Phục vụ SC"* phải có thật trong `.feature` của nền đó | 🔴 error |
|
|
108
|
+
| **T16** | Có block §4.5 (nền client) mà header thiếu hẳn `@trace.testid_attr` | 🔴 error |
|
|
109
|
+
| | …có nhưng còn ở dạng placeholder `{…}` (chưa chạy `/map-testids`) | ⚠️ warn |
|
|
110
|
+
| **T17** | Id đã khai ở §4.5.6 mà **không có trong code** — FE chưa gắn / gắn sai / element đã đổi *(cần `--code`)* | ⚠️ warn |
|
|
111
|
+
| **T18** | Id nằm trong code mà **không có trong §4.5.6 nào** — gắn ngoài hợp đồng *(cần `--code`)* | ⚠️ warn |
|
|
112
|
+
|
|
113
|
+
> **T17/T18 là WARN, không ERROR.** Id đoán từ thiết kế không sống sót 100%: lúc implement, dev
|
|
114
|
+
> có thể gộp hai element thành một component hoặc tách một thành hai. Đây là **nợ cần thấy**,
|
|
115
|
+
> không phải cái sai chặn người.
|
|
116
|
+
>
|
|
117
|
+
> T18 là **lưới bắt phía sau** cho quyết định ở `/generate-code`: khi §4.5.6 rỗng, lệnh đó cảnh
|
|
118
|
+
> báo rồi **để người quyết** thay vì chặn cứng — chính vì có T18 bắt những id tạm sinh ra ở đó,
|
|
119
|
+
> nên "vẫn sinh" không tạo nợ vô hình.
|
|
120
|
+
>
|
|
121
|
+
> Thiếu `--code` → in `T17/T18 BỎ QUA` tường minh, **không im lặng báo sạch**. Code chưa có id
|
|
122
|
+
> nào của thuộc tính đó (UI chưa viết) → im lặng, không phán "FE chưa gắn" cho cả bảng.
|
|
123
|
+
|
|
124
|
+
> **Phạm vi neo vào sự tồn tại của hợp đồng.** Doc không có §4.5 client → **không kiểm gì**.
|
|
125
|
+
> Dự án backend-only, hay dự án chưa từng chạy `/map-testids`, im lặng hoàn toàn. Hai rule nói
|
|
126
|
+
> *"chỗ nào đã hứa thì phải giữ"*, không nói *"mọi chỗ đều phải có hợp đồng"*. Dòng mẫu của
|
|
127
|
+
> template (còn `{…}`) cũng được bỏ qua — nếu không thì tech-doc vừa sinh ra đã đỏ.
|
|
128
|
+
>
|
|
129
|
+
> **Không vào `gate.blocking`** — đây là nợ cần thấy, không phải cái sai chặn PR. Cùng nhóm với
|
|
130
|
+
> `TECHDOC_DRIFT` / `BDD_DRIFT`; 13/17 cờ audit hiện tại cũng không chặn.
|
|
131
|
+
|
|
132
|
+
Khối `testid_contract` trong `bin/trace-schema.json` khai hai rule này kèm `why`, và
|
|
133
|
+
`self-check` **R8e** báo lỗi nếu `lint-trace.js` không thực sự phát ra chúng — nửa *"máy canh"*
|
|
134
|
+
của luật *"khai tường minh + để máy canh"*.
|
|
97
135
|
|
|
98
136
|
---
|
|
99
137
|
|
|
@@ -240,7 +278,7 @@ Ca thứ hai là lý do consumer **phải** chuẩn hoá tập bị ảnh hưở
|
|
|
240
278
|
|
|
241
279
|
## Xuất JSON cho panel
|
|
242
280
|
|
|
243
|
-
`trace-report.json` giữ enum `status` **đúng 4 giá trị** `OK`/`DRIFT`/`GAP`/`UNTRACKED` — VS Code extension "
|
|
281
|
+
`trace-report.json` giữ enum `status` **đúng 4 giá trị** `OK`/`DRIFT`/`GAP`/`UNTRACKED` — VS Code extension "SDD Board" sống ngoài repo framework và switch trên field này. Row `ORPHANED` xuất ra là `"status": "DRIFT"` + `"orphaned": true`; panel cũ hiện nó như DRIFT (đúng nghĩa, không im lặng), panel mới đọc `orphaned` để hiện nhãn riêng. **TSV giữ nguyên chữ `ORPHANED`** — TSV là nguồn-sự-thật.
|
|
244
282
|
|
|
245
283
|
---
|
|
246
284
|
|
|
@@ -44,7 +44,7 @@ Mọi command sau đều đọc `project-context.yaml` + `CLAUDE.md` + `domain-k
|
|
|
44
44
|
5. **Step 3 · project-context.yaml** — copy từ `templates/project-context.yaml`, điền `{{PLACEHOLDER}}`. Umbrella: verify/sửa `services` (path phải khớp tên submodule thật — generator để placeholder `TODO-…`).
|
|
45
45
|
6. **Step 4 · business-dictionary.md** — Canonical Terms / Banned Terms / Enum Registry. *(Umbrella skip — sống trong spec submodule.)*
|
|
46
46
|
7. **Step 5 · core-entities.md** — entity catalog máy-đọc-được (field, invariant, relationship). *(Umbrella skip.)*
|
|
47
|
-
8. **Step 6 · VS Code extension** — khuyến nghị cài "
|
|
47
|
+
8. **Step 6 · VS Code extension** — khuyến nghị cài "SDD Board" (Review Board + Living Docs UI).
|
|
48
48
|
9. **Step 7 · Verify** — checklist theo `project_type` (file/folder tồn tại; umbrella check submodule init).
|
|
49
49
|
|
|
50
50
|
---
|
|
@@ -1,69 +1,70 @@
|
|
|
1
|
-
[← /review-code](10-review-code.md) · [Explain Home](README.md) · [Next: /dev-gen-test →](12-dev-gen-test.md)
|
|
2
|
-
|
|
3
|
-
# 11 · `/map-testids` — Dán test-id ổn định cho UI (FE)
|
|
4
|
-
|
|
5
|
-
> **Một câu.** Gắn **test-id ổn định** vào các element có hành động trên UI FE và ghi bản đồ selector vào tech-doc §4.5.6 — làm cầu nối để QC Playwright bám selector không vỡ.
|
|
6
|
-
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
## Vấn đề giải quyết
|
|
10
|
-
|
|
11
|
-
Test tự động (Playwright) vỡ khi selector đổi (class/text thay đổi). `/map-testids` chuẩn hoá **test-id ổn định** cho mọi element tương tác, đảm bảo component tái dùng forward được test-id, và ghi map để QC dùng — tách concern "làm UI test được" khỏi "viết test".
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Vị trí & tiền đề
|
|
16
|
-
|
|
17
|
-
- **Vị trí:** Phase Tech Design
|
|
18
|
-
- **
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
| **
|
|
36
|
-
| **
|
|
37
|
-
| **
|
|
38
|
-
| **
|
|
39
|
-
| **
|
|
40
|
-
| **
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- **
|
|
54
|
-
- **
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
- **
|
|
62
|
-
- **
|
|
63
|
-
- **
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
1
|
+
[← /review-code](10-review-code.md) · [Explain Home](README.md) · [Next: /dev-gen-test →](12-dev-gen-test.md)
|
|
2
|
+
|
|
3
|
+
# 11 · `/map-testids` — Dán test-id ổn định cho UI (FE)
|
|
4
|
+
|
|
5
|
+
> **Một câu.** Gắn **test-id ổn định** vào các element có hành động trên UI FE và ghi bản đồ selector vào tech-doc §4.5.6 — làm cầu nối để QC Playwright bám selector không vỡ.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Vấn đề giải quyết
|
|
10
|
+
|
|
11
|
+
Test tự động (Playwright) vỡ khi selector đổi (class/text thay đổi). `/map-testids` chuẩn hoá **test-id ổn định** cho mọi element tương tác, đảm bảo component tái dùng forward được test-id, và ghi map để QC dùng — tách concern "làm UI test được" khỏi "viết test".
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Vị trí & tiền đề
|
|
16
|
+
|
|
17
|
+
- **Vị trí:** Phase **Tech Design**, sau `/generate-tech-docs` và **TRƯỚC** `/review-tech-docs` — tức trước cả `/generate-code`. Chốt hợp đồng test-id ở đây để FE và QC đọc cùng một bản đã đóng băng rồi **chạy song song**.
|
|
18
|
+
- **Hai chế độ:** mặc định (feature mới — nguồn là design-spec + BDD, **không đụng code**) · `--from-code` (brownfield — đọc/patch code đã có, chạy một lần mỗi UC cũ).
|
|
19
|
+
- **Chặn cứng:** chỉ FE/App (platform guard) — BE không có UI.
|
|
20
|
+
|
|
21
|
+
---
|
|
22
|
+
|
|
23
|
+
## Input / Output
|
|
24
|
+
|
|
25
|
+
**Input:** design-spec (Component Inventory, màn hình) + step `When` của `.feature` FE + tech-doc §4.5.1 (cây component) + catalog component tái dùng. *Chế độ `--from-code` đọc thêm UI code FE.*
|
|
26
|
+
|
|
27
|
+
**Output:** map §4.5.6 Test Selectors + `@trace.testid_attr` ở header tech-doc. *Chế độ `--from-code` còn patch test-id vào code FE.*
|
|
28
|
+
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
## Các bước xử lý (chi tiết)
|
|
32
|
+
|
|
33
|
+
| Step | Việc |
|
|
34
|
+
|------|------|
|
|
35
|
+
| **0 · Platform guard** | Chỉ FE/App; else STOP |
|
|
36
|
+
| **1 · Thu thập element có action** | Quét UI tìm element người dùng tương tác (nút, ô nhập, link…) |
|
|
37
|
+
| **2 · Phân giải test-id ổn định** | Đặt test-id ổn định (không phụ thuộc text/class dễ đổi) cho mỗi element |
|
|
38
|
+
| **3 · Đảm bảo component tái dùng forward test-id** | Component dùng lại (catalog) phải cho phép truyền test-id xuống — sửa component nếu chưa |
|
|
39
|
+
| **4 · Patch usage site** (chỉ EXTEND) | Gắn test-id vào nơi dùng, chỉ thêm (không viết đè) |
|
|
40
|
+
| **5 · Ghi/làm mới map §4.5.6** | Ghi bảng Test Selectors vào tech-doc để QC bám |
|
|
41
|
+
| **6 · Handoff** | Bàn giao cho QC (`/qc-*`) |
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Checkpoint & Gate
|
|
46
|
+
|
|
47
|
+
- Không gate chặn; EXTEND-only khi patch (an toàn).
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Cơ chế đặc biệt
|
|
52
|
+
|
|
53
|
+
- **Test-id ổn định** — chống test vỡ do đổi visual; nguyên tắc "selector là contract QC↔FE".
|
|
54
|
+
- **Forward test-id qua component tái dùng** — sửa gốc component để test-id lan xuống, không hardcode từng chỗ.
|
|
55
|
+
- **Map ở §4.5.6 tech-doc** — QC đọc từ một nguồn, không tự dò.
|
|
56
|
+
|
|
57
|
+
---
|
|
58
|
+
|
|
59
|
+
## 👓 Góc nhìn tối ưu
|
|
60
|
+
|
|
61
|
+
- **Lệnh chốt hợp đồng FE↔QC** — vị trí **đã được chốt**: phase Tech Design, trước `/generate-code`. Trước đây vị trí mờ (tài liệu này từng nói 'giữa Tech Design & Code') nên lệnh hay bị bỏ qua; giờ `/generate-tech-docs` trỏ thẳng sang đây, và `/review-tech-docs` T6 không cho APPROVED nếu §4.5.6 rỗng.
|
|
62
|
+
- **Phụ thuộc catalog component tái dùng** — nếu component không forward được prop test-id, Step 3 phát sinh sửa lan rộng.
|
|
63
|
+
- **EXTEND-only** an toàn nhưng nếu test-id cũ sai thì không tự sửa.
|
|
64
|
+
- **Đã vào golden path** — `/generate-tech-docs` → **`/map-testids`** → `/review-tech-docs` (T6 chặn nếu §4.5.6 rỗng). `lint-trace` T15/T16 canh bảng, T17/T18 canh bảng-vs-code.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Kết nối
|
|
69
|
+
|
|
70
|
+
**Trước:** [`/generate-tech-docs`](08-generate-tech-docs.md) · **Sau:** [`/review-tech-docs`](07-review-tech-docs.md), rồi rẽ hai nhánh song song — [`/generate-code`](09-generate-code.md) (FE gắn attribute) ∥ [`/qc-design-test`](17-qc-design-test.md) (QC dựng test theo cùng hợp đồng).
|
|
@@ -1512,6 +1512,148 @@ xem bản mới có bắt thêm gap thật hay không.
|
|
|
1512
1512
|
|
|
1513
1513
|
---
|
|
1514
1514
|
|
|
1515
|
+
# ✅ B12 — Rà trạm viết kịch bản kiểm thử theo bản gốc
|
|
1516
|
+
|
|
1517
|
+
Đi theo đúng thứ tự dây chuyền: xong trạm 1 và 2 (B11) thì tới trạm 3 — **trạm quyết định có
|
|
1518
|
+
test hay không có test**.
|
|
1519
|
+
|
|
1520
|
+
## Hai điều rà ra
|
|
1521
|
+
|
|
1522
|
+
**① Trạm này chưa hề được đụng trong cả đợt merge.** Bản đồ port ghi **21/21 file gốc ở trạng
|
|
1523
|
+
thái "chưa quyết"**. 11 kỹ năng đang chạy đến từ **một nguồn khác** (`lms_autotest`), không phải
|
|
1524
|
+
từ đội QC.
|
|
1525
|
+
|
|
1526
|
+
| | File | Dòng |
|
|
1527
|
+
|---|---|---|
|
|
1528
|
+
| Bản gốc đội QC | 21 | **2.509** |
|
|
1529
|
+
| Framework | 11 | **496** *(~20%)* |
|
|
1530
|
+
|
|
1531
|
+
**② Một lỗi im lặng, cùng lớp với `DOC_GAPS` / `DOC_GAP`:**
|
|
1532
|
+
|
|
1533
|
+
| Ai | Nói tên file là |
|
|
1534
|
+
|---|---|
|
|
1535
|
+
| 2 kỹ năng | `TC_<FEATURE>.md` |
|
|
1536
|
+
| 1 kỹ năng | `TC_<FEATURE>_API.md` |
|
|
1537
|
+
| **4 kỹ năng** | **không nêu tên gì cả** |
|
|
1538
|
+
| Lệnh thiết kế · lệnh chạy · lệnh soát · module Playwright *(13 chỗ)* | `*.Test.md` |
|
|
1539
|
+
|
|
1540
|
+
**Trạm thiết kế ghi ra thứ trạm chạy không tìm thấy.** Và không có gì báo lỗi — file vẫn nằm
|
|
1541
|
+
đó, trạm sau chỉ đơn giản không thấy.
|
|
1542
|
+
|
|
1543
|
+
Framework có **phương pháp** (EP/BVA/bảng quyết định, danh sách nhóm TC); bản gốc có **chi
|
|
1544
|
+
tiết** (cấm từ mơ hồ, khuôn TC, từ điển hành động, bảng tra mã HTTP). Đúng khuôn đã gặp ở B1.
|
|
1545
|
+
|
|
1546
|
+
## Bốn quyết định
|
|
1547
|
+
|
|
1548
|
+
| # | Chốt | Nghĩa cho người dùng |
|
|
1549
|
+
|---|---|---|
|
|
1550
|
+
| **1** | **Luật ATOMIC, có cả chế độ tách tối đa** | Mỗi test case đúng **một** dòng kết quả mong đợi. Nhiều điểm kiểm → tách thành nhiều TC độc lập |
|
|
1551
|
+
| **2** | **Bỏ bảng trong file test case** | Toàn bộ dạng danh sách, không ký tự `\|` — kể cả mục Tổng hợp và Trace Matrix |
|
|
1552
|
+
| **3** | **Hai file, chia theo "có qua giao diện"** | mặc định → file giao diện (6 nhóm) · `--api` → file API (2 nhóm) · `--all` → cả hai |
|
|
1553
|
+
| **4** | **Lấy trọn 7 file luật chung + cả nhánh API, nhưng VIẾT LẠI 2 file mẫu** | 1.523 dòng |
|
|
1554
|
+
|
|
1555
|
+
## Chỗ suýt tự bắn vào chân mình
|
|
1556
|
+
|
|
1557
|
+
Nhánh API của bản gốc có 2 file **test case mẫu**. Đọc kỹ thì chúng viết **trước** luật ATOMIC
|
|
1558
|
+
(đội QC chốt 2026-07-09, và văn bản ghi rõ *"ĐẢO rule cũ"*):
|
|
1559
|
+
|
|
1560
|
+
```
|
|
1561
|
+
MẪU GỐC (cũ hơn luật) ĐÃ VIẾT LẠI
|
|
1562
|
+
**Expected:** #### Expected Result
|
|
1563
|
+
- HTTP 201; body.id = x; - HTTP 201 AND body.id exists
|
|
1564
|
+
bản ghi có trong DB
|
|
1565
|
+
▲ ba kết cục nối bằng ";" → TC_002: body.<field> = <giá trị>
|
|
1566
|
+
mã: API-<FEATURE>-001 → TC_003: DB có bản ghi id = body.id
|
|
1567
|
+
▲ hệ mã khác mã: TC_<FEATURE>_NNN
|
|
1568
|
+
```
|
|
1569
|
+
|
|
1570
|
+
**Lấy nguyên hai file này là dạy AI làm ngược đúng cái luật vừa chốt** — vì mẫu cụ thể luôn
|
|
1571
|
+
thắng luật trừu tượng. Đã viết lại cả hai, và kiểm bằng máy: **13/13 khối kết quả mong đợi có
|
|
1572
|
+
đúng 1 dòng**.
|
|
1573
|
+
|
|
1574
|
+
Cũng bỏ 26 dòng là **bản nháp cũ** của chính họ: một bảng tra mã lỗi 14 dòng nằm gọn trong bảng
|
|
1575
|
+
95 dòng, một file chuỗi gọi 12 dòng nằm gọn trong hai file dài hơn. Lấy cả hai là có hai bảng
|
|
1576
|
+
tra cùng một thứ, rồi chúng lệch nhau.
|
|
1577
|
+
|
|
1578
|
+
## Bốn thứ giờ mới có
|
|
1579
|
+
|
|
1580
|
+
| Luật | Nó chặn điều gì |
|
|
1581
|
+
|---|---|
|
|
1582
|
+
| **Cấm 9 cụm từ mơ hồ** | *"hiển thị đúng"* · *"hoạt động bình thường"* · *"không lỗi"* → bắt viết giá trị đo được. Phép thử: **hai QC đọc có ra cùng một kết luận đỗ/trượt không?** |
|
|
1583
|
+
| **Khuôn TC + luật ATOMIC** | Mỗi TC một kết cục; mẫu đầy đủ; 5 bẫy khi đánh số lại hàng loạt |
|
|
1584
|
+
| **Cây quyết định chọn tầng** | ~12 ví dụ phân biệt: *"dropdown có placeholder"* = giao diện, *"dropdown hiện đúng N mục từ API"* = tích hợp |
|
|
1585
|
+
| **Từ điển hành động** | Một hành động **một** từ: Click (web) / Tap (mobile) / Enter (nhập) — cấm dùng Type, Input, Fill lẫn lộn |
|
|
1586
|
+
|
|
1587
|
+
Thêm **kiểm trùng lặp** — thứ framework trước đây **không có gì cả**. Nó quan trọng hơn sau khi
|
|
1588
|
+
bật chế độ tách tối đa: nhân một TC trùng lên 5 mảnh thì thành 5 TC trùng, và không ai đếm
|
|
1589
|
+
được nữa. Nên kiểm trùng phải chạy **trước** khi tách.
|
|
1590
|
+
|
|
1591
|
+
Và B11 vừa gom mọi UC vào **một thư mục** — nên **trùng chéo UC** giờ mới thực sự nhìn thấy
|
|
1592
|
+
được, và mới thực sự xảy ra. Hai UC của cùng tính năng rất hay dùng lại một luật nghiệp vụ;
|
|
1593
|
+
gặp thì trỏ trace về UC nguồn, **không viết lại**.
|
|
1594
|
+
|
|
1595
|
+
## Chín bản của một luật → một bản
|
|
1596
|
+
|
|
1597
|
+
Khối *"Format file TC"* trước đây **bị chép ở 9 kỹ năng** và câu chữ đã lệch nhau. Giờ một
|
|
1598
|
+
bản dùng chung, 9 kỹ năng trỏ về. **Cùng bệnh 5-bản mà B11 vừa chữa** — và lần này nó không
|
|
1599
|
+
tiết kiệm dòng, nó chỉ bỏ đi khả năng chín bản nói khác nhau.
|
|
1600
|
+
|
|
1601
|
+
Cũng bỏ chữ **"hoặc"**: hai kỹ năng từng ghi *"file riêng **hoặc** gộp trong file feature"*.
|
|
1602
|
+
Chữ "hoặc" nghĩa là AI tự chọn mỗi lần một kiểu — nên hai lần chạy cùng một tính năng có thể ra
|
|
1603
|
+
hai cấu trúc thư mục khác nhau.
|
|
1604
|
+
|
|
1605
|
+
## Hai lần bị máy bắt lỗi — và đó là điểm sáng
|
|
1606
|
+
|
|
1607
|
+
**Lần 1 — self-check chặn.** Tôi dồn phần `@trace.testid_attr` sang file dùng chung, làm lệnh
|
|
1608
|
+
không còn nhắc tag nữa. Rule R3 đỏ ngay: *"schema khai `qc-design-test` là consumer nhưng lệnh
|
|
1609
|
+
KHÔNG nhắc tới nó"*. Đúng — tôi gộp quá tay. Đã trả lại ở lệnh.
|
|
1610
|
+
|
|
1611
|
+
**Lần 2 — bộ test chặn.** `qc-scope.md` (B11) được 5 lệnh nạp, nên nó bị nướng 5 bản vào 5 file
|
|
1612
|
+
lệnh. Cộng thêm phần B12, tổng vượt ngưỡng: **1203 KB / ngưỡng 1200**. Framework đã có cơ chế
|
|
1613
|
+
cho đúng ca này (đọc-lúc-chạy thay vì nướng vào), chỉ là chưa dùng cho file đó. Chuyển xong:
|
|
1614
|
+
**1174 KB**.
|
|
1615
|
+
|
|
1616
|
+
> Cả hai lỗi đều là **lỗi của tôi**, và **cả hai đều do máy bắt, không phải do tôi đọc lại**.
|
|
1617
|
+
> Đây chính là lập luận cho mục còn treo 2b: thứ có máy canh thì không đi lệch.
|
|
1618
|
+
|
|
1619
|
+
## Bịt một điểm mù của chính bộ máy canh
|
|
1620
|
+
|
|
1621
|
+
Cập nhật bản đồ port xong, self-check **xanh** — nhưng `functional/api.md` nhận nội dung port mà
|
|
1622
|
+
**không đóng dấu nguồn gốc** nào. Đọc lại luật thì rõ vì sao: nó so dấu với bản đồ **khi file có
|
|
1623
|
+
khai**. File không khai gì thì nó im lặng.
|
|
1624
|
+
|
|
1625
|
+
Đã thêm một nhánh mới: **target đã port thì PHẢI khai** nguồn gốc, không chỉ "khai đúng nếu có
|
|
1626
|
+
khai". Và **thử cháy thật** cả hai góc (bỏ cả hai dòng · bỏ một dòng) — kêu đúng cả hai lần.
|
|
1627
|
+
|
|
1628
|
+
Mất dấu nguồn gốc ở file đích nghĩa là: bản đồ biết file này port từ đâu, còn **người mở file
|
|
1629
|
+
thì không** — và lần đồng bộ sau, mọi thứ thành đoán.
|
|
1630
|
+
|
|
1631
|
+
## Đã kiểm chứng
|
|
1632
|
+
|
|
1633
|
+
| Phép kiểm | Kết quả |
|
|
1634
|
+
|---|---|
|
|
1635
|
+
| Dựng lại toàn bộ | 41/41 ✅ |
|
|
1636
|
+
| Bộ kiểm tra nội bộ | sạch (giờ có **17** nhánh luật) ✅ |
|
|
1637
|
+
| Bộ test tự động | **199/199** ✅ |
|
|
1638
|
+
| Tổng kích thước lệnh | 1174 KB / ngưỡng 1200 ✅ |
|
|
1639
|
+
| Tên file cũ còn sót | **0** |
|
|
1640
|
+
| Lệnh "in bảng" trong kỹ năng thiết kế | **0** |
|
|
1641
|
+
| Dấu vết mẫu cũ trong nhánh API | **0** |
|
|
1642
|
+
| Khối kết quả mong đợi đúng 1 dòng | **13/13** |
|
|
1643
|
+
| Entry "chưa quyết" của trạm này | **21 → 0** |
|
|
1644
|
+
| Target đã port có đủ dấu nguồn gốc | **23/23** |
|
|
1645
|
+
| File mới tới đủ ba tầng (nguồn → đóng gói → đang chạy) | **13/13/13** |
|
|
1646
|
+
|
|
1647
|
+
## Cố ý chưa làm
|
|
1648
|
+
|
|
1649
|
+
| Việc | Vì sao |
|
|
1650
|
+
|---|---|
|
|
1651
|
+
| **Máy kiểm cấu trúc file test case** | Vẫn là năng lực mới, và vẫn chờ kết quả phép thử của trạm 1. Nhưng B12 làm nó **rẻ hơn hẳn**: cả hai luật mới đều **đếm được** — "0 ký tự `\|`" và "1 dòng mỗi kết quả". Nếu phép thử kết luận cần máy kiểm thì làm một lượt cho cả file gap và file test case |
|
|
1652
|
+
| **4 file tầng test của bản gốc** *(ui · e2e · integration · nfr — 935 dòng)* | Đã ghi `skipped` **kèm lý do**, không để "chưa quyết". Framework tách tầng UI thành 3 kỹ năng theo cây quyết định thay vì một file 341 dòng; phần khuôn TC và độ chính xác **đã tách ra dùng chung**. Còn lại là phần khai kiến trúc agent — framework không có. Đối chiếu nội dung từng tầng để dành |
|
|
1653
|
+
| **3 trạm còn lại** | Đi theo thứ tự dây chuyền. Trạm soát là trạm kế tiếp, và nó **tiêu thụ** đúng chuẩn B12 vừa đặt ra — làm sau là đúng thứ tự |
|
|
1654
|
+
|
|
1655
|
+
---
|
|
1656
|
+
|
|
1515
1657
|
# Tổng kết
|
|
1516
1658
|
|
|
1517
1659
|
| | Quyết định ở B7 | Bằng chứng | |
|
|
@@ -1554,7 +1696,7 @@ rồi, giờ bắt nó **so** với hai tài liệu kia"*. Không nạp thêm fi
|
|
|
1554
1696
|
|
|
1555
1697
|
# Các bước còn lại
|
|
1556
1698
|
|
|
1557
|
-
**Mười
|
|
1699
|
+
**Mười ba bước B0–B12 đã xong.** Không còn bước nào đang chờ quyết định để bắt đầu.
|
|
1558
1700
|
|
|
1559
1701
|
Nhưng có **hai việc chưa validate** và **bốn món nợ** — xem §Còn treo ở cuối.
|
|
1560
1702
|
Mô tả kế hoạch gốc nằm ở [`qc-merge-plan.md`](qc-merge-plan.md).
|
|
@@ -1568,7 +1710,7 @@ Mô tả kế hoạch gốc nằm ở [`qc-merge-plan.md`](qc-merge-plan.md).
|
|
|
1568
1710
|
Sau mỗi bước, toàn bộ hệ thống được dựng lại và kiểm tra tự động:
|
|
1569
1711
|
|
|
1570
1712
|
- 41/41 mẫu lệnh dựng thành công
|
|
1571
|
-
- Bộ kiểm tra nội bộ báo sạch
|
|
1713
|
+
- Bộ kiểm tra nội bộ báo sạch (17 nhánh luật sau B12)
|
|
1572
1714
|
- Nội dung mới đã lan đủ ba tầng: bản nguồn → bản đóng gói → bản đang chạy
|
|
1573
1715
|
- **9** dấu nguồn gốc đều được kiểm chứng khớp với file gốc thật
|
|
1574
1716
|
- Báo khói đã **thử cháy thật** cả 5 nhánh — không giao một cái chưa bao giờ kêu
|
|
@@ -1579,7 +1721,7 @@ Sau mỗi bước, toàn bộ hệ thống được dựng lại và kiểm tra
|
|
|
1579
1721
|
|
|
1580
1722
|
| # | Câu | Mức | Ai quyết |
|
|
1581
1723
|
|---|---|---|---|
|
|
1582
|
-
| **1** | Chạy thử trên một tính năng thật — **mười
|
|
1724
|
+
| **1** | Chạy thử trên một tính năng thật — **mười ba bước, chưa một lần chạy**. Sau B11 phép thử này còn quan trọng hơn: nó là cách duy nhất biết bản cấp tính năng có bắt được mâu thuẫn chéo UC, và có theo đúng template hay không. Ước lượng chi phí của tôi đã sai 3 lần, đều ước thấp | 🔴 chưa validate | bạn (cần spec thật) |
|
|
1583
1725
|
| **2** | Đưa nhật ký cho đội QC xem — họ là chủ sở hữu các kỹ năng này, và định dạng họ nhận đã đổi **hai lần** (B9 rồi B11) | 🟠 | bạn |
|
|
1584
1726
|
| **2b** | **Máy kiểm cấu trúc file gap** — bệnh *"không theo template"* vẫn chưa có gì chặn bằng máy. Hiện chỉ có chỉ thị bằng văn xuôi, tức **cùng loại** với câu chỉ đường đã thất bại, chỉ mạnh hơn | 🟠 chưa chữa | bạn (sau khi chạy thử B11) |
|
|
1585
1727
|
| **2c** | `Blocker` ↔ `Critical` — đổi trạm chạy test đọc `Critical` (một dòng) thay vì bắt đội QC đổi thói quen. Kết quả hôm trước cho thấy đổi từ ngữ của họ làm **tăng** khả năng lệch | 🟡 | bạn |
|