@educa-corp/sdd-framework 0.9.7 → 0.9.8

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.
Files changed (104) hide show
  1. package/bin/qc-base-map.json +13 -11
  2. package/bin/self-check.js +49 -4
  3. package/bin/trace-schema.json +3226 -3187
  4. package/core/FRAMEWORK_VERSION +1 -1
  5. package/core/commands/qc-analyze.md +2 -2
  6. package/core/commands/qc-automation-assess.md +3 -3
  7. package/core/commands/qc-design-script.md +60 -30
  8. package/core/commands/qc-design-test.md +79 -7
  9. package/core/commands/qc-plan.md +1 -1
  10. package/core/commands/qc-report.md +85 -76
  11. package/core/commands/qc-review-script.md +25 -16
  12. package/core/commands/qc-review-testcase.md +8 -7
  13. package/core/commands/qc-run-manualtest.md +1 -1
  14. package/core/commands/qc-run-script.md +15 -8
  15. package/core/modules/qc-playwright-ts/module.yaml +13 -0
  16. package/core/modules/qc-playwright-ts/stack-profile.yaml +99 -0
  17. package/core/modules/qc-wdio-appium/module.yaml +20 -0
  18. package/core/modules/qc-wdio-appium/stack-profile.yaml +107 -0
  19. package/core/skills/qc/qa-analyst/data-flow.md +1 -1
  20. package/core/skills/qc/qa-automation-assess/matrix.md +6 -3
  21. package/core/skills/qc/{qa-runner → qa-designer}/exploratory/session.md +8 -2
  22. package/core/skills/qc/qa-designer/functional/api.md +1 -1
  23. package/core/skills/qc/qa-designer/functional/job.md +128 -0
  24. package/core/skills/qc/qa-designer/integration/api.md +1 -1
  25. package/core/skills/qc/qa-designer/integration/db.md +1 -1
  26. package/core/skills/qc/qa-designer/integration/{kafka.md → queue.md} +20 -4
  27. package/core/skills/qc/qa-designer/shared/skill-decision-tree.md +17 -0
  28. package/core/skills/qc/qa-designer/shared/tc-metadata-format.md +17 -0
  29. package/core/skills/qc/qa-reviewer/script/_shared/review-rules.md +121 -0
  30. package/core/skills/qc/qa-reviewer/script/api/auth.md +49 -0
  31. package/core/skills/qc/qa-reviewer/script/api/endpoint.md +89 -0
  32. package/core/skills/qc/qa-reviewer/script/api/security.md +46 -0
  33. package/core/skills/qc/qa-reviewer/script/exploratory.md +2 -2
  34. package/core/skills/qc/qa-reviewer/script/mobile/e2e.md +41 -0
  35. package/core/skills/qc/qa-reviewer/script/mobile/functional.md +90 -0
  36. package/core/skills/qc/qa-reviewer/script/mobile/integration.md +41 -0
  37. package/core/skills/qc/qa-reviewer/script/mobile/non-functional.md +43 -0
  38. package/core/skills/qc/qa-reviewer/script/web/e2e.md +46 -0
  39. package/core/skills/qc/qa-reviewer/script/web/functional.md +111 -0
  40. package/core/skills/qc/qa-reviewer/script/web/integration.md +46 -0
  41. package/core/skills/qc/qa-reviewer/script/web/non-functional.md +49 -0
  42. package/core/skills/qc/qa-reviewer/shared/read-doc-gap-inputs.md +1 -1
  43. package/core/skills/qc/qa-reviewer/shared/review-file-template.md +26 -7
  44. package/core/skills/qc/qa-reviewer/test-case/e2e.md +1 -1
  45. package/core/skills/qc/qa-reviewer/test-case/exploratory.md +1 -1
  46. package/core/skills/qc/qa-reviewer/test-case/functional.md +1 -1
  47. package/core/skills/qc/qa-reviewer/test-case/integration.md +1 -1
  48. package/core/skills/qc/qa-reviewer/test-case/non-functional.md +1 -1
  49. package/core/skills/qc/qa-script-designer/_shared/api-conventions.md +94 -0
  50. package/core/skills/qc/qa-script-designer/_shared/file-naming-and-folders.md +109 -0
  51. package/core/skills/qc/qa-script-designer/_shared/mobile-conventions.md +196 -0
  52. package/core/skills/qc/qa-script-designer/_shared/web-conventions.md +257 -0
  53. package/core/skills/qc/qa-script-designer/api/auth.md +43 -0
  54. package/core/skills/qc/qa-script-designer/api/endpoint.md +61 -0
  55. package/core/skills/qc/qa-script-designer/api/security.md +41 -0
  56. package/core/skills/qc/qa-script-designer/mobile/e2e.md +35 -0
  57. package/core/skills/qc/qa-script-designer/mobile/functional/feature.md +32 -0
  58. package/core/skills/qc/qa-script-designer/mobile/functional/screen.md +42 -0
  59. package/core/skills/qc/qa-script-designer/mobile/integration.md +39 -0
  60. package/core/skills/qc/qa-script-designer/mobile/non-functional.md +39 -0
  61. package/core/skills/qc/qa-script-designer/web/e2e.md +36 -0
  62. package/core/skills/qc/qa-script-designer/web/functional/api.md +39 -0
  63. package/core/skills/qc/qa-script-designer/web/functional/gui-feature.md +34 -0
  64. package/core/skills/qc/qa-script-designer/web/functional/gui-screen.md +42 -0
  65. package/core/skills/qc/qa-script-designer/web/integration.md +43 -0
  66. package/core/skills/qc/qa-script-designer/web/non-functional.md +42 -0
  67. package/core/skills/qc/qa-script-runner/mobile/run.md +38 -0
  68. package/core/skills/qc/qa-script-runner/report.md +41 -0
  69. package/core/skills/qc/qa-script-runner/web/run.md +48 -0
  70. package/core/steps/qc-scope.md +43 -0
  71. package/core/steps/report-footer.md +2 -2
  72. package/docs/02-concepts/pipeline-steps/07-dev-selftest.md +1 -1
  73. package/docs/02-concepts/pipeline-steps/08-qc-automation.md +10 -10
  74. package/docs/02-concepts/pipeline-steps/10-feedback-loop.md +1 -1
  75. package/docs/02-concepts/traceability.md +1 -1
  76. package/docs/03-guides/developer.md +1 -1
  77. package/docs/03-guides/tester-qa.md +40 -12
  78. package/docs/04-reference/commands.md +1 -1
  79. package/docs/04-reference/modules.md +2 -1
  80. package/docs/explain/17-qc-design-test.md +2 -2
  81. package/docs/explain/19-qc-run-test.md +4 -4
  82. package/docs/explain/20-qc-report.md +1 -1
  83. package/docs/explain/23-fix-bug.md +2 -2
  84. package/docs/plans/qc-surgery/01-checklist.md +18 -6
  85. package/docs/plans/qc-surgery/PLAN_v2.md +295 -0
  86. package/docs/plans/qc-surgery/exec-S-ap-stack-typescript.md +420 -0
  87. package/docs/plans/qc-surgery/exec-S0-guard-cam-stack-cu.md +400 -0
  88. package/docs/plans/qc-surgery/exec-S1-hai-module-thay-qc-playwright.md +267 -0
  89. package/docs/plans/qc-surgery/exec-S2-qa-runner-thanh-script-designer-runner.md +340 -0
  90. package/docs/plans/qc-surgery/exec-S3-viet-lai-tieu-chi-review-script.md +322 -0
  91. package/docs/plans/qc-surgery/exec-S5-an-theo-don-dau-vet-stack-cu.md +292 -0
  92. package/package.json +1 -1
  93. package/core/modules/qc-playwright/stack-profile.yaml +0 -66
  94. package/core/skills/qc/qa-reviewer/script/e2e.md +0 -95
  95. package/core/skills/qc/qa-reviewer/script/functional.md +0 -109
  96. package/core/skills/qc/qa-reviewer/script/integration.md +0 -99
  97. package/core/skills/qc/qa-reviewer/script/non-functional.md +0 -134
  98. package/core/skills/qc/qa-runner/e2e.md +0 -49
  99. package/core/skills/qc/qa-runner/functional/api.md +0 -35
  100. package/core/skills/qc/qa-runner/functional/gui-feature.md +0 -57
  101. package/core/skills/qc/qa-runner/functional/gui-screen.md +0 -61
  102. package/core/skills/qc/qa-runner/integration.md +0 -47
  103. package/core/skills/qc/qa-runner/non-functional.md +0 -49
  104. package/core/skills/qc/qa-runner/report/report.md +0 -37
