@fui-org/fui-cli 1.3.2 → 2.1.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 (115) hide show
  1. package/README.md +21 -3
  2. package/dist/fui-cx180e19.js +379 -0
  3. package/dist/fui.js +1 -1
  4. package/package.json +3 -6
  5. package/skills/fui/SKILL.md +9 -41
  6. package/skills/fui-skill/SKILL.md +95 -225
  7. package/skills/fui-skill/assets/projectdefaultstyle-3.0.css +555 -0
  8. package/skills/fui-skill/assets/projectdefaultstyle.css +207 -235
  9. package/skills/fui-skill/references/INDEX.md +105 -137
  10. package/skills/fui-skill/references/advanced-techniques.md +76 -68
  11. package/skills/fui-skill/references/coding-standards.md +56 -56
  12. package/skills/fui-skill/references/component-design.md +166 -173
  13. package/skills/fui-skill/references/component-quickref.md +61 -60
  14. package/skills/fui-skill/references/component-table.md +128 -117
  15. package/skills/fui-skill/references/components-dialog.md +55 -56
  16. package/skills/fui-skill/references/components-display.md +24 -30
  17. package/skills/fui-skill/references/components-echart.md +186 -261
  18. package/skills/fui-skill/references/components-input.md +72 -96
  19. package/skills/fui-skill/references/controls-patterns.md +196 -342
  20. package/skills/fui-skill/references/controls-styling-vocabulary.md +130 -97
  21. package/skills/fui-skill/references/db-table-design.md +24 -28
  22. package/skills/fui-skill/references/db-workflow.md +191 -390
  23. package/skills/fui-skill/references/default-function.md +169 -128
  24. package/skills/fui-skill/references/design-modes.md +35 -63
  25. package/skills/fui-skill/references/echart-templates.md +204 -196
  26. package/skills/fui-skill/references/fastproject.md +62 -60
  27. package/skills/fui-skill/references/fsheet.md +109 -124
  28. package/skills/fui-skill/references/fullstack-workflow.md +90 -128
  29. package/skills/fui-skill/references/module-data-patterns.md +31 -40
  30. package/skills/fui-skill/references/module-json-anatomy.md +47 -52
  31. package/skills/fui-skill/references/module-structure.md +80 -196
  32. package/skills/fui-skill/references/new-session.md +49 -51
  33. package/skills/fui-skill/references/pdfmake.md +17 -17
  34. package/skills/fui-skill/references/permission-system.md +89 -108
  35. package/skills/fui-skill/references/platform-architecture.md +128 -153
  36. package/skills/fui-skill/references/project-config.md +102 -134
  37. package/skills/fui-skill/references/project-provisioning.md +139 -244
  38. package/skills/fui-skill/references/script-map.md +208 -242
  39. package/skills/fui-skill/references/sql-clr-functions.md +98 -97
  40. package/skills/fui-skill/references/system-design.md +63 -88
  41. package/skills/fui-skill/references/tapi-file-api.md +46 -52
  42. package/skills/fui-skill/references/tapi-permission-patterns.md +51 -53
  43. package/skills/fui-skill/references/tapi-reference.md +132 -207
  44. package/skills/fui-skill/references/tools-registry.md +84 -460
  45. package/skills/fui-skill/references/ui-crosswindow-patterns.md +79 -75
  46. package/skills/fui-skill/references/ui-dialog-patterns.md +98 -72
  47. package/skills/fui-skill/references/ui-layout-patterns.md +26 -26
  48. package/skills/fui-skill/references/ui-patterns.md +71 -83
  49. package/skills/fui-skill/references/ui-screenshot-review.md +63 -62
  50. package/skills/fui-skill/references/ui-table-cell-patterns.md +61 -59
  51. package/skills/fui-skill/references/ui-templates.md +16 -23
  52. package/skills/fui-skill/references/verification.md +236 -246
  53. package/skills/fui-skill/references/watcher-patterns.md +30 -63
  54. package/skills/fui-skill/references/websocket-realtime.md +83 -66
  55. package/skills/fui-skill/scripts/component-3.0.js +298 -131
  56. package/skills/fui-skill/scripts/component.js +277 -271
  57. package/skills/fui-skill/scripts/componentTable-3.0.js +182 -53
  58. package/skills/fui-skill/scripts/componentTable.js +171 -49
  59. package/skills/fui-skill/scripts/defaultfunction-3.0.js +88 -3
  60. package/skills/fui-skill/scripts/defaultfunction.js +88 -3
  61. package/skills/fui-skill/scripts/fsheet.js +38 -0
  62. package/skills/fui-target/.claude-plugin/plugin.json +6 -0
  63. package/skills/fui-target/hooks/hooks.json +1 -0
  64. package/skills/fui-target/hooks/register.tsx +71 -0
  65. package/skills/fui-target/types/index.d.ts +7 -0
  66. package/dist/fui-y8an39cn.js +0 -420
  67. package/skills/fui-skill/README.md +0 -112
  68. package/skills/fui-skill/metadata.json +0 -75
  69. package/skills/fui-skill-cli/SKILL.md +0 -139
  70. package/skills/fui-skill-cli/references/INDEX.md +0 -110
  71. package/skills/fui-skill-cli/references/advanced-techniques.md +0 -168
  72. package/skills/fui-skill-cli/references/coding-standards.md +0 -112
  73. package/skills/fui-skill-cli/references/component-design.md +0 -448
  74. package/skills/fui-skill-cli/references/component-quickref.md +0 -78
  75. package/skills/fui-skill-cli/references/component-table.md +0 -248
  76. package/skills/fui-skill-cli/references/components-dialog.md +0 -191
  77. package/skills/fui-skill-cli/references/components-display.md +0 -141
  78. package/skills/fui-skill-cli/references/components-echart.md +0 -316
  79. package/skills/fui-skill-cli/references/components-input.md +0 -335
  80. package/skills/fui-skill-cli/references/controls-patterns.md +0 -701
  81. package/skills/fui-skill-cli/references/controls-styling-vocabulary.md +0 -137
  82. package/skills/fui-skill-cli/references/db-table-design.md +0 -73
  83. package/skills/fui-skill-cli/references/db-workflow.md +0 -288
  84. package/skills/fui-skill-cli/references/default-function.md +0 -425
  85. package/skills/fui-skill-cli/references/design-modes.md +0 -57
  86. package/skills/fui-skill-cli/references/echart-templates.md +0 -489
  87. package/skills/fui-skill-cli/references/fastproject.md +0 -99
  88. package/skills/fui-skill-cli/references/fsheet.md +0 -203
  89. package/skills/fui-skill-cli/references/fullstack-workflow.md +0 -313
  90. package/skills/fui-skill-cli/references/module-data-patterns.md +0 -117
  91. package/skills/fui-skill-cli/references/module-json-anatomy.md +0 -132
  92. package/skills/fui-skill-cli/references/module-structure.md +0 -141
  93. package/skills/fui-skill-cli/references/new-session.md +0 -85
  94. package/skills/fui-skill-cli/references/pdfmake.md +0 -60
  95. package/skills/fui-skill-cli/references/permission-system.md +0 -150
  96. package/skills/fui-skill-cli/references/platform-architecture.md +0 -269
  97. package/skills/fui-skill-cli/references/project-config.md +0 -303
  98. package/skills/fui-skill-cli/references/project-provisioning.md +0 -278
  99. package/skills/fui-skill-cli/references/script-map.md +0 -262
  100. package/skills/fui-skill-cli/references/sql-clr-functions.md +0 -225
  101. package/skills/fui-skill-cli/references/system-design.md +0 -89
  102. package/skills/fui-skill-cli/references/tapi-file-api.md +0 -185
  103. package/skills/fui-skill-cli/references/tapi-permission-patterns.md +0 -156
  104. package/skills/fui-skill-cli/references/tapi-reference.md +0 -474
  105. package/skills/fui-skill-cli/references/tools-registry.md +0 -84
  106. package/skills/fui-skill-cli/references/ui-crosswindow-patterns.md +0 -321
  107. package/skills/fui-skill-cli/references/ui-dialog-patterns.md +0 -255
  108. package/skills/fui-skill-cli/references/ui-layout-patterns.md +0 -176
  109. package/skills/fui-skill-cli/references/ui-patterns.md +0 -303
  110. package/skills/fui-skill-cli/references/ui-screenshot-review.md +0 -95
  111. package/skills/fui-skill-cli/references/ui-table-cell-patterns.md +0 -318
  112. package/skills/fui-skill-cli/references/ui-templates.md +0 -22
  113. package/skills/fui-skill-cli/references/verification.md +0 -236
  114. package/skills/fui-skill-cli/references/watcher-patterns.md +0 -163
  115. package/skills/fui-skill-cli/references/websocket-realtime.md +0 -271
