@shanyucoder/flowgrid 0.1.5 → 0.1.9

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 (169) hide show
  1. package/README.md +1 -1
  2. package/adapters/laravel/registries/codegen.registry.json +9 -9
  3. package/bin/flowgrid.mjs +326 -115
  4. package/bin/lib/agent-mcp.mjs +4 -0
  5. package/bin/lib/agent-profiles.mjs +30 -6
  6. package/bin/lib/audit-run.mjs +1 -1
  7. package/bin/lib/cli-update.mjs +48 -8
  8. package/bin/lib/doctor.mjs +90 -3
  9. package/bin/lib/harness-overlay.mjs +12 -5
  10. package/bin/lib/harness-sync.mjs +17 -3
  11. package/bin/lib/init-adapters.mjs +75 -0
  12. package/bin/lib/init-scaffold.mjs +9 -0
  13. package/bin/lib/inject-consumer-scripts.mjs +115 -0
  14. package/bin/lib/merge-stack-config.mjs +89 -0
  15. package/bin/lib/project-gitignore.mjs +1 -0
  16. package/bin/lib/repo-maps-align.mjs +203 -0
  17. package/dist/graph/config/load-config.js +7 -2
  18. package/dist/graph/config/load-config.js.map +1 -1
  19. package/dist/graph/mcp/tools.js +1 -1
  20. package/dist/graph/mcp/tools.js.map +1 -1
  21. package/dist/graph/registry/load-registries.d.ts +1 -0
  22. package/dist/graph/registry/load-registries.js +14 -1
  23. package/dist/graph/registry/load-registries.js.map +1 -1
  24. package/engines/cases/render-cases.mjs +67 -5
  25. package/engines/docs/lib/qa-item.mjs +91 -0
  26. package/engines/docs/lib/render-api-summary-markdown.mjs +28 -0
  27. package/engines/docs/lib/render-bundle-markdown.mjs +77 -2
  28. package/engines/docs/lib/render-data-model-markdown.mjs +171 -0
  29. package/engines/docs/lib/render-design-tables.mjs +89 -7
  30. package/engines/docs/lib/render-qa-list.mjs +123 -25
  31. package/engines/docs/lib/render-template.mjs +6 -0
  32. package/engines/docs/render-docs.mjs +6 -2
  33. package/engines/docs/vitepress/config.ts +7 -7
  34. package/engines/docs/vitepress/surfaces-nav.mjs +45 -14
  35. package/engines/openapi/check-backend-spec.mjs +2 -2
  36. package/engines/openapi/lib/markdown-table.mjs +8 -0
  37. package/engines/openapi/lib/render-backend-spec-markdown.mjs +78 -0
  38. package/engines/registry-sync/be-capabilities-sync.mjs +118 -0
  39. package/engines/registry-sync/fe-design-sync.mjs +258 -0
  40. package/engines/registry-sync/run-registry-sync.mjs +107 -0
  41. package/engines/shared/e2e-output-layout.mjs +68 -0
  42. package/engines/shared/flowgrid-e2e-root.mjs +19 -0
  43. package/engines/shared/resolve-flowgrid-context.mjs +176 -0
  44. package/engines/spec/lib/audit-api-gaps.mjs +1 -1
  45. package/engines/spec/lib/audit-bundle-gaps.mjs +92 -3
  46. package/engines/spec/lib/audit-db-tables.mjs +529 -0
  47. package/engines/spec/lib/audit-e2e-coverage.mjs +88 -30
  48. package/engines/spec/lib/bundle-schema.mjs +4 -1
  49. package/engines/spec/lib/open-qa.mjs +71 -21
  50. package/engines/spec/split-bundle.mjs +11 -1
  51. package/engines/testcase/runners/generate-api.mjs +23 -23
  52. package/engines/testcase/runners/generate.mjs +19 -17
  53. package/engines/testcase/runners/lib/bootstrap-context.mjs +44 -0
  54. package/engines/testcase/runners/lib/write-files.mjs +37 -9
  55. package/harness/agents/antigravity/rules/antigravity-mcp.mdc +12 -0
  56. package/harness/agents/gemini/rules/gemini-mcp.mdc +11 -0
  57. package/harness/agents/gemini_antigravity/rules/antigravity-mcp.mdc +8 -6
  58. package/harness/be/skills/{grill-api → audit-api}/SKILL.md +8 -7
  59. package/harness/common/extracts/artifact-graph.md +2 -2
  60. package/harness/common/extracts/artifactgraph-phase-hooks.md +2 -2
  61. package/harness/common/extracts/docs-mark-detect.md +2 -2
  62. package/harness/common/extracts/entity-relationship.md +23 -0
  63. package/harness/common/rules/flowgrid-ux-common.mdc +3 -3
  64. package/harness/common/skills/configure-repo-maps/SKILL.md +4 -2
  65. package/harness/docs/extracts/agent-execution-protocol.md +3 -3
  66. package/harness/docs/extracts/api-codegen-readiness.md +34 -0
  67. package/harness/docs/extracts/api-codegen-tags.md +30 -0
  68. package/harness/docs/extracts/api-contract.md +43 -0
  69. package/harness/docs/extracts/api-spec-sync.md +35 -0
  70. package/harness/docs/extracts/artifactgraph-hooks-docs.md +1 -1
  71. package/harness/docs/extracts/call-external.md +16 -0
  72. package/harness/docs/extracts/common-scope.md +9 -10
  73. package/harness/docs/extracts/db-audit-wizard.md +45 -0
  74. package/harness/docs/extracts/derived-data.md +18 -0
  75. package/harness/docs/extracts/design-leaf-signoff.md +16 -0
  76. package/harness/docs/extracts/extract-registry.docs.json +11 -2
  77. package/harness/docs/extracts/qa-inbox.md +19 -10
  78. package/harness/docs/extracts/qa-team.md +32 -0
  79. package/harness/docs/extracts/spec-core.md +7 -3
  80. package/harness/docs/extracts/spec-evolution.md +21 -0
  81. package/harness/docs/extracts/spec-prd-lite.md +19 -0
  82. package/harness/docs/extracts/spec-requirement.md +6 -2
  83. package/harness/docs/extracts/spec-ssot-prep.md +25 -0
  84. package/harness/docs/extracts/tpl-module.md +12 -0
  85. package/harness/docs/extracts/verify-gate.md +33 -0
  86. package/harness/docs/extracts/wire-spec-feedback.md +31 -0
  87. package/harness/docs/rules/agent-compliance.mdc +1 -1
  88. package/harness/docs/rules/team-flow-spec.mdc +3 -4
  89. package/harness/docs/schemas/flowgrid-docs/qa-item.schema.json +65 -0
  90. package/harness/docs/skills/adopt/SKILL.md +2 -0
  91. package/harness/docs/skills/api/SKILL.md +4 -5
  92. package/harness/docs/skills/api-spec/SKILL.md +19 -6
  93. package/harness/docs/skills/api-update/SKILL.md +4 -4
  94. package/harness/docs/skills/architecture/SKILL.md +1 -1
  95. package/harness/docs/skills/business-process/SKILL.md +2 -0
  96. package/harness/docs/skills/common/SKILL.md +2 -2
  97. package/harness/docs/skills/common-spec/SKILL.md +10 -47
  98. package/harness/docs/skills/db-erd/SKILL.md +26 -0
  99. package/harness/docs/skills/grill/SKILL.md +28 -22
  100. package/harness/docs/skills/grill-api/SKILL.md +4 -6
  101. package/harness/docs/skills/grill-api-spec/SKILL.md +44 -24
  102. package/harness/docs/skills/grill-bqa/SKILL.md +28 -13
  103. package/harness/docs/skills/grill-common-spec/SKILL.md +10 -35
  104. package/harness/docs/skills/grill-dev/SKILL.md +8 -7
  105. package/harness/docs/skills/grill-docs/SKILL.md +11 -4
  106. package/harness/docs/skills/module/SKILL.md +3 -1
  107. package/harness/docs/skills/openapi/SKILL.md +2 -1
  108. package/harness/docs/skills/overview/SKILL.md +7 -1
  109. package/harness/docs/skills/qa-resolve/SKILL.md +13 -12
  110. package/harness/docs/skills/qa-review/SKILL.md +45 -0
  111. package/harness/docs/skills/spec/SKILL.md +43 -10
  112. package/harness/docs/skills/update-spec/SKILL.md +5 -2
  113. package/harness/fe/extracts/wire-audit-loop.md +72 -0
  114. package/harness/fe/extracts/wire-phase.md +45 -0
  115. package/harness/fe/rules/platform-design-vocabulary.mdc +1 -1
  116. package/harness/fe/rules/team-flow-prototype.mdc +8 -4
  117. package/harness/fe/skills/gen-common/SKILL.md +11 -84
  118. package/harness/fe/skills/grill-prototype/SKILL.md +51 -25
  119. package/harness/fe/skills/grill-test/SKILL.md +78 -20
  120. package/harness/fe/skills/grill-wire/SKILL.md +81 -0
  121. package/harness/fe/skills/prototype/SKILL.md +3 -2
  122. package/harness/fe/skills/wire/SKILL.md +8 -3
  123. package/harness/shared/AGENTS.md +3 -3
  124. package/harness/shared/SSOT_AGENT_PROTOCOL.md +3 -3
  125. package/harness/tests/extracts/grill-api-hook.md +69 -0
  126. package/harness/tests/extracts/grill-scenario-flow.md +39 -0
  127. package/harness/tests/extracts/grill-screen-tc.md +40 -0
  128. package/harness/tests/extracts/testcase-gen-cli.md +57 -0
  129. package/harness/tests/extracts/testcase-plan.md +29 -0
  130. package/harness/tests/extracts/tests-verify-gate.md +29 -0
  131. package/harness/tests/extracts/wire-test-handoff.md +37 -0
  132. package/harness/tests/skills/grill-testcase/SKILL.md +1 -0
  133. package/harness/tests/skills/test-api/SKILL.md +14 -6
  134. package/harness/tests/skills/testcase/SKILL.md +3 -1
  135. package/harness/tests/templates/TC.example-api.yaml +7 -1
  136. package/harness/tests/templates/TC.example.yaml +4 -1
  137. package/harness/tests/templates/tpl-testcase-plan.md +75 -0
  138. package/package.json +1 -1
  139. package/stacks/fastapi.json +1 -0
  140. package/stacks/laravel.json +1 -0
  141. package/stacks/nestjs.json +72 -0
  142. package/stacks/nextjs-nest.json +1 -0
  143. package/stacks/nuxt4-nest.json +1 -0
  144. package/templates/project-skeleton/architecture/03-business-process/FLOW-template.md +2 -0
  145. package/templates/project-skeleton/overview/index.md +68 -2
  146. package/templates/project-skeleton/overview/operational-areas/_template.md +37 -0
  147. package/templates/project-skeleton/qa/README.md +4 -8
  148. package/templates/project-skeleton/surfaces/common/data-model/index.md +10 -2
  149. package/templates/schemas/qa-item.schema.json +98 -0
  150. package/templates/shared/api-03-mock.stub.yaml +14 -0
  151. package/templates/shared/backend-api.bundle.yaml +3 -0
  152. package/templates/shared/backend-api.yaml +4 -0
  153. package/templates/shared/be-capabilities.registry.base.json +8 -0
  154. package/templates/shared/bundle-authoring.md +44 -7
  155. package/templates/shared/default-layout.ejs +131 -18
  156. package/templates/shared/design-spec.yaml +2 -3
  157. package/templates/shared/design.registry.base.json +38 -0
  158. package/templates/shared/feature.bundle.yaml +16 -9
  159. package/templates/shared/ir/generated/spec.md +281 -0
  160. package/templates/shared/ir-spec.yaml +1 -1
  161. package/templates/shared/qa-authoring.md +78 -0
  162. package/templates/shared/qa-item.yaml +35 -14
  163. package/templates/shared/tpl-api-contract.md +133 -0
  164. package/templates/shared/tpl-screen-data-model.md +76 -0
  165. package/templates/tests-skeleton/cases/README.md +4 -0
  166. package/templates/tests-skeleton/catalog/locale.yaml +9 -0
  167. package/templates/tests-skeleton/tpl-testcase-plan.md +9 -0
  168. package/harness/docs/skills/api-integration/SKILL.md +0 -110
  169. package/harness/docs/skills/grill-integration-spec/SKILL.md +0 -51