@@ -61,6 +61,23 @@ Mỗi trường 1 dòng, không bảng, không emoji dư:
61
61
  - **Status:** Draft
62
62
  - **Author:** AI
63
63
  - **Tags:** <lane>, <loại: smoke|sanity|regression>, <feature-tag>
64
+
65
+ **`<lane>` — giá trị hợp lệ** *(khai 2026-09-17; trước đó để ngỏ nên mỗi file viết một kiểu)*:
66
+
67
+ | Lane | Khi nào | Skill thiết kế |
68
+ |---|---|---|
69
+ | `ui` | có màn hình | `functional/gui-screen` · `gui-feature` |
70
+ | `api` | có endpoint, ai đó gọi vào | `functional/api` · `integration/api` |
71
+ | `job` | **tự chạy** theo lịch/điều kiện, không ai gọi | `functional/job` |
72
+ | `queue` | nằm chờ message rồi xử lý | `integration/queue` |
73
+ | `db` | verify trạng thái dữ liệu sau thao tác | `integration/db` |
74
+ | `e2e` | hành trình xuyên nhiều màn/hệ | `e2e/journey` |
75
+ | `nfr` | hiệu năng · bảo mật · a11y · i18n | `non-functional` |
76
+
77
+ > **Lane là câu trả lời đã chốt, không phải nhãn trang trí.** Với nền `system`, nó do **QC trả
78
+ > lời** ở trạm 3 khi không suy được hình dạng *(xem `/qc-design-test` §Nền `system`)*. Trạm 5 và
79
+ > trạm 6 **ĐỌC** lane này, **không suy lại** — suy lại là mở đường cho hai trạm kết luận khác nhau
80
+ > về cùng một TC.
64
81
  - **Trace:** BR-xx (ID gốc trong PRD/BDD ở `{paths.specs_dir}`)
65
82
  - **@trace.verifies:** {UC-ID}-SC{N}
66
83
  - **🚫 Block:** [GAP-UC{N}-{nnn}](../DOC_GAP.md) — <lý do> *(chỉ khi có)*