@@ -1,80 +1,56 @@
1
1
  # Full-Stack Module Workflow
2
2
 
3
- > File này sở hữu: **quy trình 6 bước tạo một module fullstack, UI-first (phân tích → dựng UI data cứng → chốt contract → SP → wiring API → kiểm chứng tĩnh)**, và **quy trình Design Review Gate** (SKILL.md §3 chỉ giữ *luật* "phải qua gate", các bước nằm ở đây). Quy ước tAPI xem [tapi-reference.md](tapi-reference.md); thiết kế nhiều module xem [system-design.md](system-design.md).
3
+ > Owns: **the 6-step UI-first fullstack module workflow (analyze → UI with hard-coded data → lock contract → SP → API wiring → static verification)** and **the Design Review Gate procedure** (SKILL.md §3 holds only the rule "must pass the gate"; the steps live here). tAPI conventions: [tapi-reference.md](tapi-reference.md); multi-module design: [system-design.md](system-design.md).
4
4
 
5
- Quy trình 6 bước để thiết kế một FUI module hoàn chỉnh: có cả UI (FUI) lẫn backend API (tAPI).
6
-
7
- **Nguyên tắc UI-first:** dựng UI bằng dữ liệu cứng trước, xác nhận hình ảnh đúng bằng `module_simulate({ renderUI: true })`, RỒI mới chốt contract API và viết SP. Tách pha "làm UI" khỏi pha "nối API" giảm hẳn lỗi so với viết cả hai cùng lúc — sửa cấu trúc data khi còn là literal trong `data[]` rẻ hơn nhiều so với sửa sau khi đã có `IN`/`OUT`/`watch` phụ thuộc vào nó. Không có bước nào trong quy trình này gọi API/SP thật để "test" — kiểm chứng luôn là đọc + suy luận + mock (xem [verification.md](verification.md)).
8
-
9
- Đọc [tapi-reference.md](tapi-reference.md) trước khi bắt đầu bước 3.
5
+ **UI-first:** build UI (FUI) with hard-coded data, confirm visuals with `fui module simulate --render`, THEN lock the API (tAPI) contract and write SPs. Fixing data shape while it is a literal in `data[]` is far cheaper than after `IN`/`OUT`/`watch` depend on it. No step calls a real API/SP to "test" — verification = read + reason + mock ([verification.md](verification.md)). Read [tapi-reference.md](tapi-reference.md) before step 3.
10
6
 
11
7
  ---
12
8
 
13
- ## Bước 1 — Phân tích yêu cầu
9
+ ## Step 1 — Analyze requirements
14
10
 
15
- Trước khi viết bất kỳ dòng code nào, xác định rõ:
11
+ **1.1 Business need:** list / search / filter? add / edit / delete? report / statistics? workflow (approve, reject, status)?
16
12
 
17
- **1.1 Nghiệp vụ cần làm gì?**
18
- - Danh sách / tìm kiếm / lọc dữ liệu?
19
- - Thêm / sửa / xoá bản ghi?
20
- - Báo cáo / thống kê?
21
- - Workflow (duyệt, từ chối, trạng thái)?
13
+ **1.2 Data (initial estimate — locked in step 3):** main entity and linked entities; which fields are displayed, which are input.
22
14
 
23
- **1.2 Dữ liệu liên quan (ước lượng ban đầu — sẽ chốt lại chính xác ở bước 3):**
24
- - Entity chính là gì? Các entity liên kết?
25
- - Trường nào hiển thị, trường nào nhập liệu?
15
+ **1.3 Permissions and auth:**
26
16
 