@@ -0,0 +1,281 @@
1
+
2
+ # Feature title
3
+
4
+ ## Mục lục (Contents)
5
+
6
+ 1. [Tổng quan](#overview)
7
+ 2. [Chỉ số thành công](#success-metrics)
8
+ 3. [Phạm vi không làm](#non-goals)
9
+ 4. [User stories và hành trình màn hình](#user-stories--screen-journey)
10
+ 5. [Ma trận trạng thái và phân quyền](#state--permission-matrix)
11
+ 6. [Bảng cột danh sách](#list-columns)
12
+ 7. [Từ điển dữ liệu và validation](#data-dictionary--validation)
13
+ 8. [Widget tùy biến](#custom-widgets)
14
+ 9. [Luồng hành động](#action-flows)
15
+ - [API SSOT](#api-ssot)
16
+
17
+ ---
18
+
19
+ ## Tổng quan {#overview}
20
+
21
+ | | |
22
+ | --- | --- |
23
+ | **Page ID** | `role-domain-function` |
24
+ | **Status** | draft |
25
+ | **Owner** | portal-team |
26
+
27
+
28
+ - **Testcase plans:** [base_test](https://github.com/raintr91/base_test) (`pnpm cases:render` on tests hub) — see docs-hub TESTS-HUB
29
+
30
+
31
+
32
+ - **Screen:** None
33
+
34
+
35
+ - mục tiêu nghiệp vụ (business_goals): [Nêu rõ vấn đề đang giải quyết và giá trị kinh tế/nghiệp vụ mang lại. Viết sâu sắc để Stakeholder hiểu rõ vì sao phải làm.]
36
+ - các bên liên quan (stakeholders): [Ai dùng, ai hưởng lợi, ai quản lý?]
37
+ - kịch bản người dùng (user_journey): [Kể câu chuyện người dùng trải qua các bước trên màn hình bằng ngôn ngữ đời thường.]
38
+ - bối cảnh (context):
39
+ - description: [Phân tích sâu luồng nghiệp vụ chi tiết]
40
+ - input: [Dữ liệu đầu vào. CHÚ Ý liên kết cross-page / cross-module nếu có]
41
+ - output: [Kết quả đầu ra]
42
+ - cách giải quyết (solution): [Tuỳ chọn. Ghi kỹ thuật phức tạp nếu có.]
43
+
44
+
45
+
46
+
47
+ ## Chỉ số thành công {#success-metrics}
48
+
49
+ - [Chỉ số đo được khi màn/feature đạt mục tiêu — VD: thời gian hoàn tất thao tác, tỷ lệ lỗi validation]
50
+ - [Bỏ bullet nếu chưa có số — ghi qualitative metric]
51
+
52
+
53
+
54
+
55
+
56
+ ## Phạm vi không làm {#non-goals}
57
+
58
+ - [Phạm vi KHÔNG làm trên màn/phase này — tránh scope creep]
59
+ - [VD: không xử lý export Excel tại màn list — defer QA/debt]
60
+
61
+
62
+
63
+
64
+ ## API SSOT {#api-ssot}
65
+
66
+ Hợp đồng backend: `api/<seq>/01-backend-spec.yaml` trong cùng function leaf (không gộp vào bundle). Sau split: `ir/design.yaml` chiếu endpoint; OpenAPI/mock theo stack.
67
+
68
+ - **Data model (review, multi-table):** [data-model.md](./data-model.md) — bảng/cột tách khỏi spec BA; SSOT codegen = `01` + `ir/design.yaml` `db`.
69
+
70
+
71
+ ## User Stories & Screen Journey {#user-stories--screen-journey}
72
+
73
+
74
+
75
+ ### User Story Chính
76
+ > **Là một** [Persona / Role - vd: Nhân viên Vận hành / Khách hàng / Quản trị viên],
77
+ > **Tôi muốn** [Hành động chính trên màn hình: xem danh sách, lọc, tạo mới, cập nhật, phê duyệt...],
78
+ > **Để** [Mục đích kinh doanh và giá trị thực tế đạt được].
79
+
80
+
81
+
82
+ ### Cách thức Truy cập & Chuyển giao Màn hình (Screen Access & Handoff)
83
+
84
+
85
+ - **Loại truy cập (Access Type):** `sidebarMenu`
86
+
87
+ - **Menu Sidebar:** Quản trị hệ thống &gt; Quản lý Người dùng > **Danh sách tài khoản**
88
+
89
+
90
+ - **Màn hình nguồn (Source Screen):** `W-ADM-LIST-01`
91
+
92
+ - **Dữ liệu tiếp nhận (Inputs):** customer_id · booking_id
93
+
94
+ - **Điều hướng tiếp theo (Next Screen):** `W-ADM-DETAIL-01`
95
+
96
+
97
+
98
+ ### Kịch bản Chi tiết trên Màn hình (Scenarios)
99
+
100
+ #### Khởi tạo &amp; Tải dữ liệu ban đầu (Initial Load)
101
+
102
+
103
+ - Kiểm tra quyền hạn người dùng (Role / Permissions) đối với màn hình.
104
+
105
+ - Tải danh sách dữ liệu theo bộ lọc mặc định hoặc bind thông tin bản ghi theo ID nhận được.
106
+
107
+ - Hiển thị trạng thái tải (Skeleton / Spinner), nếu không có dữ liệu hiển thị Empty State.
108
+
109
+
110
+
111
+ #### Tương tác Nhập liệu &amp; Thẩm định Dữ liệu (Input &amp; Validation)
112
+
113
+
114
+ - Người dùng nhập liệu các trường bắt buộc và tùy chọn trên form.
115
+
116
+ - Hệ thống validate trực tiếp trên giao diện (Inline error) khi nhập sai định dạng hoặc bỏ trống.
117
+
118
+ - Các trường có logic phụ thuộc tự động cập nhật hoặc mở thêm vùng nhập (Dynamic visibility / calculation).
119
+
120
+
121
+
122
+ #### Nộp dữ liệu &amp; Hoàn tất Thành công (Happy Path Submit)
123
+
124
+
125
+ - Người dùng nhấn nút thực thi chính (Primary Action Button).
126
+
127
+ - Hệ thống khóa nút và hiển thị loading để chống bấm đúp (double submit prevention).
128
+
129
+ - Lưu dữ liệu thành công (không phải xóa): Toast hoặc inline alert; điều hướng theo Handoff. Thao tác xóa — xem scenario UX affordances bên dưới.
130
+
131
+
132
+
133
+ #### Affordances UX chuẩn portal (UX — khi áp dụng)
134
+
135
+
136
+ - Breadcrumb / ngữ cảnh: Người dùng luôn biết đang ở module và bản ghi nào (trail hoặc back + title rõ).
137
+
138
+ - Danh sách: Tìm kiếm/lọc (nếu có) và phân trang; empty state khác &#39;không có kết quả filter&#39;.
139
+
140
+ - Cột trạng thái: Hiển thị chip/badge có chữ, không chỉ màu.
141
+
142
+ - Hành động trên dòng bị khóa: Có lý do hiển thị (tooltip/badge/chip), không chỉ nút disabled im lặng.
143
+
144
+ - Xóa / xóa hàng loạt: Hộp thoại xác nhận chặn → gọi API → hộp thoại kết quả (thành công/lỗi) bắt người dùng xác nhận — không chỉ toast.
145
+
146
+ - Import CSV (nếu có): Chọn file → kiểm tra → xác nhận → báo kết quả; lỗi theo dòng có thể tải log.
147
+
148
+
149
+
150
+ #### Xử lý Ngoại lệ &amp; Lỗi Giao diện (Exceptions &amp; Edge Cases)
151
+
152
+
153
+ - Xung đột dữ liệu / Đã bị sửa đổi bởi người khác (409 Conflict): Cảnh báo và tải lại.
154
+
155
+ - Lỗi kết nối / Máy chủ (Network / 5xx error): Giữ nguyên dữ liệu đã nhập trên form, không bắt nhập lại.
156
+
157
+ - Hết hạn phiên làm việc (Session timeout): Yêu cầu xác thực lại và bảo lưu tạm bản nháp.
158
+
159
+
160
+
161
+ #### Tác vụ Ngầm Kích hoạt từ Màn hình (Background / Async Logic - Tùy chọn)
162
+
163
+
164
+ - Nếu thao tác kích hoạt xử lý ngầm (gửi tin nhắn, tạo job đồng bộ): Hệ thống đẩy sự kiện vào hàng đợi.
165
+
166
+ - Cập nhật trạng thái hiển thị trên màn hình thành &#39;Đang xử lý ngầm&#39; (Processing) để người dùng theo dõi.
167
+
168
+
169
+
170
+
171
+
172
+
173
+ ### Tiêu chí Nghiệm thu (Acceptance Criteria)
174
+
175
+ - [ ] [ ] Người dùng có quyền truy cập xem được toàn bộ thông tin hợp lệ.
176
+
177
+ - [ ] [ ] Form chặn nộp khi thiếu các trường bắt buộc và thông báo lỗi rõ ràng.
178
+
179
+ - [ ] [ ] Khi nộp thành công (không phải delete), dữ liệu được lưu đúng và chuyển trang mượt mà.
180
+
181
+ - [ ] [ ] (Khi có delete) Confirm trước xóa và result dialog sau API — không toast-only.
182
+
183
+ - [ ] [ ] (Khi có action disabled theo rule) Người dùng hiểu lý do bị khóa (copy/badge/tooltip).
184
+
185
+ - [ ] [ ] (Khi list/detail drill-down) Breadcrumb hoặc ngữ cảnh điều hướng đủ cho deep link.
186
+
187
+
188
+
189
+
190
+
191
+
192
+
193
+
194
+
195
+ ## Ma Trận Trạng Thái Giao Diện & Phân Quyền (State & Permission Matrix) {#state--permission-matrix}
196
+
197
+ | Trạng Thái Bản Ghi (Record Status) | Trạng Thái Trường Form (Fields State) | Nút Hành Động Khả Dụng (Visible Buttons) | Ghi Chú Phân Quyền RBAC (Role Overrides) |
198
+ | --- | --- | --- | --- |
199
+ | `DRAFT` | ✏️ Cho phép sửa (Editable) | `btn_save_draft`, `btn_submit_record`, `btn_cancel` | Áp dụng cho mọi vai trò |
200
+ | `PENDING_APPROVAL` | 🔒 Chỉ đọc (Readonly) | `btn_cancel_request` | **manager**: Nút khả dụng [`btn_approve`, `btn_reject`] |
201
+ | `APPROVED` | 🔒 Chỉ đọc (Readonly) | `btn_print`, `btn_export` | Áp dụng cho mọi vai trò |
202
+ | `REJECTED` | ✏️ Cho phép sửa (Editable) | `btn_resubmit`, `btn_delete` | Áp dụng cho mọi vai trò |
203
+
204
+
205
+
206
+
207
+ ## Bảng cột danh sách (List columns) {#list-columns}
208
+
209
+ | Nhãn cột | Key | Ý nghĩa nghiệp vụ | Mục đích UI | Widget / render | Sort | DB (schema.field) |
210
+ | --- | --- | --- | --- | --- | --- | --- |
211
+ | Trạng thái | `status` | Tình trạng hoạt động của tài khoản trong hệ thống để quản lý quyền đăng nhập và giao dịch | Cho user thấy tài khoản còn hoạt động hay đã bị tạm khóa | chip / custom | Không | — |
212
+
213
+ <p><strong>DB chi tiết / multi-table:</strong> <a href="./data-model.md">data-model.md</a> · SSOT ghi: <code>*.bundle.yaml</code> + <code>ir/design.yaml</code>.</p>
214
+
215
+
216
+
217
+
218
+ ## Danh Mục Trường Nhập Liệu & Quy Tắc Kiểm Tra Hợp Lệ (Data Dictionary & Validation) {#data-dictionary--validation}
219
+
220
+ | Tên Trường (Label) | Mã Kỹ Thuật (Key) | Kiểu (Type) | Bắt Buộc? | Ràng Buộc & Quy Tắc Hợp Lệ (Rules) | Thông Báo Lỗi Inline (Messages) |
221
+ | --- | --- | --- | --- | --- | --- |
222
+ | Mã hồ sơ | `N/A` | input | Bắt buộc | Kiểu: `slug_uppercase`<br>Regex: `^[A-Z0-9_-]{5,20}$`<br>Độ dài [5, 20]<br>Unique DB: `/api/v1/records/check-duplicate-code` | Required: "Vui lòng nhập mã hồ sơ."<br>"Mã hồ sơ chỉ được gồm chữ in hoa, chữ số và ký tự gạch (- _)"<br>"Độ dài mã hồ sơ bắt buộc từ 5 đến 20 ký tự"<br>DB: "Mã hồ sơ này đã tồn tại trên hệ thống. Vui lòng chọn mã khác." |
223
+ | Tên hồ sơ | `N/A` | input | Bắt buộc | Kiểu: `text_clean`<br>Độ dài [3, 100] | Required: "Vui lòng nhập tên hồ sơ."<br>"Tên hồ sơ bắt buộc từ 3 đến 100 ký tự" |
224
+ | Cấp độ dịch vụ | `N/A` | select | Bắt buộc | Kiểu: `enum` | Required: "Vui lòng chọn cấp độ dịch vụ." |
225
+ | Yêu cầu đặc biệt cho gói VIP | `N/A` | textarea | Tùy chọn | Độ dài [0, 500]<br>Phụ thuộc: `service_level == 'PREMIUM'` | Required: "Vui lòng nhập yêu cầu đặc biệt khi đăng ký gói VIP."<br>"Yêu cầu đặc biệt không được vượt quá 500 ký tự." |
226
+
227
+
228
+
229
+
230
+ <div id="custom-widgets"></div>
231
+
232
+ ## Đặc Tả Khối Giao Diện Tùy Biến (Custom UI Blocks)
233
+
234
+ ### Khối Tùy Biến (`custom`)
235
+ - **Mục đích thao tác:** Theo dõi tiến độ xử lý và xem chi tiết phản hồi từng bước duyệt
236
+
237
+
238
+
239
+
240
+
241
+ ## Đặc Tả Quy Trình Hành Động (Action Flows) {#action-flows}
242
+
243
+ ### Lưu & Xác Nhận
244
+ - **Mục đích thao tác:** Thẩm định toàn bộ form và gửi dữ liệu lên máy chủ
245
+ - **Vị trí hiển thị:** `form_footer` | **Trigger:** `click` | **Variant:** `primary`
246
+
247
+ ### Hủy Bỏ
248
+ - **Mục đích thao tác:** Hủy thao tác tạo mới và quay lại trang trước
249
+ - **Vị trí hiển thị:** `form_footer` | **Trigger:** `click` | **Variant:** `outline`
250
+
251
+
252
+
253
+
254
+
255
+ ## actors
256
+
257
+
258
+ ```yaml
259
+ []
260
+ ```
261
+
262
+
263
+
264
+ ## requirements
265
+
266
+
267
+ ```yaml
268
+ - &#34;[Ghi chú: Bắt buộc định nghĩa State Machine, và UI Permissions vào thuộc tính
269
+ states của từng item trong design.sections. KHÔNG liệt kê chung chung ở đây]&#34;
270
+ - &#34;Edge Cases: [Bắt buộc định nghĩa ngoại lệ như lỗi luồng, data hỏng,
271
+ concurrency]&#34;
272
+ ```
273
+
274
+
275
+
276
+
277
+
278
+
279
+
280
+
281
+
@@ -14,5 +14,5 @@ actors: []
14
14
  requirements: []
15
15
  acceptance: []
16
16
 
17
- # Filled by spec:split from qa/open/QA-<id>-NNNN.yaml (comma-separated). Omit when none.
17
+ # Filled by spec:split from qa/<SHORT>_NNNN.yaml (comma-separated). Omit when none.
18
18
  # "Q&A": QA-role-domain-function-0001, QA-role-domain-function-0002
@@ -0,0 +1,78 @@
1
+ # flowgrid-qa-item/v1 — authoring rules (QA inbox)
2
+
3
+ Hub template: `.flowgrid/templates/qa-item.yaml` (sau `flowgrid init`) · Workflow: `docs/workflows/qa-team.md`
4
+
5
+ ## File naming
6
+
7
+ | Part | Rule | Example |
8
+ |------|------|---------|
9
+ | **SHORT** | Slug màn/module, ổn định, `A-Z0-9` + `-` | `HOTEL-LIST`, `ADM-AUTH` |
10
+ | **NNNN** | Tăng dần theo SHORT (0001…) | `0001`, `0002` |
11
+ | **Path** | `qa/<SHORT>_<NNNN>.yaml` | `qa/HOTEL-LIST_0001.yaml` |
12
+ | **id** | **Bắt buộc** = basename không `.yaml` | `HOTEL-LIST_0001` |
13
+
14
+ Legacy id `QA-<page-id>-NNNN` vẫn đọc được — file mới dùng `<SHORT>_NNNN`.
15
+
16
+ Gợi ý SHORT từ `W-HOTEL-LIST` → `HOTEL-LIST` (bỏ prefix `W-`). Team có thể chọn slug module cố định (vd. `ADM-AUTH` cho nhiều màn auth).
17
+
18
+ ## Top-level fields
19
+
20
+ | Key | Required | Purpose |
21
+ |-----|----------|---------|
22
+ | `schema` | yes | Luôn `flowgrid-qa-item/v1` |
23
+ | `id` | yes | Khớp tên file |
24
+ | `status` | yes | `open` \| `closed` |
25
+ | `target.path` | yes | Bundle hoặc `01-backend-spec.yaml` (repo-relative) |
26
+ | `target.at` | yes | Pointer field — gắn `#missing_info <id>` / `#tech-debt:<id>` |
27
+ | `updates` | yes | Timeline append-only (≥1 dòng) |
28
+ | `screen` | khuyến nghị | `W-*` hoặc `page-id` — catalog + split |
29
+ | `bundleId` | khi legacy | `page-id` bundle để `Q&A` trên `ir/spec.yaml` |
30
+ | `kind` | khuyến nghị | `customer` \| `choice` \| `tech-debt` \| `integration` \| `coverage` |
31
+ | `skill` | khuyến nghị | Skill mở gap: `spec`, `grill-dev`, `api-spec`, … |
32
+ | `options` | optional | Copy options AskQuestion khi mở (audit) |
33
+ | `tags` | optional | Mirror tag đã gắn trên spec |
34
+
35
+ ## `updates[]` (append-only)
36
+
37
+ **Không** sửa/xóa dòng cũ. Chỉ **thêm** cuối mảng.
38
+
39
+ | `kind` | Ai / khi |
40
+ |--------|----------|
41
+ | `question` | Mở QA (Log Tech Debt) — **dòng đầu** |
42
+ | `answer` | `/qa-resolve` — sau khi patch `target.at` |
43
+ | `review` | `/qa-review` — `approved:` hoặc `needs-change:` |
44
+ | `note` | Ghi chú, không đổi spec |
45
+
46
+ | `at` | Format **bắt buộc** | `20260930 08:00` (YYYYMMDD HH:mm) |
47
+ | `by` | Member / role | `ba-lead`, `middle-dev` |
48
+ | `text` | Nội dung | Block `\|` multiline |
49
+
50
+ ### Vòng đời status
51
+
52
+ - Mở file: `status: open`, `updates[0].kind: question`
53
+ - `/qa-resolve`: append `answer`, `status: closed`, gỡ tag trên spec
54
+ - `/qa-review` + `needs-change`: append `review`, **`status: open`** lại (cùng file)
55
+
56
+ ## Agent workflow (mở QA)
57
+
58
+ 1. Đọc **whole** `.flowgrid/templates/qa-item.yaml` + file này.
59
+ 2. Chọn SHORT (team convention hoặc từ `screen`).
60
+ 3. `nextQaId(hub, SHORT)` hoặc glob `qa/<SHORT>_*.yaml` → max NNNN + 1.
61
+ 4. Copy template → `qa/<SHORT>_<NNNN>.yaml`; set `id`, `target`, `at` now, `updates[0]`.
62
+ 5. Patch spec: `#missing_info <id>` trên field `target.at`.
63
+ 6. `flowgrid split` + `flowgrid render`.
64
+
65
+ ## Agent output
66
+
67
+ - **YAML only** khi tạo/sửa QA file — không markdown giải thích trong repo.
68
+ - Quote string có `:`; multiline dùng `|`.
69
+
70
+ ## Không dùng QA file cho
71
+
72
+ - ADR → `architecture/09-decisions`
73
+ - Risk dài hạn → `architecture/11-risks`
74
+ - `openQuestions` trên bundle — **cấm**
75
+
76
+ ## Schema
77
+
78
+ Validate (optional CI): `templates/schemas/qa-item.schema.json` · `flowgrid` test `validateQaItem`.
@@ -1,15 +1,36 @@
1
- # Copy to qa/open/QA-<bundle.id>-NNNN.yaml — do not leave this file in qa/open/.
2
- id: QA-cmp-adm-002-02-01-02-0001
3
- kind: customer # customer | choice | tech-debt
4
- skill: spec # spec | grill-bqa | grill-dev | grill-docs | api-spec | api-update | api-integration
1
+ # flowgrid-qa-item/v1 — Authoring: qa-authoring.md · Hub: docs/workflows/qa-team.md
2
+ # Copy to qa/<SHORT>_NNNN.yaml (id = basename without .yaml). Append-only updates[].
3
+
4
+ schema: flowgrid-qa-item/v1
5
+ id: HOTEL-LIST_0001
6
+ screen: W-HOTEL-LIST
7
+ bundleId: cmp-adm-000-01-01
8
+ status: open
9
+ kind: tech-debt
10
+ skill: spec
11
+ tags:
12
+ - "#missing_info HOTEL-LIST_0001"
5
13
  target:
6
- path: surfaces/<surface>/CMP-*/<NN…>/<slug>.bundle.yaml
7
- at: design.zones.main.items.title.purpose
8
- question: |
9
- What is still unknown?
10
- options: []
11
- # - id: a
12
- # text: Option A
13
- # recommended: true
14
- # - id: other
15
- # text: Member supplies copy
14
+ path: surfaces/<surface>/CMP-*/<slug>.bundle.yaml
15
+ at: design.sections.main.items.filter_timezone.purpose
16
+ options:
17
+ - label: "(Recommended) Theo timezone property"
18
+ recommended: true
19
+ - label: Theo locale user
20
+ updates:
21
+ - at: "20260930 08:00"
22
+ by: <member-id>
23
+ kind: question
24
+ text: |
25
+ Filter timezone lấy theo property hay user locale?
26
+ # Append only — never delete or rewrite prior lines:
27
+ # - at: "20260930 10:00"
28
+ # by: ba-lead
29
+ # kind: answer
30
+ # text: |
31
+ # Theo property TZ; label UTC+7 trên UI.
32
+ # - at: "20261001 08:00"
33
+ # by: senior
34
+ # kind: review
35
+ # text: |
36
+ # needs-change: thêm AC khi property chưa set TZ.
@@ -0,0 +1,133 @@
1
+ # Template — Hợp đồng API (review & authoring)
2
+
3
+ **Mục đích:** Cùng một ngôn ngữ cho BA / Dev BE / Dev FE / QA — **đọc trên site**, **ghi trên YAML**. SSOT codegen BE là `api/<seq>/01-backend-spec.yaml`; OpenAPI và Markdown là **bản render**, không sửa tay làm nguồn.
4
+
5
+ **Workflow:** [docs/workflows/backend.md](../../docs/workflows/backend.md) · Skills: `/api-spec`, `/grill-api-spec`, `/openapi`, `/api-update`.
6
+
7
+ ---
8
+
9
+ ## Đọc trước khi viết (global)
10
+
11
+ | Ai | Đọc gì trên VitePress / docs hub | Khi nào mở YAML `01` |
12
+ |----|-----------------------------------|----------------------|
13
+ | BA / PO | `ir/generated/spec.md` (hành vi màn) + `ir/generated/api.md` (bảng endpoint tóm tắt) | Không — delta nghiệp vụ qua `/update-spec` + Dev |
14
+ | QA | `spec.md` + `api.md` (phạm vi API khớp scenario) | Chỉ khi trace lỗi `#err:*` / status code |
15
+ | Dev FE | `ir/design.yaml` (`apiRefs`, `#reuse-api`) | Không — contract BE không phải input layout |
16
+ | Dev BE | `api.md` → `01` → (preview) `02` sau `openapi_gen` | Author `/api-spec`, grill, codegen |
17
+
18
+ Sau `flowgrid split` + `flowgrid render`: sidebar leaf **Spec · W-*** · **Data model** · **API summary** (`api.md`).
19
+
20
+ ---
21
+
22
+ ## Bộ trio trên function leaf
23
+
24
+ ```text
25
+ surfaces/<surface>/CMP-*/<NN…>/<slug>/
26
+ <slug>.bundle.yaml # FE/business — KHÔNG author spec.api
27
+ ir/design.yaml # apiRefs, actions — FE + audit fe-be
28
+ ir/generated/api.md # render từ 01 (đọc team)
29
+ api/<seq>/
30
+ 01-backend-spec.yaml # SSOT BE — mẫu: backend-api.yaml
31
+ 02-openapi.yaml # CHỈ gen từ 01 (flowgrid openapi_gen)
32
+ 03-mock.yaml # optional — copy from api-03-mock.stub.yaml
33
+ ```
34
+
35
+ **Common API** (auth, dropdown dùng chung): `…/common/yaml/<slug>/` — cùng bộ file, một primary entity.
36
+
37
+ **Quy tắc:**
38
+
39
+ - Một file `01` = một **module** + một **primary entity** — không gộp cả CMP.
40
+ - Action đã có API: `#reuse-api` + `reuseFrom` trên `ir/design.yaml` — **không** tạo `api/<seq>/` mới.
41
+ - URI có **hậu tố hành động** (`/create`, `/{id}/update`, `/list`, `/{id}/detail`) — không REST mơ hồ `PUT /users/{id}`.
42
+
43
+ ---
44
+
45
+ ## Cấu trúc `01` (tóm tắt field)
46
+
47
+ Mẫu đầy đủ: [`backend-api.yaml`](./backend-api.yaml) (sau `flowgrid init` → `.flowgrid/templates/backend-api.yaml`).
48
+
49
+ | Khối | Vai trò |
50
+ |------|---------|
51
+ | `feature` | id, title, version, `source` (portal vs `base: none`) |
52
+ | `approval` | `draft` → `approved` trước `api-gen` (policy team) |
53
+ | `modules[].entities[]` | Bảng, field, quan hệ — khớp `design.sections[].db` / ERD |
54
+ | `api.endpoints[]` | method, path, `purpose`, `errorStorming`, `#err:*` |
55
+ | `requests` / `responses` | DTO — `meaning`/`purpose` khi có validation nghiệp vụ |
56
+ | `codegen` | `profile`, `module`, `entity` — grill-api-spec bổ sung `#gen:*` |
57
+ | `externalCalls` / `services` | Chỉ khi có `#call-external` / `#cross-entity-service` |
58
+
59
+ **Không** dùng [`backend-api.bundle.yaml`](./backend-api.bundle.yaml) để sinh `01` mới — file legacy (bundle lồng `spec.api`); chỉ tham chiếu lịch sử.
60
+
61
+ ---
62
+
63
+ ## OpenAPI (01 → 02 → hub)
64
+
65
+ Chuỗi **bắt buộc** sau mỗi lần sửa `01`:
66
+
67
+ ```text
68
+ flowgrid api:check --spec …/01-backend-spec.yaml
69
+ flowgrid openapi_gen --spec …/01-backend-spec.yaml # ghi sibling 02-openapi.yaml
70
+ flowgrid openapi_render # gộp → docs/openapi/api.yaml (hub)
71
+ flowgrid render # cập nhật ir/generated/api.md
72
+ ```
73
+
74
+ | File | SSOT? | Ai sửa |
75
+ |------|-------|--------|
76
+ | `01-backend-spec.yaml` | **Có** | `/api-spec`, `/api-update`, `/grill-api-spec` |
77
+ | `02-openapi.yaml` | Không — output gen | Vá thiếu bằng cách sửa `01`, gen lại |
78
+ | `docs/openapi/api.yaml` | Không — merge hub | `openapi_render` |
79
+ | `ir/generated/api.md` | Không — đọc | `flowgrid render` |
80
+
81
+ **Cấm:** sửa `02` tay; dùng `nestjs --openapi` (hoặc stack tương đương) ghi đè docs hub; `flowgrid check` trên `01` (`check` chỉ cho `*.bundle.yaml`).
82
+
83
+ Skill: `/openapi` · Redoc/Swagger UI: `openapi_build_ui` (tùy hub).
84
+
85
+ ---
86
+
87
+ ## Portal-backed vs BE-only
88
+
89
+ | | Portal (`source.base` ≠ `none`) | BE-only (`base: none`) |
90
+ |--|--------------------------------|-------------------------|
91
+ | Input `/api-spec` | `ir/design.yaml` + actions | Requirement / partner doc — **không** `ir/design` làm contract |
92
+ | Grill | `audit fe-be` + `audit api` | `audit api` only |
93
+ | `feature.source` | `portalSpec`, `portalRefs` | `integrationRefs`, auth API key/HMAC |
94
+
95
+ ---
96
+
97
+ ## Error storming (review nhanh)
98
+
99
+ | Tình huống endpoint | Tag / status gợi ý |
100
+ |---------------------|-------------------|
101
+ | Có `{id}` trong path | `#err:not-found` (404), `#err:idor-violation` (403) |
102
+ | POST/PUT form body | `#err:validation` (422) + field rules |
103
+ | Có permission | `#err:permission-denied` (403) |
104
+ | Create/duplicate | `#err:conflict` (409) |
105
+ | Partner/webhook | `#err:signature-invalid`, `#err:rate-limit`, `#err:unauthorized` |
106
+
107
+ 401/503/500 toàn cục: thường `$ref` OpenAPI components — không lặp từng endpoint.
108
+
109
+ ---
110
+
111
+ ## YAML an toàn
112
+
113
+ - Chuỗi có `:` → bọc `"..."`.
114
+ - Chạy `flowgrid api:check` trước handoff.
115
+ - Thiếu fact → AskQuestion hoặc `qa/` — **không** `openQuestions` trong YAML.
116
+
117
+ ---
118
+
119
+ ## Liên kết bundle FE
120
+
121
+ Trên bundle chỉ khai báo **hành vi UI** và `apiRefs`; chi tiết endpoint nằm trên `01`:
122
+
123
+ ```yaml
124
+ design:
125
+ actions:
126
+ - id: submit_form
127
+ apiRefs: [ feature.create ]
128
+ onSpecificError:
129
+ - condition: "422 Validation"
130
+ notes: "Inline errors"
131
+ ```
132
+
133
+ Xem [bundle-authoring.md § design.actions](./bundle-authoring.md#designactions-api-calls--ui-error-handling).
@@ -0,0 +1,76 @@
1
+ # Template — Mô tả bảng trên màn (review, multi-table)
2
+
3
+ **Mục đích:** Member/BA review **vai trò từng bảng** trước khi đọc cột chi tiết. SSOT kỹ thuật vẫn là `design.sections[].db` + `01-backend-spec.yaml`.
4
+
5
+ **Sau `flowgrid split`:** engine sinh `ir/generated/data-model.md` (tự động). Block YAML dưới đây **bổ sung** overview — author trên bundle `design.dataModel`.
6
+
7
+ ---
8
+
9
+ ## Author trên bundle (`design.dataModel`)
10
+
11
+ ```yaml
12
+ design:
13
+ dataModel:
14
+ erdRef: "<LCA>/common/db-erd.md"
15
+ notes: |
16
+ Màn này ghi bảng chính `records` và đọc `record_attachments` cho sidebar.
17
+ Không tạo dòng mới trên bảng phụ.
18
+ tables:
19
+ - schema: records
20
+ erdEntity: Record
21
+ roleOnScreen: read-write # read | write | read-write | join | aggregate
22
+ summary: "Hồ sơ chính — form create/update"
23
+ - schema: record_attachments
24
+ erdEntity: RecordAttachment
25
+ roleOnScreen: read
26
+ summary: "File đính kèm — chỉ list & download"
27
+ ```
28
+
29
+ | `roleOnScreen` | Ý nghĩa review |
30
+ |----------------|----------------|
31
+ | `read-write` | Form/list ghi + đọc cột persisted |
32
+ | `read` | Chỉ hiển thị / lookup |
33
+ | `write` | Chỉ insert/update (ít gặp tách read) |
34
+ | `join` | FK lookup từ bảng khác (select options) |
35
+ | `aggregate` | KPI/count — thường `#derived-data`, không map `db` |
36
+
37
+ ---
38
+
39
+ ## Cột chi tiết (per table)
40
+
41
+ Ghi trên từng control / list column trong bundle:
42
+
43
+ ```yaml
44
+ bind:
45
+ field: record_code # payload API / form state
46
+ db:
47
+ schema: records # khớp ERD + 01 entities[].table
48
+ field: code # khớp 01 entities[].fields[].name
49
+ enumMapping: # optional
50
+ ACTIVE: "Đang hoạt động"
51
+ ```
52
+
53
+ List nhiều bảng — **mỗi cột** khai `db` nếu sort/filter/search DB:
54
+
55
+ ```yaml
56
+ spec:
57
+ ui:
58
+ list:
59
+ columns:
60
+ - key: attachment_name
61
+ title: "Tệp"
62
+ db:
63
+ schema: record_attachments
64
+ field: file_name
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Checklist review (không chặn split)
70
+
71
+ 1. `flowgrid audit spec <bundle>` — `confirms[]` `CONFIRM_DB_*` → AskQuestion (`db-audit-wizard.md`).
72
+ 2. Mở `ir/generated/data-model.md` — một section `## Bảng \`...\`` per table.
73
+ 3. `01-backend-spec.yaml` — mỗi `db.schema` có entity; mỗi `db.field` có `fields[]`.
74
+ 4. ERD Phase 0 — entity mới đã có trên `db-erd.md`.
75
+
76
+ Workflow: [bundle-authoring.md](./bundle-authoring.md#data-model--phase-0-erd-vs-screen-detail) · [architecture-data.md](../../docs/workflows/architecture-data.md).
@@ -3,3 +3,7 @@
3
3
  Đặt `TC-*.yaml` mirror path function trên docs-hub (bỏ prefix `surfaces/`).
4
4
 
5
5
  Ví dụ docs: `surfaces/admin/CMP-ADM-002/02/01/login/` → `cases/admin/CMP-ADM-002/02/01/login/TC-*.yaml`
6
+
7
+ - SSOT ghi: `TC-*.yaml` (`schemaVersion: 2`) — copy mẫu từ `../_templates/TC.example.yaml` (init từ harness).
8
+ - SSOT đọc QA/Dev: `pnpm cases:render` → `TC-*.md` cùng thư mục — **không sửa tay** MD.
9
+ - Hướng dẫn: `../tpl-testcase-plan.md` · workflow `docs/workflows/test.md` (toolkit repo).
@@ -5,3 +5,12 @@ headings:
5
5
  cases: Testcase
6
6
  scenarios: Scenario
7
7
  plans: Kế hoạch kiểm thử
8
+ preconditions: Điều kiện tiên quyết
9
+ steps: Các bước thực hiện
10
+ expected: Kết quả mong đợi
11
+ traceability: Liên kết docs (traceability)
12
+ testMatrix: Ma trận kiểm thử
13
+ crossRefDocs: Đối chiếu docs hub
14
+ technical: Chi tiết kỹ thuật
15
+ testData: Dữ liệu kiểm thử
16
+ coverage: Phạm vi coverage
@@ -0,0 +1,9 @@
1
+ # Testcase plan — hướng dẫn hub
2
+
3
+ Bản đầy đủ (toolkit): sau `flowgrid init` copy từ package `harness/tests/templates/tpl-testcase-plan.md` hoặc xem repo FlowGrid `templates/tests-skeleton/tpl-testcase-plan.md` (sync với harness).
4
+
5
+ - SSOT ghi: `cases/**/TC-*.yaml`
6
+ - SSOT đọc team: `cases:render` → `TC-*.md` trên VitePress (`flowgrid dev` port 5174)
7
+ - Đối chiếu nghiệp vụ: docs hub `FLOWGRID_DOCS_ROOT` — bundle + `ir/generated/spec.md`
8
+
9
+ Mẫu vàng: `TC.example.yaml` (init / harness templates).