@@ -0,0 +1,121 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-17
4
+ source: upstream/qc-base-new/AGT-006-code_reviewer.md §3.1 §3.2 §3.3 §4 (Draft) · §5 Boundary
5
+ ---
6
+
7
+ # Luật soát script — dùng chung cho mọi nền
8
+
9
+ **Nạp file này TRƯỚC file lane.** Lane chỉ nói *"nền này soát thêm gì"*; mọi thứ ở đây đúng cho
10
+ cả `web` · `mobile` · `api`. Viết một bản vì 11 file lane đều cần — 11 bản của một luật là nơi
11
+ drift sống.
12
+
13
+ ---
14
+
15
+ ## 1 · Bảy luật của lượt soát *(R01–R07)*
16
+
17
+ | Mã | Luật | Nghĩa khi soát |
18
+ |---|---|---|
19
+ | **R01** | **Review All Files** | Soát **mọi** file được đưa: spec · Page/Screen/API Object · data. Soát một phần rồi kết luận là kết luận về một thứ chưa đọc |
20
+ | **R02** | **Evidence-Based Findings** | Mỗi lỗi phải có đủ **bốn**: tên file · số dòng (hoặc đoạn code) · mô tả vấn đề · cách sửa đề nghị. Thiếu một trong bốn thì đó là cảm tưởng, không phải finding |
21
+ | **R03** | **No Silent Pass** | Không `APPROVED` một script chưa soát kỹ. Soát đủ mà không thấy lỗi → `APPROVED` là **đúng**, không phải lười |
22
+ | **R04** | **No Rewriting** | Chỉ báo cáo, **không sửa code**. Đề xuất phải đủ rõ để người viết tự sửa được mà không hỏi lại |
23
+ | **R05** | **Positive Observations Required** | Mỗi lượt soát ghi **ít nhất 2–3 điểm tốt**. Một biên bản chỉ có lỗi là biên bản mất cân bằng — người đọc không biết phần nào đang đúng để giữ |
24
+ | **R06** | **Verdict Consistency** | Verdict suy ra từ **số đếm** finding theo §3, không tự nâng/hạ |
25
+ | **R07** | **Traceability First** | Thiếu/sai header artifact ID *(TC-ID · `@trace.verifies`)* ⇒ **BLOCKER ngay, dừng soát**. Không soát tiếp một file không biết nó phục vụ scenario nào |
26
+
27
+ > **R07 chặn cửa TRƯỚC, không phải sau.** Một lượt soát trên file không có trace tag vẫn chạy
28
+ > trót lọt và vẫn in ra verdict — nhưng verdict đó nói về một thứ không neo vào scenario nào.
29
+ > Đó là kiểu hỏng **Nói dối**: biên bản trông hợp lệ, nội dung vô nghĩa.
30
+
31
+ ---
32
+
33
+ ## 2 · Bốn mức nặng-nhẹ của một lỗi *(severity)*
34
+
35
+ | Mức | Định nghĩa | Ví dụ |
36
+ |---|---|---|
37
+ | **BLOCKER** | Ngăn test chạy đúng, hoặc vi phạm chuẩn lõi | selector thô trong spec · thiếu `await` · lỗi cú pháp · **không có header block** |
38
+ | **MAJOR** | Ảnh hưởng nặng tới khả năng bảo trì hoặc độ tin cậy | hard-code test data · `waitForTimeout` · locator bám class CSS tự sinh |
39
+ | **MINOR** | Vấn đề chất lượng code, script **vẫn chạy được** | thiếu type annotation · đặt tên không nhất quán · logic lặp có thể tách |
40
+ | **SUGGESTION** | Cơ hội cải thiện — **không bắt buộc** | tên biến rõ hơn · thông điệp assertion mô tả hơn |
41
+
42
+ **Ranh giới BLOCKER ↔ MAJOR đo được, không cảm tính:** BLOCKER là *"chạy sẽ sai hoặc không chạy"*;
43
+ MAJOR là *"chạy đúng hôm nay, hỏng khi có người sửa"*.
44
+
45
+ ---
46
+
47
+ ## 3 · Bốn verdict — suy ra từ số đếm, **không override**
48
+
49
+ | Verdict | Điều kiện bắt buộc | Đi tiếp? |
50
+ |---|---|:-:|
51
+ | **APPROVED** | 0 BLOCKER, 0 MAJOR | ✅ |
52
+ | **APPROVED_WITH_SUGGESTIONS** | 0 BLOCKER, 0 MAJOR, ≥1 MINOR hoặc SUGGESTION | ✅ |
53
+ | **REVISION_REQUIRED** | 0 BLOCKER, ≥1 MAJOR | ❌ sửa rồi soát lại |
54
+ | **REJECTED** | ≥1 BLOCKER | ❌ sửa rồi soát lại |
55
+
56
+ **Ngưỡng qua cửa: `≥ APPROVED_WITH_SUGGESTIONS`** — khai ở `AGT-005:132` và `AGT-010:130`.
57
+ Hai mức trên đi tiếp, hai mức dưới quay lại. Các trạm sau *(`/qc-run-script`)* đọc **hai luồng
58
+ này**, không đọc bốn tên.
59
+
60
+ > **Vì sao lane QC dùng 4 mức còn lane DEV *(`/review-code`)* giữ 2.** Lane QC có tài liệu chuẩn
61
+ > định nghĩa severity thành bốn ô đếm được *(§2)*, nên bốn verdict chỉ là **tên của bốn ô đó** —
62
+ > không thêm phán quyết nào. Lane DEV chưa có bảng severity tương ứng, nên 4 tên ở đó sẽ là bốn
63
+ > nhãn phải tự đoán. Đây là **một bất đối xứng có lý do**, không phải chỗ quên đồng bộ.
64
+
65
+ ---
66
+
67
+ ## 4 · Ranh giới — soát cái gì, KHÔNG soát cái gì
68
+
69
+ | | |
70
+ |---|---|
71
+ | ✅ **Soát** | code test đã sinh · Page/Screen/API Object · file data · khớp với `.Test.md` gốc |
72
+ | ❌ **KHÔNG soát** | **cấu trúc file test case** — đó là việc của `/qc-review-testcase`. Áp checklist cấu trúc TC vào một Page Object là bảo người soát đi tìm `#### Expected Result` trong code |
73
+ | ❌ **KHÔNG sửa** | *(R04)* — kể cả lỗi hiển nhiên một dòng |
74
+ | ❌ **KHÔNG chạy** | chạy test là việc của `/qc-run-script`. Ở đây chỉ compile/list để biết script **dịch được** và **thấy đủ số test** |
75
+
76
+ ---
77
+
78
+ ## 5 · Phép kiểm cơ học bắt buộc — trước khi kết luận
79
+
80
+ Chạy đủ hai lệnh, **dán output vào biên bản**:
81
+
82
+ ```
83
+ npx tsc --noEmit ← dịch được? (BLOCKER nếu lỗi)
84
+ npx playwright test <spec> --list ← đếm số test collect được (web · api)
85
+ npx wdio <config> --dry-run ← tương đương cho mobile
86
+ ```
87
+
88
+ **Số test collect được phải bằng số TC `Automatable: Y`** của phạm vi này trong
89
+ `AUTOMATION_ASSESSMENT.md`. Lệch là **BLOCKER** — không phải MINOR:
90
+
91
+ - collect **ít hơn** ⇒ có TC không được sinh, và nó sẽ nằm `not_run` vĩnh viễn trong sổ trace
92
+ - collect **nhiều hơn** ⇒ có test không neo vào TC nào, `qc_status` sẽ ghi cho một scenario không tồn tại
93
+
94
+ > Đây là chỗ duy nhất trong lượt soát mà **máy trả lời thay vì người** — nên nó là chỗ đáng tin
95
+ > nhất, và là lý do hai lệnh trên không được bỏ qua kể cả khi "nhìn code thấy ổn".
96
+
97
+ ---
98
+
99
+ ## 6 · Đường dẫn — lấy từ `§layout` của module, KHÔNG viết cứng
100
+
101
+ Nền đang soát đã được `steps/qc-scope.md` §2b phân giải. Gốc thư mục lấy từ `§layout` của
102
+ module tương ứng:
103
+
104
+ ```
105
+ web automation/tests/{TICKET-ID}/<feature>-<scenario>.spec.ts
106
+ automation/pages/<feature>.page.ts
107
+ api api-automation/tests/{TICKET-ID}/<feature>-<scenario>.spec.ts
108
+ api-automation/api/<resource>.api.ts
109
+ mobile mobile-automation/tests/{TICKET-ID}/<feature>-<scenario>.spec.ts
110
+ mobile-automation/screens/<feature>.screen.ts
111
+ ```
112
+
113
+ > **`tests/` chia theo `{TICKET-ID}`, `pages/`·`api/`·`screens/` để phẳng — có chủ ý.** Một spec
114
+ > **thuộc về** một PRD; một Page Object **được dùng bởi** nhiều PRD. Nhét Page Object vào thư mục
115
+ > PRD là ép nhân bản nó cho mỗi PRD — đúng thứ Page Object Pattern sinh ra để tránh.
116
+ >
117
+ > Thiếu segment `{TICKET-ID}` ở `tests/` thì hai PRD cùng có feature `login` ghi vào **cùng một
118
+ > đường dẫn** và đè nhau **im lặng**. Đó là lý do framework lệch khỏi bố cục phẳng của
119
+ > `Automation-Standards §2.3`: chuẩn giả định `tests/` soi gương theo `test-suites/`, còn ở đây
120
+ > test case sống ở `{qc_dir}/{TICKET-ID}/{platform}/test-cases/` — áp đúng **nguyên tắc** của
121
+ > chuẩn vào layout này thì ra hình dạng trên.
@@ -0,0 +1,49 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-17
4
+ source: upstream/qc-base-new/API-Testing-Standards.md §5.5 §9.1 (Approved)
5
+ ---
6
+
7
+ # Soát script — API xác thực & phân quyền
8
+
9
+ **Nạp `../_shared/review-rules.md` rồi `endpoint.md` cùng lane.** Đây là phần thêm.
10
+
11
+ ## Khi nào trigger
12
+ - Soát script kiểm đăng nhập, token, và **quyền truy cập** của từng vai lên từng endpoint.
13
+
14
+ ---
15
+
16
+ ## Thêm gì so với endpoint
17
+
18
+ ### A · Fixture token dùng chung *(§5.5)*
19
+
20
+ - Mỗi test tự đăng nhập lại ⇒ **MINOR** — chậm và dễ chạm rate-limit; dùng `fixtures/api.fixture.ts`
21
+ - Token hard-code / token thật commit vào repo ⇒ **BLOCKER**
22
+ - Fixture không phân biệt **vai** ⇒ **MAJOR**: một token dùng cho mọi test thì không kiểm được phân quyền
23
+
24
+ ### B · Mọi endpoint được bảo vệ phải có đủ ba ca *(§9.1)*
25
+
26
+ | Ca | Mong đợi |
27
+ |---|---|
28
+ | Không token | **401** |
29
+ | Token sai / hết hạn | **401** |
30
+ | Token đúng nhưng **sai vai** | **403** |
31
+
32
+ - Thiếu bất kỳ ca nào cho một endpoint được bảo vệ ⇒ **MAJOR**
33
+ - Gộp 401 và 403 thành một ca ⇒ **MAJOR** — hai lỗi khác nhau: *chưa biết anh là ai* vs *biết rồi
34
+ nhưng anh không được phép*
35
+
36
+ ### C · Assert phải là "bị chặn", không phải "không lỗi"
37
+
38
+ - `expect(res.status()).not.toBe(200)` ⇒ **MAJOR** — 500 cũng qua được phép assert này
39
+ - Assert đúng mã, và assert body **không rò dữ liệu** của tài nguyên bị cấm ⇒ thiếu ⇒ **MINOR**
40
+
41
+ ### D · Vòng đời token
42
+
43
+ - Không kiểm token hết hạn / refresh khi hợp đồng có ⇒ **MINOR**
44
+
45
+ ---
46
+
47
+ ## Kiểm cơ học + Output
48
+
49
+ Như `endpoint.md` Phase 3 và §Output.
@@ -0,0 +1,89 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-17
4
+ source: upstream/qc-base-new/API-Testing-Standards.md §4 §5 §6 §8 §10 §11 · AGT-010 §3 (Approved)
5
+ ---
6
+
7
+ # Soát script — API endpoint *(Playwright API mode + TypeScript)*
8
+
9
+ **Nạp `../_shared/review-rules.md` trước.** Lane này dùng khi `active_platform = system`.
10
+
11
+ > ⚠️ **API Object ≠ Page Object.** Không có màn hình, không có locator, không có wait. Soát API
12
+ > bằng checklist web là đi tìm những thứ không tồn tại rồi kết luận "không có lỗi".
13
+
14
+ ## Khi nào trigger
15
+ - Soát script kiểm **endpoint** của một service: CRUD, mã trạng thái, cấu trúc response.
16
+
17
+ ## Khi KHÔNG trigger
18
+ - Xác thực / phân quyền → `auth.md` · injection & input validation → `security.md`
19
+ - API gọi phụ trợ **bên trong** một dự án web *(setup/teardown)* → `../web/functional.md`
20
+
21
+ ---
22
+
23
+ ## Phase 1 — Đọc đủ *(R01)*
24
+
25
+ 1. `api-automation/tests/{TICKET-ID}/<feature>-*.spec.ts`
26
+ 2. `api-automation/api/<resource>.api.ts` + `base.api.ts`
27
+ 3. `data/<resource>.data.ts` · `fixtures/api.fixture.ts` · `helpers/schema.helper.ts`
28
+ 4. `.Test.md` + `AUTOMATION_ASSESSMENT.md`
29
+
30
+ **R07 chặn cửa** như mọi lane.
31
+
32
+ ---
33
+
34
+ ## Phase 2 — Năm nhóm soát
35
+
36
+ ### A · API Object *(§4 · AGT-010 R01)*
37
+
38
+ - **Mọi HTTP request phải đi qua API Object.** `request.post(...)` thô trong spec ⇒ **BLOCKER**
39
+ - `extends BaseAPI`; class `<Resource>API`; file `<resource>.api.ts`
40
+ - **1 method = 1 endpoint action**; method gộp nhiều endpoint ⇒ **MAJOR**
41
+ - Kiểu trả về `Promise<APIResponse>` — **không parse response trong API Object** ⇒ parse ⇒ **MAJOR**
42
+ - **Không `expect()` trong API Object** ⇒ có ⇒ **MAJOR**
43
+ - "God API Object" gom mọi resource ⇒ **MAJOR**
44
+
45
+ ### B · Cấu trúc spec *(§5 — AAA)*
46
+
47
+ - Ba khối rõ: **Arrange** (data, token) → **Act** (gọi API Object) → **Assert**
48
+ - Trộn assert vào giữa chuỗi gọi ⇒ **MINOR**
49
+ - Header block có TC-ID + `@trace.verifies` ⇒ thiếu ⇒ **BLOCKER** *(R07)*
50
+ - Data-driven dùng `for...of` hoặc `test.each`, không copy test 5 lần ⇒ copy ⇒ **MINOR**
51
+
52
+ ### C · Assertion *(§6)*
53
+
54
+ - **Assert mã trạng thái là bắt buộc** — thiếu ⇒ **BLOCKER**
55
+ - Assert **cả cấu trúc lẫn giá trị** của body, không chỉ `status === 200` ⇒ chỉ status ⇒ **MAJOR**
56
+ - Kiểm schema cho response có cấu trúc ⇒ thiếu ⇒ **MINOR**
57
+ - Assert header khi hợp đồng có nêu *(content-type, cache)* ⇒ thiếu ⇒ **MINOR**
58
+ - `expect(res.ok()).toBeTruthy()` làm assertion duy nhất ⇒ **MAJOR** — nó đúng cho mọi 2xx/3xx
59
+
60
+ ### D · Dữ liệu *(AGT-010 R03)*
61
+
62
+ - Credential, payload, giá trị mong đợi **hard-code trong spec** ⇒ **MAJOR** — để ở `data/`
63
+ - Bản ghi tạo ra phải xoá trong `afterEach`/`afterAll`, kể cả khi fail ⇒ thiếu ⇒ **MAJOR**
64
+ - Test phụ thuộc bản ghi có sẵn trên môi trường ⇒ **MAJOR**
65
+
66
+ ### E · Async *(AGT-010 R02)* và chất lượng *(§10 · §11)*
67
+
68
+ - **`waitForTimeout` tuyệt đối không dùng** — API là đồng bộ về bản chất, `await` thẳng ⇒ có ⇒ **BLOCKER**
69
+ - Thiếu `await` trước lời gọi API ⇒ **BLOCKER** *(test xanh giả, chạy xong trước khi có response)*
70
+ - TypeScript strict, không `any` ⇒ **MINOR**
71
+ - `test.only` sót lại ⇒ **BLOCKER**
72
+
73
+ ---
74
+
75
+ ## Phase 3 — Kiểm cơ học
76
+
77
+ ```
78
+ npx tsc --noEmit
79
+ npx playwright test --config=api-automation/playwright.config.ts <spec> --list
80
+ ```
81
+
82
+ Số test collect được **phải bằng** số TC `Automatable: Y`. Lệch ⇒ **BLOCKER**.
83
+
84
+ ---
85
+
86
+ ## Output
87
+
88
+ Theo `_shared/review-rules.md` §3, kèm ≥2–3 điểm tốt *(R05)*.
89
+ Lưu ý dãy ID của lane này độc lập: `TC-API-*` ≠ `TC-*` *(§7.3)*.
@@ -0,0 +1,46 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-17
4
+ source: upstream/qc-base-new/API-Testing-Standards.md §8 §9.2 (Approved)
5
+ ---
6
+
7
+ # Soát script — API kiểm tra đầu vào & injection
8
+
9
+ **Nạp `../_shared/review-rules.md` rồi `endpoint.md` cùng lane.** Đây là phần thêm.
10
+
11
+ ## Khi nào trigger
12
+ - Soát script kiểm **biên của đầu vào** và các mẫu injection lên endpoint.
13
+
14
+ ---
15
+
16
+ ## Thêm gì so với endpoint
17
+
18
+ ### A · Kỹ thuật thiết kế phải thấy được trong code *(§8)*
19
+
20
+ - **Phân lớp tương đương**: mỗi lớp có ít nhất một ca. Chỉ kiểm ca hợp lệ ⇒ **MAJOR**
21
+ - **Giá trị biên**: với trường có giới hạn, phải có `min-1` · `min` · `max` · `max+1`.
22
+ Thiếu hẳn phân tích biên cho trường có ràng buộc ⇒ **MAJOR**
23
+ - **Phủ HTTP method**: gọi method không được hỗ trợ phải trả **405**; thiếu ⇒ **MINOR**
24
+
25
+ ### B · Payload injection *(§9.2)*
26
+
27
+ - Payload **hard-code rải trong spec** ⇒ **MAJOR** — gom vào `data/`, một bộ dùng cho nhiều endpoint
28
+ - Bộ mẫu thiếu hẳn một họ *(SQL · NoSQL · command · path traversal · XSS lưu trữ)* ⇒ **MINOR**
29
+ kèm nêu rõ họ nào thiếu
30
+
31
+ ### C · Mong đợi phải cụ thể
32
+
33
+ - Mong đợi đúng là **400/422 + thông điệp lỗi có cấu trúc**, hoặc dữ liệu được làm sạch
34
+ - Assert kiểu "không sập" ⇒ **MAJOR** — một endpoint trả 200 kèm dữ liệu đã bị nhiễm vẫn "không sập"
35
+ - Assert thông điệp lỗi **không rò** stack trace / tên bảng / phiên bản ⇒ thiếu ⇒ **MINOR**
36
+
37
+ ### D · Ranh giới của trạm này
38
+
39
+ - Đây **không** phải kiểm thâm nhập. Soát script, không đánh giá mức độ an toàn của hệ thống.
40
+ Biên bản kết luận *"hệ thống an toàn"* ⇒ **MAJOR** — vượt thẩm quyền của lượt soát *(R04 tinh thần)*
41
+
42
+ ---
43
+
44
+ ## Kiểm cơ học + Output
45
+
46
+ Như `endpoint.md` Phase 3 và §Output.
@@ -13,7 +13,7 @@ Review session note sau khi test, coaching QC cải thiện kỹ năng.
13
13
  - Khi lead/senior muốn đánh giá chất lượng session của junior