27
- **1.3 Quyền và xác thực:**
28
- - Module có cần login không? (nếu không → dùng `AUTH_` trong SP)
29
- - Có phân quyền theo `sys_SystemRight` không? → xử lý trong thân SP
17
+ - Login required? (no → use `AUTH_` in the SP)
18
+ - Rights by `sys_SystemRight`? → handle in the SP body
30
19
 
31
- **Output bước 1:** Danh sách tính năng + tên các entity chính (chưa cần chốt kiểu dữ liệu/tên cột).
20
+ **Output:** feature list + main entity names (types/column names not yet locked).
32
21
 
33
22
  ---
34
23
 
35
- ## Bước 1b — Design Review Gate (bắt buộc, trước khi viết dòng code đầu tiên)
24
+ ## Step 1b — Design Review Gate (mandatory, before the first line of code)
36
25
 
37
- SKILL.md §3 quy định **luật**: mọi hệ thống/trang/chức năng mới đều phải qua gate này. Đây là
38
- **quy trình** của nó. Áp dụng cho cả module fullstack lẫn module chỉ có UI.
26
+ SKILL.md §3 = the **rule** (every new system/page/function passes); this = the **procedure**, for fullstack and UI-only modules.
39
27
 
40
- 1. **Phân tích hiệu quả nghiệp vụ** — bao nhiêu bước để user hoàn thành tác vụ, dữ liệu nào thực sự
41
- cần hiển thị/nhập, có bước nào thừa không.
42
- 2. **Tham khảo pattern đã có trong project** — `module_list` + `module_get` xem module tương tự
43
- (layout, cách đặt tên control, vị trí action, cách trình bày filter/table/dialog). Thiết kế mới
44
- phải đồng bộ với trang hiện có, **không tự sáng tạo kiểu khác nếu project đã có convention**.
45
- 3. **Phác thảo UI trước** bằng lời hoặc khung layout sơ bộ — control nào, ở đâu, luồng dialog/form
46
- ra sao.
47
- 4. **Tự đánh giá lại phác thảo** — thân thiện không? số bước hợp lý không? vị trí nút Thêm/Sửa/Xóa,
48
- filter, phân trang có đúng chỗ user mong đợi không? nhất quán với trang khác không? Phát hiện bất
49
- hợp lý → **sửa phác thảo trước**, không mang bất hợp lý vào code.
50
- 5. Chỉ khi phác thảo đã hợp lý mới viết code thật (bước 2 trở đi).
28
+ 1. **Business efficiency** — steps to finish the task, data truly needed, redundant steps.
29
+ 2. **Project patterns** — `fui module list` + `fui module get` on similar modules (layout, control naming, action placement, filter/table/dialog). Match existing pages; **never invent a new style when a convention exists**.
30
+ 3. **Sketch the UI** in words/rough layout — controls, placement, dialog/form flow.
31
+ 4. **Self-review** — friendly? step count? Add/Edit/Delete, filters, pagination where expected? consistent? Issues → **fix the sketch first**, never in code.
32
+ 5. Only then write code (step 2+).
51
33
 
52
- **Chọn phương án dựng UI:**
34
+ **Choose the build approach:**
53
35
 
54
- | Phương án | Khi nào dùng |
55
- |---|---|
56
- | **A — module.json thuần** | Trang đơn giản: hiển thị dữ liệu, CRUD một bảng, form nhập liệu cơ bản. Ít file, dễ maintain. |
57
- | **B — Vue component (`uc-*.vue`)** | Giao diện phức tạp: dashboard nhiều vùng, layout tùy chỉnh, logic UI lặp lại nhiều nơi, hoặc `controls` vượt ~200 dòng ([component-design.md](component-design.md)). |
36
+ | Approach | When |
37
+ | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
38
+ | **A — plain module.json** | Simple page: data display, single-table CRUD, basic form. Fewer files, easy to maintain. |
39
+ | **B — Vue component (`uc-*.vue`)** | Complex UI: multi-area dashboard, custom layout, UI logic reused in many places, or `controls` over ~200 lines ([component-design.md](component-design.md)). |
58
40
 
59
- > User không chỉ định → **tự đề xuất** dựa trên mô tả, giải thích ngắn lý do và **chờ xác nhận** —
60
- > đừng tự chọn im lặng.
41
+ > Unspecified → **propose** one with a short reason and **wait for confirmation**; never choose silently.
61
42
 
62
- **Ưu tiên component**: dùng `f-*` trước (`f-button` thay `v-btn`, `f-table` thay `v-data-table` cho
63
- MỌI bảng, `f-echart` cho mọi biểu đồ), chỉ dùng `v-*` khi không có FUI equivalent.
64
- → [component-quickref.md](component-quickref.md)
43
+ **Component priority**: `f-*` first (`f-button` over `v-btn`, `f-table` over `v-data-table` for EVERY table, `f-echart` for every chart); `v-*` only when no FUI equivalent exists. → [component-quickref.md](component-quickref.md)
65
44
 
66
- **Cổng Design System** chạy song song ở đây: xác định App-mode hay Web-mode và kiểm tra
67
- `{projectId}/DESIGN.md` **trước khi** phác thảo — hai chế độ có bộ quy tắc thẩm mỹ riêng, không vay
68
- mượn qua lại. → [design-modes.md](design-modes.md)
45
+ **Design System gate** (parallel): decide App-mode vs Web-mode and check `{projectId}/DESIGN.md` **before** sketching — separate aesthetic rules; never mix. → [design-modes.md](design-modes.md)
69
46
 
70
- **Output bước 1b:** phác thảo UI đã tự review, phương án A/B đã chốt (có xác nhận của user nếu do ta
71
- đề xuất), chế độ thẩm mỹ đã xác định.
47
+ **Output:** self-reviewed sketch, approach A/B locked (user-confirmed if we proposed it), aesthetic mode decided.
72
48
 
73
49
  ---
74
50
 
75
- ## Bước 2 — Dựng UI với dữ liệu cứng
51
+ ## Step 2 — Build UI with hard-coded data
76
52
 
