@relipa/ai-flow-kit 0.1.2 → 0.1.4-beta.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. package/README.md +139 -0
  2. package/bin/aiflow.js +89 -2
  3. package/custom/harness/playwright/.env.example +10 -0
  4. package/custom/harness/playwright/playwright.config.ts +34 -0
  5. package/custom/harness/playwright/tests/e2e/auth.setup.ts +25 -0
  6. package/custom/harness/playwright/tests/e2e/fixtures/test.ts +6 -0
  7. package/custom/harness/playwright/tests/e2e/pages/BasePage.ts +9 -0
  8. package/custom/harness/playwright/tests/e2e/support/auth.ts +5 -0
  9. package/custom/mcp-presets/playwright.json +8 -0
  10. package/custom/rules/test-patterns.md +70 -0
  11. package/custom/skills/automation-testing/SKILL.md +239 -0
  12. package/custom/skills/automation-testing/templates/BasePage.ts +29 -0
  13. package/custom/skills/automation-testing/templates/PageObject.example.ts +29 -0
  14. package/custom/skills/automation-testing/templates/playwright.config.ts +39 -0
  15. package/custom/skills/automation-testing/templates/spec.example.ts +29 -0
  16. package/custom/skills/ba-skills/skill-ba-phan-tich-ban-dau-v1.md +44 -0
  17. package/custom/skills/ba-skills/skill-ba-prototype-v1.md +35 -0
  18. package/custom/skills/ba-skills/skill-ba-qa-template-v1.md +21 -0
  19. package/custom/skills/ba-skills/skill-ba-qa-v1.md +35 -0
  20. package/custom/skills/ba-skills/skill-ba-template-phan-tich-ban-dau-v1.md +30 -0
  21. package/custom/skills/ba-skills/skill-ba-template-uc-v1.md +83 -0
  22. package/custom/skills/ba-skills/skill-ba-ve-luong-mermaid-v1.md +35 -0
  23. package/custom/skills/ba-skills/skill-ba-viet-spec-uc-v1.md +38 -0
  24. package/custom/skills/ba-skills/skill-ba-xay-dung-business-rules-v1.md +39 -0
  25. package/custom/skills/coverage-check/SKILL.md +202 -0
  26. package/custom/skills/evidence-aggregation/SKILL.md +246 -0
  27. package/custom/skills/execute-flow/SKILL.md +499 -0
  28. package/custom/skills/execute-flow/templates/playwright.config.ts +39 -0
  29. package/custom/skills/gate-review/SKILL.md +195 -0
  30. package/custom/skills/generate-test-report/SKILL.md +99 -0
  31. package/custom/skills/generate-test-report/templates/test-report.md +58 -0
  32. package/custom/skills/generate-testcase/SKILL.md +350 -0
  33. package/custom/skills/generate-testcase/templates/testcase.md +88 -0
  34. package/custom/skills/log-bug/SKILL.md +131 -0
  35. package/custom/skills/pr-impact-analysis/SKILL.md +180 -0
  36. package/custom/skills/retest-orchestration/SKILL.md +191 -0
  37. package/custom/skills/script-sync/SKILL.md +208 -0
  38. package/custom/skills/test-analysis/SKILL.md +300 -0
  39. package/custom/skills/test-skills/categories/00-core/00.01.requirement-analysis.md +111 -0
  40. package/custom/skills/test-skills/categories/00-core/00.02.risk-analysis.md +24 -0
  41. package/custom/skills/test-skills/categories/00-core/00.03.test-scenario-builder.md +90 -0
  42. package/custom/skills/test-skills/categories/00-core/00.04.testcase-review.md +68 -0
  43. package/custom/skills/test-skills/categories/01-test-design/01.01.boundary-value-analysis.md +30 -0
  44. package/custom/skills/test-skills/categories/01-test-design/01.02.equivalence.partitioning.md +27 -0
  45. package/custom/skills/test-skills/categories/01-test-design/01.03.decision-table.md +26 -0
  46. package/custom/skills/test-skills/categories/01-test-design/01.04.state.transition.md +26 -0
  47. package/custom/skills/test-skills/categories/01-test-design/01.05.pairwise.md +25 -0
  48. package/custom/skills/test-skills/categories/01-test-design/01.06.error-guessing.md +28 -0
  49. package/custom/skills/test-skills/categories/02-ui-testing/02.01.UI-layout.md +29 -0
  50. package/custom/skills/test-skills/categories/02-ui-testing/02.02.form-validation.md +57 -0
  51. package/custom/skills/test-skills/categories/02-ui-testing/02.03.navigation.md +27 -0
  52. package/custom/skills/test-skills/categories/02-ui-testing/02.04.localization.md +27 -0
  53. package/custom/skills/test-skills/categories/02-ui-testing/02.05.accessibility.md +27 -0
  54. package/custom/skills/test-skills/categories/03-business-testing/03.01.CRUD-testing.md +51 -0
  55. package/custom/skills/test-skills/categories/03-business-testing/03.02.workflow-testing.md +44 -0
  56. package/custom/skills/test-skills/categories/03-business-testing/03.03.permission-testing.md +41 -0
  57. package/custom/skills/test-skills/categories/03-business-testing/03.04.dependency-validation.md +40 -0
  58. package/custom/skills/test-skills/categories/03-business-testing/03.05.notification-testing.md +43 -0
  59. package/custom/skills/test-skills/categories/03-business-testing/03.06.calculation.testing.md +44 -0
  60. package/custom/skills/test-skills/categories/04-data-testing/04.01.database-testing.md +43 -0
  61. package/custom/skills/test-skills/categories/04-data-testing/04.02.import-export-testing.md +43 -0
  62. package/custom/skills/test-skills/categories/04-data-testing/04.03.data-mapping.md +39 -0
  63. package/custom/skills/test-skills/categories/04-data-testing/04.04.duplicate-handling.md +39 -0
  64. package/custom/skills/test-skills/categories/04-data-testing/04.05.migration.md +42 -0
  65. package/custom/skills/test-skills/categories/05-integration/05.01.API-testing.md +37 -0
  66. package/custom/skills/test-skills/categories/05-integration/05.02.third-party-integration.md +36 -0
  67. package/custom/skills/test-skills/categories/05-integration/05.03.batch-processing.md +38 -0
  68. package/custom/skills/test-skills/categories/05-integration/05.04.file-upload-download.md +40 -0
  69. package/custom/skills/test-skills/categories/08-domain-skills/CMS.md +34 -0
  70. package/custom/skills/test-skills/categories/08-domain-skills/Ecommerce.md +35 -0
  71. package/custom/skills/test-skills/categories/99-review/99.01.coverage-review.md +35 -0
  72. package/custom/skills/test-skills/categories/99-review/99.02.knowledge-learning.md +34 -0
  73. package/custom/skills/test-skills/categories/99-review/99.03.repository-update.md +33 -0
  74. package/custom/skills/test-skills/categories/99-review/99.04.change-history.md +38 -0
  75. package/custom/skills/test-skills/rules/Directory_and_Naming_Convention.md +257 -0
  76. package/custom/skills/test-skills/rules/QA_Writing_Standards.md +49 -0
  77. package/custom/skills/test-skills/template/template_testcase.md +92 -0
  78. package/custom/templates/shared/create-spec-workflow.md +441 -0
  79. package/custom/templates/shared/create-testcase-workflow.md +470 -0
  80. package/custom/templates/shared/gate-workflow.md +421 -11
  81. package/docs/common/CHANGELOG.md +52 -0
  82. package/docs/common/QUICK_START.md +30 -0
  83. package/docs/common/cli-reference.md +48 -7
  84. package/package.json +2 -2
  85. package/scripts/create-score-excel.js +37 -14
  86. package/scripts/detect.js +10 -0
  87. package/scripts/guide.js +9 -0
  88. package/scripts/init.js +48 -1
  89. package/scripts/prompt.js +36 -0
  90. package/scripts/review.js +91 -0
  91. package/scripts/scaffold-playwright.js +106 -0
  92. package/scripts/task.js +21 -7
  93. package/scripts/update.js +127 -124
  94. package/scripts/use.js +36 -12