14
14
 
15
15
  ## Khi KHÔNG trigger
16
- - Review Python script → dùng qa-reviewer/script/functional
16
+ - Soát script tự động → dùng `web/functional.md` · `mobile/functional.md` · `api/endpoint.md` theo nền
17
17
  - Review charter → dùng qa-reviewer/test-case/exploratory
18
18
 
19
19
  ---
@@ -41,7 +41,7 @@ Review session note sau khi test, coaching QC cải thiện kỹ năng.
41
41
 
42
42
  **Điểm `XX/100`** — ánh xạ mức độ sang điểm trừ: 🔴 = `FAIL` (−5đ) · 🟠 = `WARN` (−2đ) ·
43
43
  🟡 = ghi nhận, không trừ. ≥80 đạt · 60–79 cần cải thiện · <60 không đạt.
44
- **Verdict:** `≥80` không còn 🔴**`APPROVED`**; ngược lại **`NEEDS_FIX`**.
44
+ **Verdict:** suy từ **số đếm lỗi** theo `../shared/review-file-template.md` §Verdict — `≥1 BLOCKER` `REJECTED` · `≥1 MAJOR` `REVISION_REQUIRED` · chỉ MINOR/SUGGESTION → `APPROVED_WITH_SUGGESTIONS` · sạch → `APPROVED`.
45
45
 