77
- Thiết kế toàn bộ UI của module bằng dữ liệu **literal** khai báo thẳng trong `data[]` — chưa có API nào cả. Xem [module-json-anatomy.md](module-json-anatomy.md) và [controls-patterns.md](controls-patterns.md) để biết cấu trúc control/grid.
53
+ Whole UI on **literal** data in `data[]`, no API yet. Structure: [module-json-anatomy.md](module-json-anatomy.md), [controls-patterns.md](controls-patterns.md).
78
54
 
79
55
  ```json
80
56
  "data": [
@@ -89,34 +65,28 @@ Thiết kế toàn bộ UI của module bằng dữ liệu **literal** khai báo
89
65
  ]
90
66
  ```
91
67
 
92
- Dựng `f-table`/`v-dialog`/form theo dữ liệu cứng này — component-table/dialog patterns xem [component-table.md](component-table.md), [ui-templates.md](ui-templates.md).
68
+ `f-table`/`v-dialog`/form patterns: [component-table.md](component-table.md), [ui-templates.md](ui-templates.md).
93
69
 
94
- **QA hình ảnh ngay ở bước này:** `module_simulate({ renderUI: true, vueData: {...dữ liệu cứng nếu muốn override} })`, đọc screenshot + DOM audit, tự sửa lỗi hiển thị (tràn ngang, dialog vỡ, thiếu label...) trước khi đi tiếp — không mang lỗi UI sang các bước sau.
70
+ **Visual QA now:** `fui module simulate --render` (vueData override: `fui module simulate --help`). Read screenshot + DOM audit; fix display bugs (horizontal overflow, broken dialog, missing labels...) before moving on.
95
71
 
96
- **Output bước 2:** `module.json` có layout hoàn chỉnh, chạy được với data cứng, đã qua `renderUI` QA sạch.
72
+ **Output:** `module.json` with complete layout, running on hard-coded data, clean `--render` QA.
97
73
 
98
74
  ---
99
75
 
100
- ## Bước 3 — Chốt cấu trúc data + thiết kế API endpoints
101
-
102
- Từ chính các field đã dùng ở data cứng bước 2 (đây là lý do bước 2 đi trước — cấu trúc field đã được xác nhận đúng bằng mắt trước khi biến thành contract SP), chốt:
103
- - Tên field chính xác, kiểu dữ liệu (dùng để suy ra kiểu cột SQL)
104
- - Entity/table nào sinh ra field nào
76
+ ## Step 3 — Lock data shape + design API endpoints
105
77
 
106
- Rồi map sang các SP tAPI cần tạo. Quy ước đặt tên đầy đủ (`spAPI_*` / `spAPI_AUTH_*` / `spAPIFILE_*`, params `@url1_`, response contract) là của [tapi-reference.md](tapi-reference.md) — ở đây chỉ áp dụng vào việc map tính năng sang SP theo pattern `spAPI_{Entity}{Action}`.
78
+ From the step-2 fields (visually confirmed before becoming an SP contract), lock exact field names + types (→ SQL column types) and the source entity/table of each. Map features to SPs as `spAPI_{Entity}{Action}`; full naming (`spAPI_*` / `spAPI_AUTH_*` / `spAPIFILE_*`, `@url1_`, response contract) is in [tapi-reference.md](tapi-reference.md).
107
79
 
108
- **Bảng mapping thường gặp:**
80
+ | Feature | SP name | Main params |
81
+ | ----------------- | ---------------------------- | ---------------------- |
82
+ | List | `spAPI_{Entity}List` | Filter params (custom) |
83
+ | Detail | `spAPI_{Entity}Get` | `@url1_{EntityID}` |
84
+ | Insert | `spAPI_{Entity}Insert` | Entity fields |
85
+ | Update | `spAPI_{Entity}Update` | ID + fields to update |
86
+ | Delete | `spAPI_{Entity}Delete` | `@url1_{EntityID}` |
87
+ | Lookup / dropdown | `spAPI_AUTH_{Entity}Options` | No auth, returns list |
109
88
 
110
- | Tính năng | SP name | Params chính |
111
- |---|---|---|
112
- | Lấy danh sách | `spAPI_{Entity}List` | Filter params (custom) |
113
- | Lấy chi tiết | `spAPI_{Entity}Get` | `@url1_{EntityID}` |
114
- | Thêm mới | `spAPI_{Entity}Insert` | Các field của entity |
115
- | Cập nhật | `spAPI_{Entity}Update` | ID + các field cần cập nhật |
116
- | Xoá | `spAPI_{Entity}Delete` | `@url1_{EntityID}` |
117
- | Lookup / dropdown | `spAPI_AUTH_{Entity}Options` | Không cần auth, trả danh sách |
118
-
119
- **Ví dụ cho module "Quản lý Sinh viên"** (khớp field đã dùng ở data cứng bước 2: `StudentID`, `FullName`, `ClassID`, `ClassName`, `GPA`):
89
+ **Example — "Student management"** (matches step-2 fields `StudentID`, `FullName`, `ClassID`, `ClassName`, `GPA`):
120
90
 
121
91
  ```
122
92
  spAPI_StudentList -- danh sách, lọc theo ClassID + Keyword — trả đúng các cột đã hiển thị ở bước 2
@@ -127,15 +97,15 @@ spAPI_StudentDelete -- xoá theo url1=StudentID
127
97
  spAPI_AUTH_ClassOptions -- dropdown danh sách lớp (không cần auth)
128
98
  ```
129
99
 
130
- **Output bước 3:** Danh sách đầy đủ SP, tên + params + response shape khớp field đã dùng trong UI.
100
+ **Output:** full SP list; names + params + response shape match the fields used in the UI.
131
101
 
132
102
  ---
133
103
 
134
- ## Bước 4 — Viết SQL Stored Procedures
104
+ ## Step 4 — Write SQL stored procedures
135
105
 
136
- Viết SP theo đúng quy tắc tAPI và đúng contract đã chốt ở bước 3. Xem chi tiết tại [tapi-reference.md](tapi-reference.md).
106
+ Per tAPI rules ([tapi-reference.md](tapi-reference.md)) and the step-3 contract.
137
107
 