@@ -0,0 +1,239 @@
1
+ ---
2
+ name: automation-testing
3
+ description: Sinh Playwright TypeScript E2E test từ test case draft của tester. Dùng Playwright MCP để xem DOM THẬT của app và lấy selector chính xác (không đoán). Dùng khi tester muốn tạo script test tự động từ mô tả test case bằng ngôn ngữ tự nhiên.
4
+ allowed-tools: Read, Write, Edit, Glob, Grep, Bash, mcp__playwright__browser_navigate, mcp__playwright__browser_snapshot, mcp__playwright__browser_generate_locator, mcp__playwright__browser_click, mcp__playwright__browser_type, mcp__playwright__browser_fill_form, mcp__playwright__browser_select_option, mcp__playwright__browser_press_key, mcp__playwright__browser_wait_for, mcp__playwright__browser_take_screenshot, mcp__playwright__browser_console_messages, mcp__playwright__browser_navigate_back, mcp__playwright__browser_close
5
+ ---
6
+
7
+ # Skill: automation-testing
8
+
9
+ Sinh **Playwright TypeScript** test scripts từ test case draft của tester.
10
+ Điểm khác biệt cốt lõi so với "sinh code thuần": skill **mở app thật bằng Playwright MCP**,
11
+ chụp cây accessibility/DOM và sinh selector từ element CÓ THẬT — nên script chạy được ngay,
12
+ tester không cần biết TypeScript và hạn chế tối đa việc nhờ dev sửa selector.
13
+
14
+ ## Cách gọi
15
+
16
+ ```
17
+ /automation-testing baseUrl: <url> [autoRun: true|false] [headed: true|false] [ticketId: <id>]
18
+ ---
19
+ <test case draft của tester — text tự do, mỗi dòng một case>
20
+ ```
21
+
22
+ Ví dụ:
23
+ ```
24
+ /automation-testing baseUrl: http://localhost:3000 autoRun: false
25
+ ---
26
+ 1. Vào trang login, nhập đúng email/password → vào được dashboard
27
+ 2. Nhập sai password → hiện thông báo lỗi
28
+ 3. Để trống email → hiện validation lỗi
29
+ ```
30
+
31
+ ## Tham số (parse từ phần đầu lời gọi)
32
+
33
+ Đọc các tham số từ text người dùng truyền vào (dạng `key: value`). Nếu không thấy, dùng default.
34
+
35
+ | Param | Default | Ý nghĩa |
36
+ |------------|---------|---------|
37
+ | `baseUrl` | — | URL web app đang test. **Bắt buộc.** Nếu thiếu → hỏi tester rồi mới tiếp tục. |
38
+ | `autoRun` | `false` | Tự chạy `npx playwright test` sau khi sinh script. |
39
+ | `headed` | `true` | Hiện cửa sổ browser khi `autoRun=true`. |
40
+ | `ticketId` | suy ra | Thư mục con cho spec (`tests/e2e/specs/<ticketId>/`). Nếu thiếu → suy từ tên feature (vd `login`). |
41
+
42
+ Phần text sau dấu `---` là **test case draft**.
43
+
44
+ ---
45
+
46
+ ## Phase 1 — Collect (Thu thập input)
47
+
48
+ Đọc tất cả nguồn có sẵn, theo thứ tự ưu tiên:
49
+
50
+ 1. `plan/<ticketId>/requirement.md` (nếu có) — dùng `Read`.
51
+ 2. `plan/<ticketId>/plan.md` (nếu có).
52
+ 3. **Test case draft** — phần text sau `---` trong lời gọi.
53
+ 4. `custom/rules/test-patterns.md` — các pattern chuẩn (login, CRUD, form, modal...). **Luôn đọc file này** để áp dụng quy ước chung.
54
+
55
+ Kiểm tra điều kiện tiên quyết:
56
+ - Thiếu `baseUrl` → hỏi tester, dừng lại chờ.
57
+ - Không có bất kỳ test case nào (cả draft lẫn requirement) → hỏi:
58
+ > "Bạn muốn test feature gì? Hãy mô tả các test case hoặc paste test case draft vào đây."
59
+
60
+ ---
61
+
62
+ ## Phase 2 — Analyze (Sinh danh sách test case có cấu trúc)
63
+
64
+ Phân tích tất cả input và lập bảng test case:
65
+
66
+ ```
67
+ ## Test Cases — <Feature Name>
68
+
69
+ | ID | Tên test case | Steps | Expected Result |
70
+ |------|--------------------------|------------------------------------------------|----------------------------|
71
+ | TC01 | Đăng nhập thành công | 1. Vào /login 2. Nhập email+pass hợp lệ 3. Submit | Redirect về /dashboard |
72
+ | TC02 | Sai mật khẩu | 1. Vào /login 2. Nhập sai pass 3. Submit | Hiện error message |
73
+ | TC03 | Để trống email | 1. Vào /login 2. Submit ngay | Hiện "Email là bắt buộc" |
74
+ ```
75
+
76
+ > ⚠️ **GATE 1 — BẮT BUỘC.** Hiển thị bảng và hỏi:
77
+ > "Danh sách test cases trên đã đúng chưa? Cần thêm/sửa/xóa case nào không?
78
+ > Xác nhận để tôi mở app và lấy selector thật."
79
+ >
80
+ > **Dừng lại, chờ tester xác nhận.** Không tự chuyển Phase 3.
81
+
82
+ ---
83
+
84
+ ## Phase 3 — Explore (Khám phá DOM thật qua Playwright MCP) 🔑
85
+
86
+ Đây là bước quyết định độ chính xác. **Không được đoán selector** — phải lấy từ app thật.
87
+
88
+ Với mỗi trang/màn hình liên quan trong các test case đã chốt:
89
+
90
+ 1. `mcp__playwright__browser_navigate` tới `<baseUrl><path>` (vd `http://localhost:3000/login`).
91
+ 2. `mcp__playwright__browser_snapshot` để lấy cây accessibility (role, name, ref của từng element).
92
+ 3. Với từng element cần thao tác (input, button, message...), dùng
93
+ `mcp__playwright__browser_generate_locator` để lấy **locator Playwright chuẩn** từ element thật.
94
+ 4. Nếu một test case cần đi qua nhiều bước (vd phải submit mới hiện error), dùng
95
+ `browser_type` / `browser_fill_form` / `browser_click` để **đi tới đúng trạng thái** rồi
96
+ `browser_snapshot` lại để lấy selector của element xuất hiện sau đó (error message, modal...).
97
+ 5. Ghi lại bảng ánh xạ: phần tử logic → locator thật. Ví dụ:
98
+
99
+ ```
100
+ Email field → getByRole('textbox', { name: 'Email' })
101
+ Password field→ getByLabel('Mật khẩu')
102
+ Submit button → getByRole('button', { name: 'Đăng nhập' })
103
+ Error message → getByText('Sai tên đăng nhập hoặc mật khẩu')
104
+ ```
105
+
106
+ Quy tắc ưu tiên locator (theo Playwright best practice):
107
+ `getByRole` > `getByLabel` > `getByPlaceholder` > `getByText` > `getByTestId` > CSS.
108
+ Chỉ dùng CSS/XPath khi không còn cách nào khác, và ghi chú lý do.
109
+
110
+ > ⚠️ **Nếu không mở được app** (baseUrl sai, app chưa chạy, route không tồn tại):
111
+ > báo rõ cho tester, **không** sinh selector đoán mò. Hỏi tester sửa baseUrl / khởi động app.
112
+ >
113
+ > Đóng browser bằng `mcp__playwright__browser_close` khi khám phá xong.
114
+
115
+ ### Nếu app yêu cầu đăng nhập (auth)
116
+
117
+ Khi feature cần test nằm sau màn hình login:
118
+
119
+ 1. Khám phá selector trang login bằng MCP (như trên).
120
+ 2. Cập nhật `tests/e2e/auth.setup.ts`: thay 3 dòng locator mặc định (Email / Mật khẩu /
121
+ nút Đăng nhập) bằng **selector thật** vừa khám phá, và chỉnh `expectPathAfterLogin`.
122
+ 3. Hỏi tester **tài khoản test** (không hardcode tài khoản thật). Hướng dẫn họ điền vào `.env`:
123
+ `E2E_USER`, `E2E_PASSWORD`, `E2E_LOGIN_PATH`, `E2E_POST_LOGIN_PATH` (xem `.env.example`).
124
+ Có `E2E_USER` → auth tự bật: project `setup` đăng nhập 1 lần, lưu `.auth/user.json`,
125
+ các test sau tái dùng phiên (không login lại từng test).
126
+ 4. Test mà bản thân nó cần trạng thái **CHƯA đăng nhập** (vd chính test login/logout):
127
+ thêm ở đầu spec `test.use({ storageState: LOGGED_OUT })` (import `LOGGED_OUT` từ
128
+ `../../fixtures/test`).
129
+
130
+ ---
131
+
132
+ ## Phase 4 — Generate (Sinh script với selector thật)
133
+
134
+ Sinh file theo cấu trúc:
135
+
136
+ ```
137
+ tests/e2e/
138
+ ├── pages/
139
+ │ ├── BasePage.ts ← chỉ tạo nếu chưa có (đã có sẵn trong repo)
140
+ │ └── <Feature>Page.ts ← Page Object, locator lấy từ Phase 3
141
+ ├── specs/
142
+ │ └── <ticketId>/
143
+ │ └── <feature>.spec.ts ← nhóm nhiều TCs (xem quy tắc bên dưới)
144
+ └── fixtures/test.ts ← chỉ tạo nếu chưa có (đã có sẵn)
145
+ ```
146
+
147
+ Khi được gọi từ `coverage-check` (Phase 2d), output vào `test-plan/test-scripts/`:
148
+
149
+ ```
150
+ test-plan/test-scripts/
151
+ ├── AD10_001.spec.ts ← mỗi TC_ID một file riêng
152
+ ├── AD10_002.spec.ts
153
+ └── ...
154
+ ```
155
+
156
+ Quy tắc sinh code:
157
+
158
+ - **`<Feature>Page.ts`**: kế thừa `BasePage`. Khai báo tất cả `Locator` ở constructor,
159
+ **dùng đúng locator lấy được ở Phase 3**. Mỗi hành động là một async method (vd `login()`).
160
+ Tham khảo `templates/PageObject.example.ts` để biết style.
161
+
162
+ - **Đặt tên test function — bắt buộc chứa TC_ID:**
163
+ ```typescript
164
+ // ScreenID là mã màn hình/chức năng của từng dự án (AD10, LOGIN, ORD, ... — không cố định)
165
+ test.describe('[ScreenID] — Tên màn hình', () => {
166
+ test('[ScreenID_001] Mô tả scenario đầu tiên', async ({ page }) => {
167
+ // ...
168
+ })
169
+ test('[ScreenID_002] Mô tả scenario thứ hai', async ({ page }) => {
170
+ // ...
171
+ })
172
+ })
173
+ ```
174
+ Ví dụ thực tế (ScreenID tùy dự án): `[AD10_001]`, `[LOGIN_001]`, `[ORD_002]`
175
+
176
+ Format bắt buộc: `'[TC_ID] Mô tả scenario'` — TC_ID phải nằm ở **đầu tên test**, trong dấu `[]`.
177
+ Mục đích: khi chạy `--grep "AD10_001"` (hoặc TC_ID thực tế) sẽ select đúng test case, và kết quả map 1-1 với testcase document.
178
+
179
+ - **`<feature>.spec.ts`**: import `{ test, expect }` từ `../../fixtures/test`.
180
+ dùng `test.describe('[ScreenID]', ...)` để nhóm. Assertion rõ ràng (`expect(...).toBeVisible()`...).
181
+ - **Không tạo lại** `BasePage.ts` / `playwright.config.ts` / `fixtures/test.ts` /
182
+ `auth.setup.ts` / `support/auth.ts` nếu đã tồn tại (kiểm tra bằng `Glob` trước) —
183
+ với `auth.setup.ts` chỉ **sửa locator/đường dẫn**, không ghi đè toàn bộ.
184
+
185
+ ### Incremental Update — chỉ generate scripts mới hoặc đã thay đổi
186
+
187
+ Khi được gọi với danh sách TC_IDs (từ `coverage-check` hoặc sau khi TESTER update testcases):
188
+
189
+ 1. **Kiểm tra scripts đã tồn tại:** `Glob` tìm các file trong `test-plan/test-scripts/*.spec.ts`
190
+ 2. **Phân loại từng TC_ID:**
191
+ - Nếu `[TC_ID].spec.ts` **chưa tồn tại** → `[NEW]` — sinh script mới
192
+ - Nếu `[TC_ID].spec.ts` **đã tồn tại** và TC nằm trong danh sách "đã thay đổi" (do TESTER chỉ định) → `[UPDATED]` — regenerate, overwrite
193
+ - Nếu `[TC_ID].spec.ts` **đã tồn tại** và không trong danh sách thay đổi → `[SKIP]` — không đụng vào
194
+ 3. **Chỉ mở DOM/Playwright MCP cho TCs cần generate** (`[NEW]` và `[UPDATED]`)
195
+ 4. **Báo cáo kết quả:**
196
+ ```
197
+ Script generation complete:
198
+ [NEW] AD10_005.spec.ts — created
199
+ [UPDATED] AD10_002.spec.ts — regenerated (TC content changed)
200
+ [SKIP] AD10_001.spec.ts — unchanged, kept existing
201
+ [SKIP] AD10_003.spec.ts — unchanged, kept existing
202
+ ```
203
+
204
+ Khi TESTER không chỉ định danh sách thay đổi (chạy lần đầu từ `coverage-check`), generate TẤT CẢ TCs có `Type = Auto` trong `final-testcases.md` mà chưa có script.
205
+
206
+ ---
207
+
208
+ ## Phase 5 — Execute
209
+
210
+ Set `BASE_URL` = `baseUrl` khi chạy để Playwright dùng đúng app.
211
+
212
+ ### autoRun = false (default)
213
+ In hướng dẫn chạy thủ công:
214
+ ```
215
+ ✅ Đã sinh script xong!
216
+
217
+ Chạy test:
218
+ BASE_URL=<baseUrl> npx playwright test tests/e2e/specs/<ticketId>/
219
+ BASE_URL=<baseUrl> npx playwright test --headed # hiện browser
220
+ npx playwright test --ui # mở Playwright UI
221
+ Xem report:
222
+ npx playwright show-report
223
+ ```
224
+
225
+ ### autoRun = true
226
+ 1. Chạy bằng `Bash`:
227
+ `BASE_URL=<baseUrl> npx playwright test tests/e2e/specs/<ticketId>/ <--headed nếu headed=true>`
228
+ 2. Tóm tắt pass/fail cho tester (dễ đọc, không bắt đọc log thô).
229
+ 3. Nếu có test fail: chỉ ra TC nào fail, lý do, và đề xuất sửa.
230
+ In `npx playwright show-report` để mở HTML report.
231
+
232
+ ---
233
+
234
+ ## Nguyên tắc chung
235
+
236
+ - **Gate trước khi sinh code** (Phase 2) là bắt buộc — tránh sinh sai hàng loạt.
237
+ - **Selector phải đến từ DOM thật** (Phase 3) — đây là lý do tồn tại của skill này.
238
+ - Viết test case, tên test, comment bằng **tiếng Việt** cho khớp draft của tester.
239
+ - Nếu app yêu cầu đăng nhập trước, hỏi tester credentials test (đừng hardcode tài khoản thật).
@@ -0,0 +1,29 @@
1
+ import { Page, Locator } from '@playwright/test'
2
+
3
+ export abstract class BasePage {
4
+ readonly page: Page
5
+
6
+ constructor(page: Page) {
7
+ this.page = page
8
+ }
9
+
10
+ async navigate(path: string) {
11
+ await this.page.goto(path)
12
+ await this.waitForLoad()
13
+ }
14
+
15
+ async waitForLoad() {
16
+ await this.page.waitForLoadState('networkidle')
17
+ }
18
+
19
+ async takeScreenshot(name: string) {
20
+ await this.page.screenshot({
21
+ path: `evidence/${name}.png`,
22
+ fullPage: true,
23
+ })
24
+ }
25
+
26
+ async getPageTitle(): Promise<string> {
27
+ return this.page.title()
28
+ }
29
+ }
@@ -0,0 +1,29 @@
1
+ // TEMPLATE THAM CHIẾU — không phải file chạy thật.
2
+ // Skill dùng style này để sinh tests/e2e/pages/<Feature>Page.ts.
3
+ // CÁC LOCATOR DƯỚI ĐÂY LÀ VÍ DỤ — khi sinh thật phải thay bằng locator
4
+ // lấy từ Phase 3 (Playwright MCP browser_snapshot / browser_generate_locator).
5
+
6
+ import { Page, Locator } from '@playwright/test';
7
+ import { BasePage } from './BasePage';
8
+
9
+ export class LoginPage extends BasePage {
10
+ readonly emailInput: Locator;
11
+ readonly passwordInput: Locator;
12
+ readonly submitButton: Locator;
13
+ readonly errorMessage: Locator;
14
+
15
+ constructor(page: Page) {
16
+ super(page);
17
+ // ↓ Locator THẬT lấy từ DOM ở Phase 3, ưu tiên getByRole > getByLabel > ...
18
+ this.emailInput = page.getByRole('textbox', { name: 'Email' });
19
+ this.passwordInput = page.getByLabel('Mật khẩu');
20
+ this.submitButton = page.getByRole('button', { name: 'Đăng nhập' });
21
+ this.errorMessage = page.getByText('Sai tên đăng nhập hoặc mật khẩu');
22
+ }
23
+
24
+ async login(email: string, password: string): Promise<void> {
25
+ await this.emailInput.fill(email);
26
+ await this.passwordInput.fill(password);
27
+ await this.submitButton.click();
28
+ }
29
+ }
@@ -0,0 +1,39 @@
1
+ import { defineConfig, devices } from '@playwright/test'
2
+
3
+ export default defineConfig({
4
+ testDir: './tests/e2e/specs',
5
+ fullyParallel: false,
6
+ forbidOnly: !!process.env.CI,
7
+ retries: process.env.CI ? 2 : 0,
8
+ workers: 1,
9
+ reporter: [
10
+ ['html', { outputFolder: 'playwright-report' }],
11
+ ['json', { outputFile: 'test-results/results.json' }],
12
+ ],
13
+
14
+ use: {
15
+ baseURL: process.env.BASE_URL || 'http://localhost:3000',
16
+ trace: 'on-first-retry',
17
+ screenshot: 'only-on-failure',
18
+ video: 'on-first-retry',
19
+ headless: !process.env.HEADED,
20
+ locale: 'vi-VN',
21
+ },
22
+
23
+ projects: [
24
+ // Auth setup (chỉ chạy khi có E2E_USER trong .env)
25
+ ...(process.env.E2E_USER
26
+ ? [{ name: 'setup', testMatch: /auth\.setup\.ts/ }]
27
+ : []),
28
+ {
29
+ name: 'chromium',
30
+ use: {
31
+ ...devices['Desktop Chrome'],
32
+ ...(process.env.E2E_USER ? { storageState: '.auth/user.json' } : {}),
33
+ },
34
+ dependencies: process.env.E2E_USER ? ['setup'] : [],
35
+ },
36
+ ],
37
+
38
+ outputDir: 'test-results',
39
+ })
@@ -0,0 +1,29 @@
1
+ // TEMPLATE THAM CHIẾU — không phải file chạy thật.
2
+ // Skill dùng style này để sinh tests/e2e/specs/<ticketId>/<feature>.spec.ts.
3
+ // ID test (TC01...) phải khớp bảng test case đã chốt ở Phase 2.
4
+
5
+ import { test, expect } from '../../fixtures/test';
6
+ import { LoginPage } from '../../pages/LoginPage';
7
+
8
+ test.describe('Đăng nhập hệ thống', () => {
9
+ test('TC01 - Đăng nhập thành công với credentials hợp lệ', async ({ page }) => {
10
+ const loginPage = new LoginPage(page);
11
+ await loginPage.navigate('/login');
12
+ await loginPage.login('admin@example.com', 'Password123');
13
+ await expect(page).toHaveURL(/\/dashboard/);
14
+ });
15
+
16
+ test('TC02 - Hiển thị lỗi khi nhập sai mật khẩu', async ({ page }) => {
17
+ const loginPage = new LoginPage(page);
18
+ await loginPage.navigate('/login');
19
+ await loginPage.login('admin@example.com', 'wrong-password');
20
+ await expect(loginPage.errorMessage).toBeVisible();
21
+ });
22
+
23
+ test('TC03 - Hiển thị validation khi để trống email', async ({ page }) => {
24
+ const loginPage = new LoginPage(page);
25
+ await loginPage.navigate('/login');
26
+ await loginPage.submitButton.click();
27
+ await expect(page.getByText('Email là bắt buộc')).toBeVisible();
28
+ });
29
+ });
@@ -0,0 +1,44 @@
1
+ # Skill: Phân tích yêu cầu ban đầu (BA Analyst) - Phiên bản v1
2
+
3
+ ## 1. Mục đích (Purpose)
4
+ Kỹ năng này giúp Business Analyst (hoặc Agent) quét, đọc hiểu và cấu trúc hóa các yêu cầu thô được cung cấp bởi khách hàng hoặc các stakeholders. Mục tiêu là phân tách rõ ràng giữa các thông tin thực tế (Facts) và các giả định (Assumptions), phát hiện các khoảng trống nghiệp vụ (Gaps), và tạo cơ sở cho việc lập danh sách câu hỏi làm rõ (Q&A) cũng như dự thảo spec ban đầu.
5
+
6
+ ## 2. Kiến thức cần có (Prerequisite Knowledge)
7
+ - **Tư duy phân tích (Analytical Thinking):** Khả năng chia nhỏ một yêu cầu lớn thành các luồng nghiệp vụ nhỏ và các thành phần cấu thành.
8
+ - **Phân biệt Fact vs. Assumption:**
9
+ - *Fact (Sự thật):* Thông tin được ghi rõ ràng trong tài liệu, được khẳng định từ khách hàng.
10
+ - *Assumption (Giả định):* Những giả thiết do BA đưa ra dựa trên kinh nghiệm hoặc ngữ cảnh mà chưa được khách hàng xác nhận bằng văn bản.
11
+ - **Kỹ thuật Gap Analysis:** Kỹ thuật nhận diện các điểm chưa thống nhất, các thông tin bị thiếu (ví dụ: thiếu thông báo lỗi khi validate thất bại, thiếu quy tắc lưu trữ vào cơ sở dữ liệu, thiếu mô tả quyền truy cập).
12
+ - **Thuật ngữ phần mềm cơ bản:** Khách hàng (Client), Người dùng (User), Tác nhân (Actor), Ràng buộc (Constraints), Luồng chính (Happy Path), Trường hợp ngoại lệ (Edge cases).
13
+
14
+ ## 3. Quy trình thực hiện (Step-by-step Process)
15
+ - **Bước 1: Tiếp nhận và đọc quét (Read & Scan):**
16
+ Đọc toàn bộ tài liệu đầu vào (ví dụ trong folder `TÀI LIỆU/input/`) ít nhất 2 lần để nắm bức tranh tổng thể và ngữ cảnh nghiệp vụ.
17
+ Sau đó đọc source code liên quan (nếu workspace có source repos):
18
+ - Ưu tiên đọc: data models/entity, API endpoints hiện tại, service/business logic
19
+ - Mục đích: hiểu hệ thống đang tồn tại, tìm constraints kỹ thuật, tránh đề xuất mâu thuẫn architecture
20
+ - Nếu GitNexus MCP có sẵn: dùng `gitnexus: query()` / `gitnexus: context()` thay vì đọc file trực tiếp
21
+ - **Bước 2: Phân loại thông tin (Categorize):**
22
+ Trích xuất các thông tin theo các cấu trúc:
23
+ - Mục tiêu của chức năng.
24
+ - Các tác nhân tham gia vào luồng.
25
+ - Các yêu cầu chức năng (các hành động, nút bấm, trường thông tin).
26
+ - Các yêu cầu phi chức năng (bảo mật, hiệu năng, nền tảng hệ điều hành/trình duyệt).
27
+ - **Bước 3: Nhận diện và ghi nhận Gap (Identify Gaps):**
28
+ Đối chiếu từng yêu cầu chức năng với các câu hỏi:
29
+ - Dữ liệu đầu vào của trường này có giới hạn độ dài/định dạng không?
30
+ - Nếu để trống thì hệ thống xử lý thế nào? Có thông báo lỗi gì không?
31
+ - Có quy tắc nghiệp vụ (Business rules) ngầm định nào không?
32
+ - Luồng thay thế (Alternative flows) hoặc luồng lỗi (Exception flows) là gì?
33
+ - **Bước 4: Soạn dự thảo Kết quả phân tích ban đầu:**
34
+ Áp dụng template phân tích ban đầu (`skill-ba-template-phan-tich-ban-dau-v1.md`) để điền thông tin và lập bảng Gap/Assumption.
35
+
36
+ ## 4. Checklist kiểm tra (Checklist for Verification)
37
+ - [ ] Đã xác định rõ Mục tiêu hệ thống/chức năng chưa? (Hệ thống giải quyết bài toán gì?)
38
+ - [ ] Đã làm rõ tất cả các Tác nhân (Actors) tham gia chưa?
39
+ - [ ] Đã bóc tách hết các trường thông tin (Inputs) được liệt kê trong tài liệu thô chưa?
40
+ - [ ] Đã ghi nhận rõ ràng danh sách các điểm mơ hồ hoặc thiếu thông tin dưới dạng **Gap/Assumption** chưa?
41
+ - [ ] Không tự tiện bổ sung các tính năng ngoài phạm vi yêu cầu của khách hàng khi chưa có thảo luận/Q&A.
42
+
43
+ ## 5. Output mong đợi (Expected Output)
44
+ - File tài liệu phân tích ban đầu định dạng markdown, cấu trúc thống nhất dựa theo `@skill-ba-template-phan-tich-ban-dau-v1.md`, đặt tên theo chuẩn: `Tên chức năng_Kết quả phân tích(n).md` trong thư mục `TÀI LIỆU/output/Kết quả phân tích/`.
@@ -0,0 +1,35 @@
1
+ # Skill: Thiết kế Layout và Prototype HTML/CSS - Phiên bản v1
2
+
3
+ ## 1. Mục đích (Purpose)
4
+ Kỹ năng này hướng dẫn BA thiết kế và hiện thực hóa giao diện người dùng (UI mockup/prototype) dưới dạng mã nguồn HTML/CSS tự chứa (self-contained). Prototype giúp khách hàng hình dung trực quan luồng đi của màn hình, đồng thời giúp lập trình viên và kiểm thử viên xác định chính xác cấu trúc trang, ID của các phần tử và vị trí hiển thị lỗi.
5
+
6
+ ## 2. Kiến thức cần có (Prerequisite Knowledge)
7
+ - **HTML5 Semantic Tags:** Sử dụng các thẻ ngữ nghĩa như `<header>`, `<main>`, `<section>`, `<nav>`, `<form>`, `<input>`, `<button>`, `<label>` để trang web có cấu trúc chuẩn SEO và dễ kiểm thử.
8
+ - **Vanilla CSS Layouts:** Thành thạo Flexbox và CSS Grid để dựng bố cục nhanh chóng, đáp ứng tốt trên các kích thước màn hình khác nhau (Responsive).
9
+ - **Nguyên lý UX/UI cơ bản:**
10
+ - *Primary Flow & Visual Hierarchy:* Làm nổi bật các thành phần quan trọng bằng kích thước, màu sắc và độ tương phản (ví dụ: nút bấm chính).
11
+ - *Bố cục F-pattern & Z-pattern:* Đặt tiêu đề, logo ở góc trên bên trái, thông tin quan trọng chạy ngang và chéo xuống nút bấm thực thi ở góc dưới bên phải.
12
+ - *Khoảng trắng (Whitespace):* Giữ khoảng cách hợp lý giữa các nhóm thông tin (Chunking) để tránh rối mắt.
13
+
14
+ ## 3. Quy trình thực hiện (Step-by-step Process)
15
+ - **Bước 1: Phân tích các thành phần (Wireframing mentally):**
16
+ Dựa trên tài liệu phân tích, liệt kê tất cả các phần tử UI cần có (ví dụ: Logo, Tiêu đề, Ô nhập ID, Ô nhập Password, Nút Đăng nhập, Link Quên mật khẩu, Vùng hiển thị lỗi).
17
+ - **Bước 2: Dựng khung HTML:**
18
+ - Viết mã HTML chuẩn. Bắt buộc đặt các thuộc tính `id`, `name`, `type`, `placeholder` rõ ràng cho các ô nhập liệu (ví dụ: `<input type="text" id="username" name="username"...>`).
19
+ - Đưa các thông báo lỗi (Error message) vào đúng vị trí dưới các ô nhập liệu, gán class dạng `.error-message` hoặc `.inline-error` và tạm ẩn đi bằng CSS (`display: none;` hoặc thông qua trạng thái ẩn) nhưng vẫn có mặt trong mã nguồn để Tester biết vị trí hiển thị.
20
+ - **Bước 3: Tạo kiểu dáng CSS:**
21
+ - Sử dụng thẻ `<style>` nội bộ nằm ngay trong file HTML (để file HTML tự chứa tất cả tài nguyên, dễ chia sẻ và import vào tài liệu spec).
22
+ - Sử dụng bảng màu hiện đại (tránh màu đỏ/xanh lá gốc, dùng các màu trung tính, dịu mắt phối hợp hiệu ứng hover cho các nút bấm).
23
+ - Đảm bảo thiết kế responsive cơ bản bằng media queries nếu cần.
24
+ - **Bước 4: Kiểm tra và lưu trữ:**
25
+ Mở file HTML trên trình duyệt để kiểm tra trực quan. Lưu vào thư mục `TÀI LIỆU/output/design/`.
26
+
27
+ ## 4. Checklist kiểm tra (Checklist for Verification)
28
+ - [ ] File HTML có tự chứa toàn bộ CSS không? (Không liên kết tới file CSS bên ngoài trừ font chữ hệ thống).
29
+ - [ ] Tất cả các trường nhập liệu đã có thẻ `<label>` tương ứng và thuộc tính `id`, `name` chưa?
30
+ - [ ] Vị trí các thông báo lỗi (Alert và Inline error) đã được dựng sẵn trong code và định dạng rõ ràng chưa?
31
+ - [ ] Giao diện có hiển thị cân đối trên cả màn hình Desktop và Mobile không?
32
+ - [ ] Các phần tử tương tác (Button, Link, Input) có hiệu ứng trực quan khi hover hoặc focus không?
33
+
34
+ ## 5. Output mong đợi (Expected Output)
35
+ - Một file HTML độc lập chứa đầy đủ code HTML và CSS nội bộ, đặt tên theo chuẩn: `Tên chức năng_design.html` trong thư mục `TÀI LIỆU/output/design/`.
@@ -0,0 +1,21 @@
1
+ # Skill: Template Q&A - Phiên bản v1
2
+
3
+ Mẫu tài liệu dùng để trình bày danh sách câu hỏi Q&A và theo dõi phản hồi từ khách hàng.
4
+
5
+ ---
6
+
7
+ # Tài liệu Q&A: [Tên Chức Năng]
8
+
9
+ *Tài liệu này dùng để theo dõi các vấn đề nghiệp vụ cần làm rõ giữa đội ngũ dự án và khách hàng. Trạng thái bao gồm: **Open** (Đang chờ phản hồi), **Confirmed** (Đã thống nhất).*
10
+
11
+ ## Danh sách câu hỏi Q&A
12
+
13
+ | ID | Chức năng / Màn hình | Nội dung yêu cầu hiện tại | Câu hỏi / Điểm chưa rõ | Đề xuất giải pháp (Options) | Câu trả lời của Khách hàng | Trạng thái |
14
+ | :-: | :--- | :--- | :--- | :--- | :--- | :-: |
15
+ | **QA-01** | *Đăng nhập* | *Có text link đổi mật khẩu* | *Text link này sẽ dẫn sang URL cụ thể nào? Hệ thống tự sinh OTP gửi mail hay chuyển sang màn nhập email?* | *- Option A: Chuyển sang URL `/forgot-password` để nhập Email nhận link reset.<br>- Option B: Hiển thị popup nhập SĐT nhận OTP.* | *Khách hàng phản hồi: Chọn Option A, link URL là `/forgot-password`* | **Confirmed** |
16
+ | **QA-02** | | | | | | **Open** |
17
+
18
+ ---
19
+ ## Lịch sử cập nhật tài liệu
20
+ *Sau mỗi lần nhận phản hồi, BA cập nhật bảng trên và ghi nhận lịch sử tại đây:*
21
+ - **Ngày [dd/mm/yyyy]:** Nhận phản hồi lần 1 từ khách hàng cho câu hỏi QA-01. Cập nhật trạng thái sang **Confirmed** và chỉnh sửa tài liệu Phân tích bản đầu tương ứng.
@@ -0,0 +1,35 @@
1
+ # Skill: Xử lý và Thiết kế Q&A (Q&A Specification) - Phiên bản v1
2
+
3
+ ## 1. Mục đích (Purpose)
4
+ Kỹ năng này giúp BA thiết kế các câu hỏi rõ ràng, khách quan và chuyên nghiệp để gửi tới khách hàng/stakeholders nhằm làm rõ các khoảng trống nghiệp vụ (Gaps). Đồng thời, hướng dẫn cách tiếp nhận câu trả lời để cập nhật tài liệu phân tích một cách nhất quán, tránh hiểu sai hoặc tự ý giả định thông tin.
5
+
6
+ ## 2. Kiến thức cần có (Prerequisite Knowledge)
7
+ - **Kỹ năng giao tiếp bằng văn bản (Written Communication):** Sử dụng câu từ ngắn gọn, lịch sự, đi thẳng vào vấn đề.
8
+ - **Kỹ thuật đặt câu hỏi mở và đóng:**
9
+ - Tránh câu hỏi mập mờ (ví dụ: "Hệ thống có cần khóa tài khoản không?").
10
+ - Nên đưa ra các tùy chọn rõ ràng (ví dụ: "Khi nhập sai mật khẩu liên tiếp, hệ thống sẽ xử lý thế nào? Tùy chọn A: Khóa tài khoản sau 5 lần sai trong 30 phút. Tùy chọn B: Chỉ hiển thị thông báo lỗi mà không khóa tài khoản. Tùy chọn C: Ý kiến khác...").
11
+ - **Tư duy kiểm thử (Testing Mindset):** Đứng dưới góc nhìn của Tester để hỏi về các biên dữ liệu, các trường hợp lỗi mạng, mất kết nối cơ sở dữ liệu, hoặc dữ liệu không hợp lệ.
12
+
13
+ ## 3. Quy trình thực hiện (Step-by-step Process)
14
+ - **Bước 1: Chuyển đổi Gap thành câu hỏi Q&A:**
15
+ Từ danh sách khoảng trống phát hiện ở bước Phân tích ban đầu, chuyển mỗi dòng thành một câu hỏi Q&A cụ thể.
16
+ - **Bước 2: Chuẩn hóa câu hỏi theo mẫu `@skill-ba-qa-template-v1.md`:**
17
+ - Xác định phân vùng nghiệp vụ (Module/Screen).
18
+ - Trích dẫn yêu cầu hiện tại (Current Status/Requirement).
19
+ - Nêu rõ vấn đề mơ hồ.
20
+ - Đưa ra các giải pháp đề xuất (Options) cùng giả định của BA.
21
+ - **Bước 3: Nhận phản hồi và Cập nhật (Process Responses):**
22
+ - Khi nhận được câu trả lời từ khách hàng: Đọc kỹ để đảm bảo câu trả lời đã giải quyết triệt để câu hỏi. Nếu câu trả lời vẫn chưa rõ ràng, tiếp tục duy trì trạng thái "Open" và hỏi lại ở version tiếp theo.
23
+ - Nếu đã rõ ràng: Đánh dấu "Resolved" và cập nhật thông tin đó trực tiếp vào tài liệu phân tích hiện tại (`Kết quả phân tích(n).md`).
24
+ - Ghi nhận lịch sử thay đổi để Dev/Test nắm được lý do thay đổi logic.
25
+
26
+ ## 4. Checklist kiểm tra (Checklist for Verification)
27
+ - [ ] Mỗi câu hỏi có chỉ rõ phần màn hình/tính năng liên quan không?
28
+ - [ ] Câu hỏi có sử dụng từ ngữ trung lập, không mang tính áp đặt ý kiến chủ quan của BA không?
29
+ - [ ] Có đưa ra các phương án gợi ý (Option A, Option B...) cho các vấn đề phức tạp để khách hàng dễ lựa chọn không?
30
+ - [ ] Các thuật ngữ viết tắt trong câu hỏi có được giải thích rõ không?
31
+ - [ ] Đã cập nhật đúng và đầy đủ tất cả câu trả lời của khách hàng vào tài liệu phân tích chưa? (Không bỏ sót bất kỳ điểm chốt nào).
32
+
33
+ ## 5. Output mong đợi (Expected Output)
34
+ - File danh sách câu hỏi Q&A định dạng markdown, cấu trúc thống nhất dựa theo `@skill-ba-qa-template-v1.md`, đặt tên theo chuẩn: `Tên chức năng_Q&A(m).md` trong thư mục `TÀI LIỆU/output/QA/`.
35
+ - Tài liệu phân tích được cập nhật tương ứng với phiên bản mới tăng dần `(n+1)`.
@@ -0,0 +1,30 @@
1
+ # Skill: Template Phân Tích Ban Đầu - Phiên bản v1
2
+
3
+ Mẫu tài liệu này được sử dụng để trình bày kết quả phân tích yêu cầu ban đầu sau khi bóc tách từ tài liệu thô.
4
+
5
+ ---
6
+
7
+ # Tài liệu Phân Tích Yêu Cầu Ban Đầu: [Tên Chức Năng]
8
+
9
+ ## 1. Mục tiêu chức năng
10
+ *Mô tả ngắn gọn chức năng này dùng để làm gì? Giải quyết nhu cầu gì của doanh nghiệp hoặc người dùng?*
11
+
12
+ ## 2. Các tác nhân chính (Actors)
13
+ *Liệt kê danh sách các tác nhân (User, Admin, Manager...) sẽ tương tác trực tiếp hoặc gián tiếp với chức năng.*
14
+
15
+ ## 3. Yêu cầu chức năng chi tiết (Functional Requirements)
16
+ *Bóc tách chi tiết các tính năng nhỏ, các nút bấm, các hành động mà hệ thống phải xử lý.*
17
+ - **Giao diện/Trường thông tin:** Liệt kê các trường dữ liệu cần hiển thị hoặc nhập liệu.
18
+ - **Quy tắc nhập liệu sơ bộ:** Định dạng, bắt buộc hay không (Required/Optional).
19
+
20
+ ## 4. Yêu cầu phi chức năng (Non-Functional Requirements)
21
+ *Các yêu cầu về bảo mật, hiệu suất, khả năng tương thích, hoặc giao diện UX/UI đặc thù.*
22
+
23
+ ## 5. Bảng Phân Tích Khoảng Trống & Giả Định (Gap & Assumption Analysis)
24
+
25
+ | # | Tính năng/Luồng nghiệp vụ | Hiện trạng mô tả thô | Khoảng trống (Gap) / Sự mơ hồ phát hiện | Giả định của BA (Assumption) | Đề xuất giải pháp / Q&A ID tương ứng |
26
+ | :-: | :--- | :--- | :--- | :--- | :--- |
27
+ | 1 | *Ví dụ: Nhập Password* | *Mật khẩu được che giấu* | *Có nút show/hide mật khẩu hay không? Đăng nhập sai bao nhiêu lần thì khóa?* | *Mặc định không hiển thị nút show/hide. Cho phép nhập sai tối đa 5 lần.* | *Xem Q&A_01* |
28
+ | 2 | | | | | |
29
+
30
+ *Lưu ý: Bảng này là cơ sở quan trọng nhất để tạo ra danh sách câu hỏi Q&A chuẩn xác cho khách hàng.*
@@ -0,0 +1,83 @@
1
+ # Skill: Template Đặc tả Use Case (Use Case Spec) - Phiên bản v1
2
+
3
+ Cấu trúc chuẩn của một tài liệu đặc tả Use Case hoàn chỉnh dùng để chuyển giao cho Dev/Test.
4
+
5
+ ---
6
+
7
+ # Tài liệu Đặc Tả Use Case: Chức năng [Tên Chức Năng]
8
+
9
+ ## 1. Thông tin chung (General Information)
10
+
11
+ | Thuộc tính | Mô tả chi tiết |
12
+ | :--- | :--- |
13
+ | **Tên chức năng (Function Name)** | [Tên chức năng chính xác] |
14
+ | **Mô tả (Description)** | [Tóm tắt mục đích và giá trị nghiệp vụ của chức năng] |
15
+ | **Tác nhân (Actors)** | [Danh sách các tác nhân sử dụng hoặc bị tác động] |
16
+ | **Tác nhân kích hoạt (Trigger)** | [Sự kiện kích hoạt luồng xử lý này] |
17
+ | **Điều kiện tiên quyết (Pre-Conditions)** | [Các điều kiện hệ thống hoặc trạng thái dữ liệu bắt buộc phải có trước khi thực hiện] |
18
+ | **Điều kiện sau xử lý (Post-Conditions)** | [Trạng thái của hệ thống và dữ liệu sau khi kết thúc thành công] |
19
+
20
+ ### Luồng xử lý chính (Main Flow)
21
+
22
+ | Bước | Tác nhân (Actor Action) | Hệ thống (System Response) |
23
+ | :-: | :--- | :--- |
24
+ | 1 | Người dùng kích hoạt sự kiện... | Hệ thống hiển thị giao diện... |
25
+ | 2 | Người dùng nhập các thông tin... | |
26
+ | 3 | Người dùng nhấn nút... | Hệ thống kiểm tra và thực hiện... |
27
+ | 4 | | Hệ thống thông báo thành công và chuyển hướng... |
28
+
29
+ ### Các luồng thay thế / ngoại lệ (Alternative / Exception Flows)
30
+
31
+ - **Alternative Flow A: [Tên luồng thay thế]**
32
+ - Thực hiện từ bước [X] của Luồng chính:
33
+ - Các bước xử lý: ...
34
+ - **Exception Flow B: [Tên luồng lỗi]**
35
+ - Thực hiện khi xảy ra lỗi: ...
36
+ - Các bước xử lý: ...
37
+
38
+ ---
39
+
40
+ ## 2. Mô tả màn hình (Screen Description)
41
+ *Nhúng code HTML của màn hình prototype hoặc ảnh chụp mockup tại đây:*
42
+
43
+ ```html
44
+ <!-- Dán code HTML/CSS prototype ở đây -->
45
+ ```
46
+
47
+ ---
48
+
49
+ ## 3. Mô tả thành phần giao diện (UI Components Description)
50
+
51
+ | # | Tên Component | Loại Component | Cho phép sửa | Bắt buộc | Giá trị mặc định | Quy tắc định dạng & Giới hạn dữ liệu | Mô tả hành vi & tương tác |
52
+ | :-: | :--- | :--- | :-: | :-: | :--- | :--- | :--- |
53
+ | 1 | `ログインID` | Textbox | Yes | Yes | None | Độ dài: 3-20 ký tự. Chỉ chữ và số. Không chứa khoảng trắng. | Ô nhập tên tài khoản của người dùng. |
54
+ | 2 | `ログイン` | Button | N/A | N/A | N/A | N/A | Nhấn để gửi thông tin đăng nhập lên hệ thống. |
55
+ | 3 | | | | | | | |
56
+
57
+ ---
58
+
59
+ ## 4. Sơ đồ luồng hoạt động (Activity Flow Diagram)
60
+ *Sử dụng biểu đồ Mermaid để trực quan hóa quy trình xử lý.*
61
+
62
+ ```mermaid
63
+ graph TD
64
+ %% Viết mã nguồn Mermaid tại đây
65
+ ```
66
+
67
+ ---
68
+
69
+ ## 5. Quy tắc nghiệp vụ (Business Rules)
70
+
71
+ ### BR1: Quy tắc kiểm tra dữ liệu đầu vào (Validation Rules)
72
+ *Định nghĩa các lỗi khi người dùng nhập dữ liệu sai hoặc để trống.*
73
+ - **[BR1.1] Trống dữ liệu bắt buộc:** Nếu bất kỳ trường bắt buộc nào bị trống khi nhấn nút thực thi:
74
+ - Hệ thống dừng xử lý.
75
+ - Hiển thị lỗi tương ứng: `[Tên thông báo lỗi]` dưới ô nhập liệu bị trống.
76
+ - **[BR1.2] Định dạng dữ liệu không hợp lệ:** ...
77
+
78
+ ### BR2: Quy tắc lưu trữ dữ liệu (Saving Rules)
79
+ *Định nghĩa cách dữ liệu được ghi nhận vào cơ sở dữ liệu.*
80
+ - **[BR2.1]** Hệ thống ghi nhận thời gian đăng nhập vào bảng `user_logs` với các trường: `user_id`, `login_time`, `status`.
81
+
82
+ ### BR3: Quy tắc phân quyền & Bảo mật (Authorization & Security Rules)
83
+ - **[BR3.1]** Sau 5 lần nhập sai mật khẩu liên tiếp, tài khoản tự động bị khóa trong 30 phút.