46
46
  **Ghi vào `{qc_artifact_dir}test-cases/REVIEW_<FEATURE>.md`** — thêm một hàng vào bảng Tổng quan
47
47
  (cột `Tầng` phân biệt vai soát-code với vai soát-kịch-bản; **không ghi đè** hàng của vai kia).
@@ -0,0 +1,41 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-17
4
+ source: upstream/qc-base-new/Mobile-Automation-Standards.md §5 §9 §11 (Approved)
5
+ ---
6
+
7
+ # Soát script — Mobile E2E *(hành trình xuyên nhiều màn app)*
8
+
9
+ **Nạp `../_shared/review-rules.md` rồi `functional.md` cùng nền.**
10
+
11
+ ## Khi nào trigger
12
+ - Soát script đi trọn một hành trình trong app, qua nhiều màn.
13
+
14
+ ---
15
+
16
+ ## Thêm gì so với functional
17
+
18
+ ### A · Một hành trình = một test
19
+
20
+ - Chia thành nhiều `it()` phụ thuộc nhau ⇒ **BLOCKER** — chạy riêng lẻ là fail
21
+ - Chia chặng bằng `describe`/step để report Allure đọc được; >5 thao tác mà không chia ⇒ **MINOR**
22
+
23
+ ### B · Điều hướng và trạng thái app
24
+
25
+ - Quay lại bằng `driver.back()` mà không assert đã về đúng màn ⇒ **MAJOR**
26
+ - Không reset app giữa các hành trình *(`driver.reset()` hoặc fixture)* ⇒ **MAJOR** — trạng thái rò
27
+
28
+ ### C · Gesture trong hành trình dài
29
+
30
+ - Cuộn tìm phần tử phải có **giới hạn số lần**; cuộn vô hạn ⇒ **MAJOR** *(treo cho tới timeout)*
31
+
32
+ ### D · Flaky *(§11)*
33
+
34
+ - E2E mobile là nơi flaky sống nhất *(mạng + emulator + animation)*. Test đỏ-xanh thất thường mà
35
+ không tag `@flaky` ⇒ **MAJOR**
36
+
37
+ ---
38
+
39
+ ## Kiểm cơ học + Output
40
+
41
+ Như `functional.md` Phase 3 và §Output.
@@ -0,0 +1,90 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-17
4
+ source: upstream/qc-base-new/Mobile-Automation-Standards.md §4 §6 §7 §8 §9 §10 §11 §12 (Approved)
5
+ ---
6
+
7
+ # Soát script — Mobile Functional *(WebdriverIO + Appium + TypeScript)*
8
+
9
+ **Nạp `../_shared/review-rules.md` trước.** File này chỉ có phần riêng của nền app.
10
+
11
+ > ⚠️ **Đây KHÔNG phải bản web đổi tên.** Chuẩn mobile khác web ở bốn chỗ có thật: thứ tự locator,
12
+ > gesture, đối chiếu dữ liệu server, và kiểm môi trường. Soát mobile bằng checklist web là bỏ sót cả bốn.
13
+
14
+ ## Khi nào trigger
15
+ - Soát script functional cho nền `app` (`app-ios` · `app-android`), sau `/qc-design-script`.
16
+
17
+ ## Khi KHÔNG trigger
18
+ - Nền `web` → `../web/functional.md` · nền `system` → `../api/endpoint.md`
19
+
20
+ ---
21
+
22
+ ## Phase 1 — Đọc đủ *(R01)*
23
+
24
+ 1. `mobile-automation/tests/{TICKET-ID}/<feature>-*.spec.ts`
25
+ 2. `mobile-automation/screens/<feature>.screen.ts` + `base.screen.ts`
26
+ 3. `helpers/{api,device,gesture}.helper.ts` nếu spec dùng
27
+ 4. `wdio.config.ts` · `.env.example` — biết thiết bị và endpoint
28
+ 5. `.Test.md` + `AUTOMATION_ASSESSMENT.md`
29
+
30
+ **R07 chặn cửa** như mọi lane.
31
+
32
+ ---
33
+
34
+ ## Phase 2 — Sáu nhóm soát của nền app
35
+
36
+ ### A · Screen Object *(§4)* — KHÔNG gọi là Page
37
+
38
+ - `extends BaseScreen`; class `<Feature>Screen`; file `<feature>.screen.ts`
39
+ - Đặt tên `Page`/`page.ts` ở nền app ⇒ **MINOR** nhưng phải sửa — làm người sau tra nhầm chuẩn
40
+ - Không `expect()` trong Screen Object ⇒ **MAJOR**
41
+
42
+ ### B · Locator *(§7.1)* — thứ tự KHÁC HẲN web
43
+
44
+ ```
45
+ ~accessibilityId → id (resource-id) → xpath (cuối cùng, phải ghi lý do)
46
+ ```
47
+
48
+ - Dùng `getByRole` / `getByLabel` *(của web)* ⇒ **BLOCKER** — không tồn tại ở Appium
49
+ - `xpath` không kèm comment lý do ⇒ **MAJOR**
50
+ - `~accessibilityId` yêu cầu dev gán `content-desc`; locator trỏ id chưa có trong bảng §4.5.6
51
+ ⇒ **MAJOR** kèm đề nghị bổ sung vào tech-doc
52
+
53
+ ### C · Gesture *(§9)*
54
+
55
+ - Vuốt/cuộn viết tay bằng toạ độ **rải trong spec** ⇒ **MAJOR** — phải qua `helpers/gesture.helper.ts`
56
+ - Toạ độ hard-code không kèm ghi chú độ phân giải ⇒ **MINOR**: đúng trên một máy, sai trên máy khác
57
+
58
+ ### D · Đối chiếu dữ liệu server *(§6)*
59
+
60
+ - Spec `*-api-sync.spec.ts` phải dùng `helpers/api.helper.ts` *(Playwright `request`)*
61
+ - Chỉ assert trên màn hình, không đối chiếu server ⇒ **MAJOR**: một màn hiển thị đúng **dữ liệu cũ**
62
+ vẫn là bug, và UI assertion không bắt được
63
+
64
+ ### E · Wait *(§8)* và độ ổn định
65
+
66
+ - `browser.pause(...)` cứng ⇒ **MAJOR**; dùng `waitForDisplayed({ timeout })`
67
+ - Luồng có dialog quyền mà spec không xử lý ⇒ **MAJOR** — nó nuốt thao tác đầu tiên
68
+
69
+ ### F · Môi trường *(§12 — Gate 6B)*
70
+
71
+ - Đọc `API_BASE_URL` từ `.env`, hard-code ⇒ **MAJOR**
72
+ - Spec giả định emulator/APK sẵn sàng: **không** phải lỗi của spec, nhưng biên bản phải nhắc
73
+ checklist §12 chạy **trước** lượt execute
74
+
75
+ ---
76
+
77
+ ## Phase 3 — Kiểm cơ học
78
+
79
+ ```
80
+ npx tsc --noEmit
81
+ npx wdio ./wdio.config.ts --dry-run
82
+ ```
83
+
84
+ Số test phải bằng số TC `Automatable: Y`. Lệch ⇒ **BLOCKER**.
85
+
86
+ ---
87
+
88
+ ## Output
89
+
90
+ Theo `_shared/review-rules.md` §3, kèm ≥2–3 điểm tốt *(R05)*.
@@ -0,0 +1,41 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-17
4
+ source: upstream/qc-base-new/Mobile-Automation-Standards.md §5.3 §6 §8 (Approved)
5
+ ---
6
+
7
+ # Soát script — Mobile Integration *(app ↔ backend)*
8
+
9
+ **Nạp `../_shared/review-rules.md` rồi `functional.md` cùng nền.** Đây là phần thêm.
10
+
11
+ ## Khi nào trigger
12
+ - Soát script kiểm app **giao tiếp với server thật**: gửi lên, nhận về, đồng bộ sau thao tác.
13
+
14
+ ---
15
+
16
+ ## Thêm gì so với functional
17
+
18
+ ### A · `*-api-sync.spec.ts` là tầng này, không phải functional
19
+
20
+ - Chuẩn tách hẳn một loại spec cho việc này *(§5.3)*. Trộn kiểm đồng bộ vào spec functional
21
+ ⇒ **MINOR** — nhưng phải tách, vì hai loại có điều kiện môi trường khác nhau
22
+
23
+ ### B · Hai phía phải cùng được assert
24
+
25
+ - Thao tác trên app → assert UI **và** gọi `api.helper.ts` kiểm bản ghi trên server
26
+ - Chỉ một phía ⇒ **MAJOR**
27
+
28
+ ### C · Trạng thái mạng
29
+
30
+ - Không kiểm nhánh mất mạng / timeout khi `.Test.md` có ⇒ **MAJOR**
31
+ - Dùng `browser.setNetworkConditions` hoặc cơ chế tương đương, không mock ở tầng UI
32
+
33
+ ### D · Dọn dữ liệu
34
+
35
+ - Bản ghi tạo qua app phải được xoá qua API trong `after`, kể cả khi test fail ⇒ thiếu là **MAJOR**
36
+
37
+ ---
38
+
39
+ ## Kiểm cơ học + Output
40
+
41
+ Như `functional.md` Phase 3 và §Output.
@@ -0,0 +1,43 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-17
4
+ source: upstream/qc-base-new/Mobile-Automation-Standards.md §8 §11 §12 (Approved)
5
+ ---
6
+
7
+ # Soát script — Mobile Non-Functional
8
+
9
+ **Nạp `../_shared/review-rules.md` rồi `functional.md` cùng nền.**
10
+
11
+ ## Khi nào trigger
12
+ - Soát script kiểm thuộc tính phi chức năng của app: thời gian mở màn, bộ nhớ, quyền, đa thiết bị.
13
+
14
+ ---
15
+
16
+ ## Thêm gì so với functional
17
+
18
+ ### A · Ngưỡng là con số
19
+
20
+ - Assert hiệu năng không có ngưỡng cụ thể ⇒ **BLOCKER**
21
+ - Đo thời gian mở màn bằng mốc **sự kiện** *(`waitForDisplayed` trả về)*, không bằng `pause` rồi trừ
22
+
23
+ ### B · Quyền và bảo mật
24
+
25
+ - Kiểm từ chối quyền: phải assert app **xử lý được**, không crash ⇒ assert yếu ⇒ **MAJOR**
26
+ - Credential/token thật trong code ⇒ **BLOCKER**; đọc từ `.env`
27
+
28
+ ### C · Đa thiết bị
29
+
30
+ - Chạy đa cấu hình bằng **capabilities trong `wdio.config.ts`**, không lặp tay trong spec
31
+ ⇒ lặp tay ⇒ **MAJOR**
32
+ - Chỉ một emulator rồi gọi là kiểm tương thích ⇒ **MAJOR**
33
+
34
+ ### D · Môi trường *(§12)*
35
+
36
+ - Kết quả phi chức năng **không có nghĩa** nếu checklist Gate 6B chưa chạy. Biên bản phải nêu
37
+ đã chạy hay chưa; không nêu ⇒ **MINOR**
38
+
39
+ ---
40
+
41
+ ## Kiểm cơ học + Output
42
+
43
+ Như `functional.md` Phase 3 và §Output.
@@ -0,0 +1,46 @@
1
+ ---
2
+ version: 1.0
3
+ updated: 2026-09-17
4
+ source: upstream/qc-base-new/Automation-Standards.md §5 §11 (Approved)
5
+ ---
6
+
7
+ # Soát script — Web E2E *(hành trình xuyên nhiều màn)*
8
+
9
+ **Nạp `../_shared/review-rules.md` trước**, rồi `functional.md` cùng nền.
10
+
11
+ ## Khi nào trigger
12
+ - Soát script đi **trọn một hành trình người dùng** qua nhiều màn, nhiều vai.
13
+
14
+ ## Khi KHÔNG trigger
15
+ - Một màn → `functional.md` · hai thành phần → `integration.md`
16
+
17
+ ---
18
+
19
+ ## Thêm gì so với functional
20
+
21
+ ### A · Hành trình phải là một test
22
+
23
+ - Chia hành trình thành nhiều `test()` phụ thuộc nhau ⇒ **BLOCKER** — chạy riêng lẻ là fail,
24
+ và Playwright **không bảo đảm thứ tự** khi chạy song song
25
+ - Một hành trình = một `test()`, các chặng chia bằng `test.step()` để report đọc được
26
+ - Thiếu `test.step()` cho hành trình >5 thao tác ⇒ **MINOR** — fail ở đâu không ai biết
27
+
28
+ ### B · Vai và phiên
29
+
30
+ - Đổi vai giữa chừng phải qua `storageState` riêng hoặc `browser.newContext()`, **không**
31
+ logout/login trong cùng context ⇒ làm sai ⇒ **MAJOR** *(rò trạng thái giữa hai vai)*
32
+
33
+ ### C · Độ dài và chi phí
34
+
35
+ - Hành trình >15 chặng mà không tách được ⇒ **MINOR** kèm đề nghị tách; E2E dài là E2E flaky
36
+ - E2E **không** kiểm lại thứ functional đã kiểm — trùng lặp ⇒ **SUGGESTION**
37
+
38
+ ### D · Flaky
39
+
40
+ - E2E là nơi flaky sống *(§11)*. Không có tag `@flaky` cho test đã đỏ-xanh thất thường ⇒ **MAJOR**
41
+
42
+ ---
43
+
44
+ ## Kiểm cơ học + Output
45
+
46
+ Như `functional.md` Phase 3 và §Output.