138
- **Template SP SELECT (danh sách):**
108
+ **SELECT (list):**
139
109
 
140
110
  ```sql
141
111
  CREATE PROCEDURE spAPI_StudentList
@@ -152,7 +122,7 @@ AS BEGIN
152
122
  END
153
123
  ```
154
124
 
155
- **Template SP INSERT:**
125
+ **INSERT:**
156
126
 
157
127
  ```sql
158
128
  CREATE PROCEDURE spAPI_StudentInsert
@@ -172,7 +142,7 @@ AS BEGIN
172
142
  END
173
143
  ```
174
144
 
175
- **Template SP DELETE:**
145
+ **DELETE:**
176
146
 
177
147
  ```sql
178
148
  CREATE PROCEDURE spAPI_StudentDelete
@@ -184,7 +154,7 @@ AS BEGIN
184
154
  END
185
155
  ```
186
156
 
187
- **Template SP GET (chi tiết, dùng convert_to_object):**
157
+ **GET (detail, convert_to_object):**
188
158
 
189
159
  ```sql
190
160
  CREATE PROCEDURE spAPI_StudentGet
@@ -199,38 +169,30 @@ AS BEGIN
199
169
  END
200
170
  ```
201
171
 
202
- > Dùng `convert_to_object = ''` khi SP trả về đúng một record → response dạng object thay vì `data[0][0]`.
172
+ > `convert_to_object = ''` when the SP returns exactly one record → response is an object instead of `data[0][0]`.
203
173
 
204
- Deploy bằng `db_sp_save` + `db_sp_deploy` (không tự gọi endpoint để "chạy thử" — xem bước 6).
174
+ Deploy with `fui sp save` + `fui sp deploy` (never call the endpoint to "try it" — see step 6).
205
175
 
206
- **KHÔNG viết `GRANT EXECUTE` vào file .sql.** Thân `CREATE PROCEDURE` kéo dài **tới hết batch**, mà
207
- `_sql_execute_NonQuery` gửi đúng một batch và **không hỗ trợ `GO`** (`GO` là chỉ thị của client, không
208
- phải lệnh T-SQL). Nên câu `GRANT` đặt sau `END` bị **nuốt vào trong thân SP** — nó thành một lệnh chạy
209
- mỗi lần gọi SP, chứ không cấp quyền lúc deploy. Không lỗi nào nổi lên; chỉ là endpoint tAPI trả lỗi
210
- quyền trong khi SP nhìn vào thì hoàn toàn đúng.
176
+ **NEVER put `GRANT EXECUTE` in the .sql file.** A `CREATE PROCEDURE` body runs **to end of batch**; `_sql_execute_NonQuery` sends one batch and **does not support `GO`** (client directive, not T-SQL). A `GRANT` after `END` is **swallowed into the SP body** — runs on every call, never grants at deploy. No error; the endpoint just returns a permission error while the SP looks right.
211
177
 
212
- `db_sp_deploy` **tự cấp quyền** cho procedure mới (không áp dụng cho FUNCTION — function không cần
213
- EXECUTE cho `[public]`), rồi **hỏi lại `sys.database_permissions` xem quyền có thật hay không** và báo
214
- trong kết quả:
178
+ `fui sp deploy` **auto-grants** new procedures (not FUNCTIONs — functions need no EXECUTE for `[public]`), then **re-checks `sys.database_permissions`** and reports:
215
179
 
216
- - `✓ [public] đã có quyền EXECUTE trên "..."` — xong.
217
- - `❗ [public] CHƯA có quyền EXECUTE ...` — kết quả in sẵn câu chạy được, copy nguyên văn:
218
- `db_sql_execute_nonquery({ sqlcmd: "GRANT EXECUTE ON [dbo].[spAPI_StudentList] TO [public] AS [dbo]", db: "..." })`
219
- - Bước cấp quyền hỏng nhưng deploy thành công thì **SP vẫn đã lên server** — chạy câu GRANT ở trên,
220
- **đừng deploy lại**.
180
+ - `✓ [public] đã có quyền EXECUTE trên "..."` — done.
181
+ - `❗ [public] CHƯA có quyền EXECUTE ...` — the output prints a runnable command; copy verbatim:
182
+ `fui exec "GRANT EXECUTE ON [dbo].[spAPI_StudentList] TO [public] AS [dbo]" --db ...`
183
+ - Grant failed but deploy succeeded → **the SP is already on the server**; run the GRANT above, **do not redeploy**.
221
184
 
222
- Deploy SP bằng đường khác (`db_sql_execute_nonquery` với `CREATE PROCEDURE`) thì **không có auto-grant
223
- và không xoá cache tham số tAPI** — tool sẽ cảnh báo và nêu đúng hai lệnh cần chạy tiếp.
185
+ Deploying via `fui exec` with `CREATE PROCEDURE` → **no auto-grant, no tAPI param-cache clear**; fui warns and names the two commands to run next.
224
186
 
225
- **Output bước 4:** Toàn bộ SQL script đã deploy cho các SP thiết kế ở bước 3.
187
+ **Output:** all step-3 SPs deployed.
226
188
 
227
189
  ---
228
190
 
229
- ## Bước 5 — Thay dữ liệu cứng bằng binding API
191
+ ## Step 5 — Replace hard-coded data with API bindings
230
192
 
231
- Sửa lại `module.json` đã dựng ở bước 2: giữ nguyên layout, thay giá trị literal trong `data[]` bằng named action `IN`/`OUT`/`CALLBACK` trỏ vào các SP vừa deploy.
193
+ Keep the step-2 layout; replace `data[]` literals with named `IN`/`OUT`/`CALLBACK` actions on the deployed SPs.
232
194
 
233
- **5.1 Khai báo action thay cho data cứng**
195
+ **5.1 Actions replacing hard-coded data**
234
196
 
235
197
  ```json
236
198
  "data": [
@@ -270,7 +232,7 @@ Sửa lại `module.json` đã dựng ở bước 2: giữ nguyên layout, thay
270
232
  ]
271
233
  ```
272
234
 
273
- **5.2 Khai báo watch để tự load khi filter thay đổi**
235
+ **5.2 `watch` to reload when filters change**
274
236
 
275
237
  ```json
276
238
  "watch": {
@@ -279,42 +241,42 @@ Sửa lại `module.json` đã dựng ở bước 2: giữ nguyên layout, thay
279
241
  }
280
242
  ```
281
243
 
282
- **5.3 Thêm `{ "CALL": "vueData.fetchStudents" }` cuối `data[]`** để auto-load khi module mở.
244
+ **5.3** Append `{ "CALL": "vueData.fetchStudents" }` at the end of `data[]` to auto-load on open.
283
245
 
284
- **Output bước 5:** `module.json` đã wiring API đầy đủ, layout không đổi so với bước 2.
246
+ **Output:** `module.json` fully wired, layout unchanged from step 2.
285
247
 
286
248
  ---
287
249
 
288
- ## Bước 6 — Kiểm chứng tĩnh và hoàn thiện
250
+ ## Step 6 — Static verification and finish
251
+
252
+ Pre-publish checklist — **no step calls a real API/SP/DML**:
253
+
254
+ **API/SP** — full checklist (naming, params, security, `GRANT EXECUTE`, deploy workflow): [verification.md](verification.md). Here:
289
255
 
290
- Checklist trước khi publish — **không bước nào gọi API/SP/DML thật**:
256
+ - [ ] `AUTH_` on endpoints that need no login
257
+ - [ ] `fui sp verify` per new SP — reads the real body, infers response shape/error contract, checks params, emits a `--mocks` snippet (no endpoint call)
258
+ - [ ] **Write** APIs: read the body and reason (WHERE, transaction, RAISERROR) — no trial run
291
259
 
292
- **API/SP** — checklist đầy đủ (naming, params, security, `GRANT EXECUTE`, deploy workflow) ở
293
- [verification.md](verification.md#deploy-workflow). Ở bước này:
294
- - [ ] SP có `AUTH_` cho các endpoint không cần login
295
- - [ ] `db_sp_verify` cho từng SP mới deploy — đọc thân SP thật, suy luận response shape/contract lỗi, đối chiếu params, sinh sẵn snippet `apiMocks` (không gọi endpoint thật)
296
- - [ ] API **ghi**: đọc thân SP suy luận (WHERE, transaction, RAISERROR) — không có "chạy thử" nào khác ngoài đọc + suy luận
260
+ **module.json:**
297
261
 
298
- **FUI module.json:**
299
- - [ ] `API` path trong mỗi action khớp đúng `/{apiName}/{FunctionName}`
300
- - [ ] `IN` params khớp đúng tên param trong SP (phân biệt hoa thường)
301
- - [ ] Route params (url1, url2) được truyền qua URL, không phải qua `IN`
302
- - [ ] `OUT` nhận đúng kiểu dữ liệu (array hay object tuỳ SP) — đối chiếu với response shape suy luận từ `db_sp_verify`
303
- - [ ] `watch` đã khai báo cho các filter tự động reload
304
- - [ ] `data[]` khai báo named action fetch ban đầu, kết thúc bằng `{ "CALL": ... }` auto-startup
262
+ - [ ] Each action's `API` path matches `/{apiName}/{FunctionName}`
263
+ - [ ] `IN` params match SP param names exactly (case-sensitive)
264
+ - [ ] Route params (url1, url2) go via the URL, not `IN`
265
+ - [ ] `OUT` receives the right type (array vs object per SP) — check against the shape inferred by `fui sp verify`
266
+ - [ ] `watch` declared for auto-reload filters
267
+ - [ ] `data[]` declares the initial fetch action and ends with a startup `{ "CALL": ... }`
305
268
 
306
- **Kiểm chứng cuối cùng theo thứ tự:** `module_validate` (lỗi cú pháp/quy tắc) → `module_outline` (review cấu trúc UI dạng text) → `module_simulate` với `apiMocks` lấy từ snippet của `db_sp_verify` (verify luồng action/watch/dialog) → nếu còn nghi ngờ hiển thị, `module_simulate({ renderUI: true })` lần cuối với cùng `apiMocks`.
269
+ **Final verification, in order:** `fui module validate` (syntax/rule errors) → `fui module outline` (text review of UI structure) → `fui module simulate --mocks '{...}'` using the `fui sp verify` snippet (action/watch/dialog flow) → if display is still in doubt, a last `fui module simulate --render` with the same `--mocks`. (`fui module check` runs validate + outline + simulate in one step.)
307
270
 
308
- **Output bước 6:** Module hoạt động end-to-end, UI ↔ API thông suốt, chưa từng có lời gọi thật nào trong suốt quá trình kiểm chứng.
271
+ **Output:** module works end-to-end, UI ↔ API connected, zero real calls during verification.
309
272
 
310
273
  ---
311
274
 
312
- ## Ví dụ đầu ra hoàn chỉnh
275
+ ## Complete output example
313
276
 
314
- ### SP cần tạo (bước 4 output)
277
+ ### SPs (step 4)
315
278
 
316
- Mỗi SP là **một file riêng** qua `db_sp_save` → `db_sp_deploy`. Không GRANT trong file, không `GO`
317
- (xem bước 4); tham số tAPI **không được có default value** — `db_sp_deploy` chặn cứng.
279
+ Each SP is **its own file** via `fui sp save` → `fui sp deploy`. No GRANT in the file, no `GO` (step 4); tAPI params **must not have default values** — `fui sp deploy` hard-blocks them.
318
280
 
319
281
  ```sql
320
282
  -- 1. Danh sách (file spAPI_StudentList.sql)
@@ -334,7 +296,7 @@ AS BEGIN
334
296
  END
335
297
  ```
336
298
 
337
- ### module.json actions (bước 5 output)
299
+ ### module.json actions (step 5)
338
300
 
339
301
  ```json
340
302
  "fetchStudents": { "API": "/me/StudentList", "IN": { "Keyword": "vueData.keyword" }, "OUT": "studentList" },
@@ -343,9 +305,9 @@ END
343
305
 
344
306
  ---
345
307
 
346
- ## Lưu ý quan trọng
308
+ ## Key notes
347
309
 
348
- - **`{apiName}`** trong API path là tên apiName của app trong tAPI (ví dụ `me`, `lms`, `hr`). Hỏi người dùng nếu chưa biết. **Một project có thể dùng nhiều apiName** (mỗi cái một database) — mỗi alias cần một lần `db_connect` riêng, và alias trong path chính là tham số `db` của các DB tool ([db-workflow.md](db-workflow.md) §4).
349
- - **Route params** (`@url1_`) truyền qua URL, không qua `IN`: dùng backtick prefix trong API path: `"API": "/me/StudentDelete/\`{{vueData.selectedID}}"`
350
- - **Response từ SP có nhiều SELECT** → `data[0]`, `data[1]`... — khai báo rõ trong `OUT` hoặc dùng `EXE` để tách.
351
- - **`convert_to_object = ''`** → response là object phẳng, đọc trực tiếp `vueData.studentDetail.FullName` thay vì `vueData.studentDetail[0].FullName`.
310
+ - **`{apiName}`** in the API path is the app's tAPI apiName (e.g. `me`, `lms`, `hr`). Ask the user if unknown. **A project may use several apiNames** (one database each) — each alias needs its own `fui db add`, and the alias in the path is the `--db` argument of DB commands ([db-workflow.md](db-workflow.md) §4).
311
+ - **Route params** (`@url1_`) go via the URL, not `IN`, using the backtick prefix: `"API": "/me/StudentDelete/\`{{vueData.selectedID}}"`
312
+ - **SP with multiple SELECTs** → `data[0]`, `data[1]`... — declare explicitly in `OUT` or split with `EXE`.
313
+ - **`convert_to_object = ''`** → flat object response: read `vueData.studentDetail.FullName`, not `vueData.studentDetail[0].FullName`.
@@ -1,14 +1,14 @@
1
- # module.json `data[]` — Khai báo state & value resolution (chuyên sâu)
1
+ # module.json `data[]` — State declaration & value resolution
2
2
 
3
- > File này sở hữu: **pattern khai báo `data[]`: ba loại phần tử, thứ tự state → named action → auto-startup**. Value resolution xem [controls-patterns.md](controls-patterns.md) §0; cú pháp key lồng nhau (dot/bracket/`#PARENT`) xem [controls-patterns.md](controls-patterns.md) §1; trao đổi cross-window xem [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
3
+ > Owns: **`data[]` declaration patterns: three element kinds, order state → named action → auto-startup**. Value resolution: [controls-patterns.md](controls-patterns.md) §0; nested key syntax (dot/bracket/`#PARENT`): [controls-patterns.md](controls-patterns.md) §1; cross-window: [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
4
4
 
5
- Cách FUI đọc `data[]`: xử lý **tuần tự từ trên xuống**, mỗi object gán/chạy dựa trên cách viết value. Ví dụ trong file này rút từ `ex/ex-v3-1SetData` + `ex-v3-2CauTruc` (module demo chính thức của FUI).
5
+ FUI processes `data[]` **sequentially top to bottom**; each object assigns/runs based on how its value is written. Examples come from `ex/ex-v3-1SetData` + `ex-v3-2CauTruc` (official FUI demo modules).
6
6
 
7
- > Quy tắc value resolution hình thức: [controls-patterns.md](controls-patterns.md) §0. Tổng quan 4 thành phần: [module-json-anatomy.md](module-json-anatomy.md). Engine nền tảng: [platform-architecture.md](platform-architecture.md) §5.
7
+ > Overview of the 4 blocks: [module-json-anatomy.md](module-json-anatomy.md). Engine: [platform-architecture.md](platform-architecture.md) §5.
8
8
 
9
9
  ---
10
10
 
11
- ## 1. Ba loại phần tử trong `data[]`
11
+ ## 1. Three element kinds in `data[]`
12
12
 
13
13
  ```json
14
14
  "data": [
@@ -19,53 +19,44 @@ Cách FUI đọc `data[]`: xử lý **tuần tự từ trên xuống**, mỗi ob
19
19
  ]
20
20
  ```
21
21
 
22
- - (a) không có key action → tạo biến reactive trong `vueData`.
23
- - (b) key là **tên hàm** → định nghĩa action tái sử dụng (gọi bằng `CALL`).
24
- - (c) object là chính một action (`API`/`CALL`/`FUN`…) → **chạy ngay khi trang load**, theo thứ tự.
22
+ - (a) no action key → creates reactive var in `vueData`.
23
+ - (b) key is a **function name** → reusable action (invoke via `CALL`).
24
+ - (c) object is itself an action (`API`/`CALL`/`FUN`…) → **runs on page load**, in order.
25
25
 
26
26
  ---
27
27
 
28
- ## 2. Value resolution — CÁCH VIẾT quyết định GIÁ TRỊ (điểm hay sai)
28
+ ## 2. Value resolution — HOW you write it decides the VALUE (common mistake)
29
29
 
30
- Bảng quy tắc đầy đủ (`getVueData`: backtick / `{{ }}` / chuỗi có dấu cách / chuỗi không dấu cách →
31
- JS eval) nằm ở [controls-patterns.md §0](controls-patterns.md#0-value-resolution-rules-fundamental)
32
- — file Tier A luôn được nạp sẵn, không chép lại ở đây.
30
+ Full rules (`getVueData`: backtick / `{{ }}` / string with spaces / string without spaces → JS eval) live in [controls-patterns.md §0](controls-patterns.md#0-value-resolution-rules-fundamental) — Tier A, always loaded; not repeated here.
33
31
 
34
- > **Hệ quả cho AI khi viết `data[]`:** muốn gán **chuỗi cố định không dấu cách** (id, url, mã) →
35
- > **bọc backtick** (`` "`winUser" ``) hoặc single-quote (`"'winUser'"`), nếu không FUI sẽ hiểu là
36
- > biến. Đây là lỗi phổ biến nhất khi viết `data`/`IN`.
32
+ > **Consequence for `data[]`:** to assign a **fixed string without spaces** (id, url, code) → **wrap in backticks** (``"`winUser"``) or single quotes (`"'winUser'"`), otherwise FUI treats it as a variable. This is the most common `data`/`IN` bug.
37
33
 
38
34
  ---
39
35
 
40
- ## 3. Key là đường dẫn lồng nhau (deep set)
36
+ ## 3. Keys as nested paths (deep set)
41
37
 
42
- Key bên trái cũng được phân giải (dot / bracket / index động / `#PARENT`) — bảng cú pháp đầy đủ nằm ở
43
- [controls-patterns.md §1](controls-patterns.md#1-khai-báo-và-gán-dữ-liệu-trong-data) *(Tier A, đã nạp sẵn)*,
44
- không chép lại ở đây.
38
+ The left-hand key is also resolved (dot / bracket / dynamic index / `#PARENT`) — full syntax in [controls-patterns.md §1](controls-patterns.md#1-data-keys-and-assignment) _(Tier A, already loaded)_.
45
39
 
46
40
  ---
47
41
 
48
- ## 4. Action tự chạy: inline `IN`/`OUT`/`API` khi load
42
+ ## 4. Auto-run action: inline `IN`/`OUT`/`API` on load
49
43
 
50
- Object là action đứng riêng trong `data[]` → chạy khi load. Không cần đặt tên:
44
+ A standalone action object in `data[]` runs on load; no name needed:
51
45
 
52
46
  ```json
53
47
  { "API": "https://tapi.example.vn/me/auth/ApplicationList", "OUT": "Mang" },
54
48
  { "IN": { "ABC": "`gdsgdsg", "DEF": "val5", "CBV": 1233 }, "OUT": "DoiTuong" }
55
49
  ```
56
50
 
57
- → dùng để nạp dữ liệu ban đầu của trang (danh mục, dropdown, dữ liệu bảng).
51
+ → loads the page's initial data (catalogs, dropdowns, table data).
58
52
 
59
53
  ---
60
54
 
61
- ## 5. Named action + CALLBACK (tái sử dụng)
55
+ ## 5. Named action + CALLBACK (reusable)
62
56
 
63
57
  ```json
64
58
  {
65
- "cmdSETData": [
66
- { "MESS": "Thông báo" },
67
- { "#Win1.GiaTriSetTuCHA": "Giá trị set từ CHA" }
68
- ],
59
+ "cmdSETData": [{ "MESS": "Thông báo" }, { "#Win1.GiaTriSetTuCHA": "Giá trị set từ CHA" }],
69
60
  "apiChart": {
70
61
  "API": "/ts/TS_Report_ForChart/{{ab}}",
71
62
  "IN": { "sachID": "apiLoadFBUser", "modeY": 12345 },
@@ -75,13 +66,13 @@ Object là action đứng riêng trong `data[]` → chạy khi load. Không cầ
75
66
  }
76
67
  ```
77
68
 
78
- Gọi bằng `{ "CALL": "cmdSETData" }` từ `controls`, `watch`, hay action khác. `CALLBACK` chạy sau khi API xong (xem [ui-patterns.md](ui-patterns.md) §7).
69
+ Invoke with `{ "CALL": "cmdSETData" }` from `controls`, `watch` or another action. `CALLBACK` runs after the API completes (see [ui-patterns.md](ui-patterns.md) §7).
79
70
 
80
71
  ---
81
72
 
82
- ## 6. `watch` với `v_old` — giá trị cũ
73
+ ## 6. `watch` with `v_old` — previous value
83
74
 
84
- Trong `watch`, `v_old.<field>` cho giá trị **trước khi đổi**:
75
+ In `watch`, `v_old.<field>` gives the value **before the change**:
85
76
 
86
77
  ```json
87
78
  "watch": {
@@ -95,13 +86,13 @@ Trong `watch`, `v_old.<field>` cho giá trị **trước khi đổi**:
95
86
  }
96
87
  ```
97
88
 
98
- Chi tiết `v_old`, `deep-watch`: [watcher-patterns.md](watcher-patterns.md).
89
+ `v_old`, `deep-watch` details: [watcher-patterns.md](watcher-patterns.md).
99
90
 
100
91
  ---
101
92
 
102
- ## 7. Trao đổi cross-window ngay trong `data[]`
93
+ ## 7. Cross-window exchange inside `data[]`
103
94
 
104
- `data[]` có thể đọc/ghi cửa sổ khác bằng key/value `#PARENT.*` / `#WinID.*` — đặt **trước** các CALL fetch:
95
+ `data[]` can read/write other windows via `#PARENT.*` / `#WinID.*` keys/values — place **before** fetch CALLs:
105
96
 
106
97
  ```json
107
98
  "data": [
@@ -113,14 +104,14 @@ Chi tiết `v_old`, `deep-watch`: [watcher-patterns.md](watcher-patterns.md).
113
104
  ]
114
105
  ```
115
106
 
116
- Đầy đủ: [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
107
+ Full: [ui-crosswindow-patterns.md](ui-crosswindow-patterns.md).
117
108
 
118
109
  ---
119
110
 
120
- ## 8. Checklist viết `data[]`
111
+ ## 8. `data[]` checklist
121
112
 
122
- 1. Khởi tạo **mọi** biến state ở object đầu (kể cả `[]`, `false`, `null`) — để reactive hoạt động.
123
- 2. Named action nhóm giữa; auto-startup (`CALL`/`API`) đặt **cuối**.
124
- 3. Gán chuỗi cố định không dấu cách → **backtick**; đừng để FUI hiểu nhầm là biến.
125
- 4. `#PARENT.*` / biến từ URL đặt trước các CALL fetch.
126
- 5. Không nhồi logic phức tạp vào `data` — tách sang `script.js` (hàm) hoặc `EXE` dè xẻn.
113
+ 1. Initialize **every** state var in the first object (including `[]`, `false`, `null`) so reactivity works.
114
+ 2. Named actions in the middle; auto-startup (`CALL`/`API`) **last**.
115
+ 3. Fixed space-free strings → **backticks**; never let FUI read them as variables.
116
+ 4. `#PARENT.*` / URL vars before fetch CALLs.
117
+ 5. No complex logic in `data` — move to `script.js` (functions) or sparing `EXE`.