@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,318 +0,0 @@
1
- # FUI Table Cell Patterns — f-table & in-cell controls
2
-
3
- > Owns: **in-cell `f-table` controls (`t-*`), `ctrl-update`, show-select, chip-group, `t-button` vs `t-menu`**. Table props: [component-table.md](component-table.md).
4
-
5
- Patterns for `f-table` and in-cell controls (`t-check`, `t-button`, `t-select`, `t-menu`, `ctrl-update`, `show-select`, `v-chip-group`), from project **security-manager**.
6
-
7
- > See also: [ui-patterns.md](ui-patterns.md) (data/watch/toolbar), [ui-dialog-patterns.md](ui-dialog-patterns.md), [component-table.md](component-table.md).
8
-
9
- ---
10
-
11
- ## 1. Basic f-table with fixed header
12
-
13
- ```json
14
- {
15
- "el": "f-table",
16
- "attr": {
17
- "label": "User list",
18
- ":items-per-page": 50,
19
- ":height": -16,
20
- ":items": "dsUser",
21
- "item-key": "UserID",
22
- ":hide-default-footer": false,
23
- ":item-class": "item => item.ChuaKichHoat>0 ? 'danger' : ''",
24
- ":headers": [
25
- { "align": "center", "text": "UserID", "value": "UserID" },
26
- { "text": "Username", "value": "UserName" },
27
- { "text": "Fullname", "value": "FullName" }
28
- ]
29
- },
30
- "w": 12
31
- }
32
- ```
33
-
34
- - **Table height RULE (lint D9)**: the module's main data table declares `":height": -16` — f-table **measures its real position** after layout (`getBoundingClientRect().top`), fills to the screen bottom leaving 16px, and enables `fixed-header`. Data scrolls **inside the table** only, header stays put, no nested page scrollbars. Updates on window resize and when `items` changes.
35
-
36
- | `:height` | Behavior |
37
- | ----------- | ----------------------------------------------------------------------------------------------------- |
38
- | _(omitted)_ | Grows with row count — intentional short/lookup tables; wrong for the main table (whole page scrolls) |
39
- | `<= 0` | Fill to bottom leaving `abs(height)` px — **standard for main table** |
40
- | `> 0` | Fixed px — **table inside a dialog** (e.g. `":height": 360`) |
41
-
42
- Same three modes apply to `f-sheet` — see [fsheet.md](fsheet.md) §Height.
43
-
44
- ⚠ Old pattern `":height": "$( window ).height()-285"` is **deprecated** — it forces guessing total toolbar/filter/menu height; wrong guess = short or overflowing. It returns a **positive** number so it still works as fixed px (doesn't break) but loses auto-measure; lint D9 warns so you replace it with `-16`.
45
-
46
- - `:item-class`: conditional row highlight — `"item => item.Active==0 ? 'danger' : ''"`
47
-
48
- ---
49
-
50
- ## 2. t-check — toggle in cell
51
-
52
- In `headers`, renders a checkbox/icon toggle that fires an API on click.
53
-
54
- ```json
55
- {
56
- "text": "Active",
57
- "value": "Enable",
58
- "align": "center",
59
- "el": "t-check",
60
- "attr": {
61
- "on-icon": "mdi-check",
62
- "off-icon": "mdi-lock",
63
- ":action": [
64
- { "API": "/SM_Users_SetActive", "IN": { "UserID": "item.UserID" } },
65
- { "dsUser": [] },
66
- { "CALL": "getUser" }
67
- ]
68
- }
69
- }
70
- ```
71
-
72
- ---
73
-
74
- ## 3. t-button — button in cell
75
-
76
- Button/icon with an action in a cell; supports dynamic icons.
77
-
78
- ```json
79
- {
80
- "text": "Allow",
81
- "value": "Locked",
82
- "align": "center",
83
- "el": "t-button",
84
- "attr": {
85
- "color": "primary",
86
- ":outlined": false,
87
- ":icon-text": "`${ item.Locked==0 ? 'mdi-check-bold':'mdi-lock'}`",
88
- ":action": [
89
- { "API": "/SM_Computer_SetLocked", "IN": { "ComputerID": "item.ComputerID" } },
90
- { "dsComputer": [] },
91
- { "CALL": "getComputer" }
92
- ]
93
- }
94
- }
95
- ```
96
-
97
- ---
98
-
99
- ## 4. t-select — inline dropdown in cell
100
-
101
- Edit a field in the table; fires an API on selection.
102
-
103
- ```json
104
- {
105
- "text": "SystemRight",
106
- "value": "SysRight",
107
- "el": "t-select",
108
- "width": "250px",
109
- "attr": {
110
- "class": "flex-md-grow-0 my-2",
111
- ":items": "vueData.dsSystemRight",
112
- "item-text": "Note",
113
- "item-value": "SysRight",
114
- ":action": [
115
- {
116
- "CONFIRM": "Bạn có chắc cập nhật System Right cho user này không?",
117
- "API": "/SM_UserModule_UpdateSystemRight",
118
- "IN": {
119
- "ModuleID": "sModuleID",
120
- "UserID": "item.UserID",
121
- "SysRight": "item.SysRight"
122
- },
123
- "CALLBACK": { "MESS": "Cập nhật thành công." }
124
- }
125
- ]
126
- }
127
- }
128
- ```
129
-
130
- ---
131
-
132
- ## 5. t-menu — context menu in table (menuChucNang)
133
-
134
- Define menu items in `data[]`, reference via `t-menu` in headers.
135
-
136
- **Step 1 — `menuChucNang` in `data[]`:**
137
-
138
- ```json
139
- {
140
- "menuChucNang": [
141
- {
142
- "color": "primary",
143
- "icon-text": "mdi-account-details",
144
- "text": "Update Info",
145
- "action": [
146
- {
147
- "addNew": 0,
148
- "dongChon": "item",
149
- "sUserID": "item.UserID",
150
- "sUserName": "item.UserName",
151
- "sLastName": "item.LastName",
152
- "sFirstName": "item.FirstName"
153
- },
154
- { "dlUserInfo": true }
155
- ]
156
- },
157
- {
158
- "color": "primary",
159
- "icon-text": "mdi-shield-account-outline",
160
- "text": "User Permission",
161
- "action": [
162
- {
163
- "dongChon": "item",
164
- "sUserID": "item.UserID",
165
- "sFullName": "item.FullName"
166
- },
167
- {
168
- "FUN": "openWindow",
169
- "IN": {
170
- "id": "`WinPer",
171
- "title": "`User Permission",
172
- "url": "`/UserPermission"
173
- }
174
- }
175
- ]
176
- }
177
- ]
178
- }
179
- ```
180
-
181
- **Step 2 — `t-menu` in `headers`:**
182
-
183
- ```json
184
- {
185
- "el": "t-menu",
186
- "width": "120px",
187
- "align": "center",
188
- "text": "Update",
189
- "value": "Update",
190
- "attr": { ":items": "vueData.menuChucNang" }
191
- }
192
- ```
193
-
194
- - `"dongChon": "item"` — stores the current record in `dongChon`
195
- - `"sUserID": "item.UserID"` etc. — copy item fields into state
196
- - `{ "dlXxx": true }` — open the dialog after state is ready
197
-
198
- ---
199
-
200
- ## 6. ctrl-update CRUD
201
-
202
- CRUD directly in the table — no manual dialog.
203
-
204
- ```json
205
- {
206
- "el": "f-table",
207
- "attr": {
208
- ":items": "dsFunctionRight",
209
- "item-key": "FunctionID",
210
- ":headers": [
211
- { "text": "Code", "value": "FunctionCode" },
212
- { "text": "Name", "value": "FunctionName" },
213
- { "text": "Update", "value": "ctrl-update" }
214
- ],
215
- ":update-form": [
216
- {
217
- "el": "v-text-field",
218
- "w": 12,
219
- "attr": { "v-model": "FunctionCode", "label": "Function Code", ":required": true }
220
- },
221
- {
222
- "el": "v-text-field",
223
- "w": 12,
224
- "attr": { "v-model": "FunctionName", "label": "Function Name" }
225
- }
226
- ],
227
- ":update-api": {
228
- "new": {
229
- "API": "/SM_Function_Insert",
230
- "IN": { "ModuleID": "sModuleID", "FunctionCode": "item.FunctionCode", "FunctionName": "item.FunctionName" },
231
- "CALLBACK": { "CALL": "getFunctionRight" }
232
- },
233
- "edit": {
234
- "API": "/SM_Function_Update",
235
- "IN": {
236
- "FunctionID": "item.FunctionID",
237
- "FunctionCode": "item.FunctionCode",
238
- "FunctionName": "item.FunctionName"
239
- },
240
- "CALLBACK": { "CALL": "getFunctionRight" }
241
- },
242
- "delete": {
243
- "CONFIRM": "Bạn có chắc muốn xóa quyền này không?",
244
- "API": "/SM_Function_Delete",
245
- "IN": { "FunctionID": "item.FunctionID" },
246
- "CALLBACK": [{ "MESS": "Xóa thành công" }, { "CALL": "getFunctionRight" }]
247
- }
248
- }
249
- }
250
- }
251
- ```
252
-
253
- Use ctrl-update for simple edit forms (2–5 fields) with no complex layout.
254
-
255
- ---
256
-
257
- ## 7. f-table with show-select (multi-select)
258
-
259
- ```json
260
- {
261
- "el": "f-table",
262
- "attr": {
263
- ":show-select": true,
264
- "v-model": "sUserSelected",
265
- ":items": "dsUsers",
266
- "item-key": "UserID",
267
- ":items-per-page": -1,
268
- ":hide-default-footer": true,
269
- ":update-api": { "default-item": { "xAA": [] } },
270
- ":headers": [...]
271
- }
272
- }
273
- ```
274
-
275
- - `v-model`: array of selected items
276
- - `:update-api.default-item`: injects default fields into each item on load (here `xAA: []` for chip-group)
277
-
278
- ---
279
-
280
- ## 8. v-chip-group in cell
281
-
282
- Tag list in a cell; click opens a dialog.
283
-
284
- ```json
285
- {
286
- "text": "FunctionRight",
287
- "value": "FunctionName",
288
- "el": "v-chip-group",
289
- "attr": {
290
- "v-model": "item.xAA",
291
- "column": true,
292
- "v-if": "item.FunctionName"
293
- },
294
- "innerHTML": [
295
- {
296
- "el": "v-chip",
297
- "attr": {
298
- ":small": true,
299
- "color": "primary",
300
- "outlined": "",
301
- "v-for": "fn in item.FunctionName",
302
- ":key": "fn",
303
- "v-on:click": "vueData.dlFunction = true; CALL(setFunction(item, item.FunctionName));"
304
- },
305
- "innerHTML": "<div>{{fn.FunctionCode}}-{{fn.FunctionName}}</div>"
306
- }
307
- ]
308
- }
309
- ```
310
-
311
- ---
312
-
313
- ## `t-button` vs `t-menu`
314
-
315
- - **`t-button`**: the only action is viewing/loading related data → one direct click
316
- - **`t-menu`**: several actions **or** a state-changing action (Kích hoạt, Chốt điểm, Xóa...)
317
-
318
- > Don't wrap "Xem chi tiết" in `t-menu` — adds a wasted click; use `t-button`. See Master-Detail in [ui-layout-patterns.md](ui-layout-patterns.md).
@@ -1,22 +0,0 @@
1
- # UI Templates — `examples/`
2
-
3
- > Owns: **the 4 sample files in `examples/` and how to reuse them**. `controls`/action rules: [controls-patterns.md](controls-patterns.md); detailed f-table patterns: [component-table.md](component-table.md).
4
-
5
- `examples/` holds **real reference files**, not blank templates to copy whole. Read them for correct syntax/patterns, then rewrite for the actual business case.
6
-
7
- ## Files
8
-
9
- | File | Use when |
10
- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11
- | `component.vue` | Sample custom Vue component (`uc-*`) — standard `<template>` + `<script>`, no `name:`, no `components:{}`, no `<style>` |
12
- | `module-patterns.json` | **Full module reference** — data/watch/controls combined: menuChucNang, TypeLoad, addNew flag dialog, nested IF/THEN/ELSE, bulk action, openWindow+button+ctrlhotkey, `_.find`, pushRouter, inline f-menu, row-prop-object |
13
- | `f-table-patterns.json` | **In-depth f-table reference** — all props, every header type (`t-check`/`t-select`/`t-button`/`t-link`/`t-menu`/`v-chip-group`/`v-icon`/divider), full `ctrl-update`, f-table in a dialog, default-item-only |
14
- | `project-patterns.json` | **`project.json` reference** — full project config: menuLeft/menu/menuStyle/menuComponent/domainSetting, `right` by SystemRight+FunctionRight, relation to module.json `set` (per-page override of title/menu/apiDomain) |
15
-
16
- ## How to use
17
-
18
- 1. Identify the case → open the matching file above.
19
- 2. Take **only the pattern needed** (one action, one header, one dialog block) — never the whole file.
20
- 3. Replace APIs with real endpoints; rename fields/labels for the business case.
21
- 4. Merge into the module's existing `data` / `controls` / `watch`.
22
- 5. Run `fui module validate` then `fui module outline` before publishing.
@@ -1,236 +0,0 @@
1
- # FUI Definition-of-Done Checklists
2
-
3
- > Owns: **definition-of-done checklists before publish (module.json, `.vue`, SP, deploy)** and **symptom → verification tier matrix**. Flags: `fui <command> --help`.
4
-
5
- Each item is a gate: not ready while any required item is unchecked.
6
-
7
- ---
8
-
9
- ## Pick the tier by SYMPTOM (read before rendering)
10
-
11
- Tiers differ ~100× in cost per run:
12
-
13
- | Tier | Command | Cost | Sees |
14
- | ---- | ------------------------------ | -------------------- | --------------------------------------------------- |
15
- | 1 | `fui module validate` | instant, file-only | static rule/reference errors |
16
- | 2 | `fui module outline` | instant | layout, orphan actions, dialogs nobody opens |
17
- | 3 | `fui module simulate` | ~1 s | flow: action chain, watch, what OUT assigns |
18
- | 4 | `fui component preview` | browser, 1 component | bugs in one `uc-*.vue` |
19
- | 5 | `fui module simulate --render` | browser, ~10–30 s | **real visuals**: layout, height, style, responsive |
20
-
21
- `fui module check` = tiers 1–3 in one step.
22
-
23
- **Start at the cheapest tier that catches the symptom**, never tier 5 by default. Tier 5 alone sees visuals but can't say **why**.
24
-
25
- | Symptom | Cheapest tier | Why |
26
- | ----------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
27
- | Blank page, **no** JS error, **no** `[Vue warn]` | **1** | statement inside a `:attr` — Vue swallows template compile errors |
28
- | `[Vue warn] Property or method "x" is not defined` | **1** | variable not in `data[]` |
29
- | Button does nothing | **1** (CALL target) → **3** | |
30
- | `Unknown custom element: <f-…>` / empty component | **1** | wrong name or missing required import |
31
- | Chart draws nothing | **1** (missing `echarts.min.js`/`fechart.js`, most cases) → **5** (0-size canvas) | |
32
- | Misaligned columns, cramped row | **2** (Σw > 12) | |
33
- | Dialog won't open | **2** (`⚠ không thấy lệnh mở`) → **3** | |
34
- | Wrong action order · infinite watch loop · CONFIRM/MESS wrong branch | **3** | |
35
- | Wrong numbers · `undefined`/`NaN` on page | **3** | almost always `OUT`/mapData on the wrong key, not display |
36
- | API returns unexpected shape | `fui sp verify` (static, **calls no endpoint**) | infers from the real SP body + generates `--mocks` for tier 3. Only metadata reads: `OBJECT_DEFINITION` when no local `.sql`, `sys.database_permissions` with `--check-grant`; never runs the SP |
37
- | One `uc-*.vue` wrong | **4** | once proven, remaining bugs are assembly |
38
- | Horizontal overflow · wrong height · leaking style · bad spacing · broken on mobile | **5** | only tier seeing geometry |
39
- | Import/asset not loaded | **5**, section `⛔ MÔI TRƯỜNG THIẾU FILE` | environment error — **don't** edit the module for it |
40
- | Suspected "platform library bug" | **5**, check `⛔ ASSET CŨ` FIRST | stale asset ⇒ on-disk copy ran; CDN conclusions worthless |
41
- | **Permission-gated** button/menu hidden for real users but shown in preview | **1** after `fui right function list` | undefined code ⇒ `rightTest()` always false, no JS error. Tiers 3/5 **pre-grant** scanned codes so they always show — [permission-system.md](permission-system.md) |
42
-
43
- **Stale assets:** `--render` revalidates every asset per run (conditional GET; trace shows `N revalidate 304`). `⛔ ASSET CŨ, KHÔNG XÁC MINH ĐƯỢC` = network failed, on-disk copy ran ⇒ "library X has a bug" from that run is **unusable**; reconnect and re-render, or `--refresh-assets`. `ℹ️ ASSET PLATFORM ĐÃ ĐỔI` = platform file changed between runs — behavior changed without a `module.json` edit ⇒ look there first.
44
-
45
- **Read the `--render` report top-down:** `═══ CHẨN ĐOÁN ═══` groups failures by **where to fix** — `[MÔI TRƯỜNG]` (fix first; the others may be consequences) · `[MODULE]` (module.json/script.js/component) · `[HIỂN THỊ]` (DOM audit + image). `↪` = cheaper tier that should have caught it.
46
-
47
- **STOP re-rendering** when `Δ so với lượt trước` shows _no metric changed_: the fix missed the bug. Drop to tiers 1–3 to learn why, then return.
48
-
49
- ---
50
-
51
- ## Module Checklist
52
-
53
- ### Structure
54
-
55
- - [ ] `_moduleInfo.json` has `ModuleID`, `ModuleName`, `Framework`, `mTitle`, `HTMLOnly`
56
- - [ ] `module.json` is valid JSON (no trailing commas, no comments) — re-read after every long edit to catch a comma after the last array/object element
57
- - [ ] Custom components ⇒ `components/_components.json` lists all `uc-*.vue`
58
- - [ ] External JS/CSS ⇒ `imports/_imports.json` exists
59
-
60
- ### module.json — Data
61
-
62
- - [ ] All state declared in `data[]` before use in actions
63
- - [ ] Every named action reachable (`CALL`, `watch` or button click)
64
- - [ ] No hardcoded IDs — use `vueData.someVar`, not literal numbers
65
- - [ ] `OUT` keys match state names exactly (case-sensitive)
66
-
67
- ### module.json — Actions
68
-
69
- - [ ] Every `API` has `IN` and `OUT` (or `CALLBACK`)
70
- - [ ] Every delete has `CONFIRM` before `API`
71
- - [ ] Every mutation has a `CALLBACK` that reloads data or shows `MESS`
72
- - [ ] Literal strings in `IN`: backtick prefix or single quotes — ``"`winId"`` or `"'text'"`
73
- - [ ] `IF/THEN/ELSE` branches have matching action structures
74
- - [ ] No raw `EXE` duplicating logic expressible as actions
75
-
76
- ### module.json — Controls
77
-
78
- - [ ] `controls` starts with `{ "prop": "fluid grid-list-md", "rows": [...] }`
79
- - [ ] Every `cols` item has `w`
80
- - [ ] `v-on:click`, not `@click`
81
- - [ ] No `children` — nest with `innerHTML` array
82
- - [ ] Permission gates on `col: { "v-if": "vueData.user.SystemRight>=N" }` (not `attr`)
83
- - [ ] **Every gated `FunctionRight`/`SystemRight` code EXISTS** — ran `fui right function list`/`fui right system list` (also builds the cache `fui module validate` checks); missing ⇒ `fui right function new`/`fui right system new` FIRST. Invented codes hide controls silently while **preview still shows them** — [permission-system.md](permission-system.md)
84
- - [ ] `v-if` uses `vueData.` prefix for state
85
- - [ ] Dialogs use `el: "hidden-container"`, one per dialog
86
-
87
- ### module.json — Watch
88
-
89
- - [ ] Keys reference declared state
90
- - [ ] `deep-watch` for nested object/array
91
- - [ ] No watch calls an action that re-triggers itself (infinite loop)
92
-
93
- ### UI Quality
94
-
95
- - [ ] Vuetify classes/props before inline `style` (FUI V2 = Vuetify 1.5, FUI V3 = Vuetify 3)
96
- - [ ] `f-*` over raw `v-*` when an equivalent exists
97
- - [ ] Tables: `f-table`, not `v-data-table` — CRUD and read-only (read-only = no `:update-api`)
98
- - [ ] Totals via `sum-format` (object → total row; string → text line below) — never hand-built
99
- - [ ] Charts: **`f-echart`** only — not `v-chart`, `<canvas>`, other libs; follow **default display conventions** in components-echart.md
100
- - [ ] Date/time: `f-date`/`f-time`, not `v-text-field` + manual parsing
101
-
102
- ### Import JS/CSS
103
-
104
- - [ ] Each component needing imports (table in `component-quickref.md`): checked with `fui import list`
105
- - [ ] Missing ⇒ `fui import new` per file
106
- - [ ] Component removed ⇒ if its import is unused elsewhere, `fui import delete`
107
- - [ ] **`f-echart`**: both imports, in order:
108
- - `/include/chart/echarts.min.js`
109
- - `/include/chart/fechart.js`
110
-
111
- ### Validate before publish
112
-
113
- - [ ] New module with UI + API: UI built with hardcoded `data[]` + visual QA (`fui module simulate --render`) BEFORE the API contract and SPs — [fullstack-workflow.md](fullstack-workflow.md)
114
- - [ ] `fui module validate` after editing `module.json` — fix every **error** (missing CALL target, `@`/`#` shorthand, `children`, bad grid...)
115
- - [ ] Read each warning — may be intentional (unlisted component, optional param...), never skip unread
116
- - [ ] **`[design]`** warnings (colored dialog toolbar, red delete button, odd dialog width, no floating label, delete without CONFIRM, redundant Close button, hand-built v-snackbar/v-alert instead of MESS/MESSBOX, main f-table/f-sheet without `":height": -16` so the page scrolls instead of the table...) — **must fix** unless the user explicitly asked otherwise this session
117
- - [ ] Strict mode (`FUI_MCP_STRICT=1`): errors BLOCK publish
118
- - [ ] `fui module outline`, READ the tree: row Σw ≤12? `⚠ không thấy lệnh mở`? `⚠ không thấy nơi gọi`? `⚠ không thấy dùng`?
119
- - [ ] Complex runtime logic (action chain, watch cascade, dialog flow): `fui module simulate` with main-flow `--scenario` + `--mocks` (shape from `fui sp verify` snippet) + asserts — fix every `⚠` and ✘ first. Your `--mocks` always win; a static API with NO mock whose SP is confirmed read-only (`fui sp verify`/local `.sql`) is called for real (max 8 calls/run, cached in `_testdata/`) instead of `{data:[]}` — see the "Live/Cache data" line. SPs with writes are never called
120
- - [ ] **`--mocks` for existing SPs come from `fui sp verify`, never guessed** — on `🚨 CẤU TRÚC MOCK CHƯA ĐƯỢC KIỂM CHỨNG`, stop, run `fui sp verify`, copy the snippet verbatim (no hand edits). Invented shapes only for SPs not yet deployed
121
- - [ ] **Final visual QA (Playwright available)**: `fui module simulate --render --vue-data '{..demo data..}' --mocks '{...}'`. READ the screenshot (always inline; big PNG → JPEG) + DOM audit (empty app, overflow, "undefined"/"NaN", broken image, 0-size chart canvas) + JS errors/`[Vue warn]` + final vueData; fix and re-render until clean. **`⛔ MÔI TRƯỜNG THIẾU FILE` first**: environment error — run its suggested command (`fui project sync`/`fui module get`); errors below may be consequences, don't edit module.json for them. How to read screenshots: `ui-screenshot-review.md`. Chart/animation missing → raise `--settle-ms` (e.g. 1500). Open dialog captured as `render-dialog.jpg`. Mobile use → extra run `--device mobile`. No Playwright → skip (command returns install steps)
122
- - [ ] **Changed project level + module level** (project component/import, `project.json`/menu): publish **project level FIRST**, then render — `--render` loads `$projectData`, project components and project CSS from the server (`_aset`); module-level parts render locally (iterate freely, publish later). **Project components are hard-blocked** (no bypass flag) if a local `uc-*.vue` differs from the server bundle: `fui component preview` → `fui component new`/`update` → render. Blocked because server is newer (web IDE edit) → `fui project sync`, never push over
123
-
124
- ### Publish — only what changed
125
-
126
- - [ ] Only `module.json` → `fui module publish json` (no preview/approval)
127
- - [ ] `header.html` / `body.html` / title → `fui module preview` → user approves → `fui module publish html --approval <token>` (includes module.json)
128
- - [ ] `script.js` (even emptied) → `fui module publish script` — **⚠️ `publish html` does not clear an empty script on the server**
129
- - [ ] `uc-*.vue` → `fui component new` (first) / `fui component update` (later), per file — `update` hard-errors if absent on server, never creates
130
- - [ ] Several parts → one command each, in turn
131
-
132
- For `fui module publish html`: preview ran and diff reviewed · user explicitly confirmed · approval token in hand.
133
-
134
- ---
135
-
136
- ## Stored Procedure Checklist
137
-
138
- ### Naming
139
-
140
- - [ ] `spAPI_{Entity}{Action}`, Action = `List`/`Select`/`Insert`/`Update`/`Delete`/`Save` (e.g. `spAPI_ContractList`, `spAPI_ContractInsert`)
141
- - [ ] No spaces, no `sp_`/`SP_` prefix
142
-
143
- ### Parameters
144
-
145
- - [ ] `@sys_UserID int` in all writes (INSERT/UPDATE/DELETE)
146
- - [ ] `@sys_SystemRight int` when checking permission
147
- - [ ] Input params before system params; no unused params
148
-
149
- ### Security
150
-
151
- - [ ] Permission check at top: `IF @sys_SystemRight < N BEGIN RAISERROR(N'[Unauthorized]Bạn không có quyền...', 16, 1) RETURN END` — severity always `16`; `[Unauthorized]` prefix required so tAPI returns HTTP 401 ([tapi-reference.md](tapi-reference.md) §5)
152
- - [ ] No SQL string concatenation (parameterize)
153
- - [ ] `.sql` has **NO `GRANT EXECUTE`** — tAPI sends one batch, no `GO`, so a GRANT after `END` is **swallowed into the SP body** and runs on every call, silently. `fui sp deploy` grants new procedures and **re-queries `sys.database_permissions` to confirm**
154
- - [ ] `fui sp deploy` shows `✓ [public] đã có quyền EXECUTE`; on `❗` run exactly the printed GRANT (**don't redeploy**). `fui exec` deploys have no auto-grant (fui warns with the command). Later doubts: `fui sp verify <name> --check-grant`
155
-
156
- ### Logic
157
-
158
- - [ ] Returns exactly the columns `OUT` expects
159
- - [ ] Errors: `RAISERROR(N'...', 16, 1)` then `RETURN`, never silent
160
- - [ ] Transactions for multi-step writes
161
- - [ ] Reviewed statically (read body, reason about branches/edge cases) — never smoke-tested against the live endpoint
162
-
163
- ### Deploy
164
-
165
- - [ ] `fui sp save` first (local only)
166
- - [ ] Full body reviewed in the local file
167
- - [ ] Summary to user: SP name, CREATE/ALTER, affected tables
168
- - [ ] User explicitly confirmed before `fui sp deploy`
169
- - [ ] Any API (read or write) about to be wired into module.json → `fui sp verify` once: static shape/error contract + param check, **no endpoint call** (metadata reads only, as above)
170
- - [ ] **Write** APIs: verify by reading the body (`fui sp get`/`fui sp verify`) — WHERE, transaction, RAISERROR; test the UI flow with `fui module simulate --mocks '{...}'` (snippet from `fui sp verify`), never the real API
171
-
172
- ---
173
-
174
- ## Vue Component Checklist (`uc-*.vue`)
175
-
176
- ### File
177
-
178
- - [ ] Name starts with `uc-`; registered in `_components.json`
179
- - [ ] `<style scoped>`: every selector prefixed with the component's own class — `scoped` does NOT scope (server concatenates `ComCSS`), bare selectors leak. [component-design.md](component-design.md)
180
- - [ ] No backtick template strings in `<template>`
181
-
182
- ### API Design
183
-
184
- - [ ] Inputs are typed `props`; neutral names (`items`, `value`, `label`)
185
- - [ ] Emits events (`input`, `change`, `select`, `action`), never mutates parent state
186
- - [ ] Loading, empty, error states handled (prop or slot)
187
-
188
- ### Behavior
189
-
190
- - [ ] No data fetching unless explicitly data-owning
191
- - [ ] No hardcoded route/module paths
192
- - [ ] No permission logic — gating stays in `module.json`
193
-
194
- ### Verify in isolation (before assembling / pushing)
195
-
196
- - [ ] `fui component preview` with **≥2 cases**: normal + edge (empty list / very long string / missing field) — edge cases fail most
197
- - [ ] READ **desktop and mobile** screenshots (default): no overflow, no break at 390px, no "undefined"/"NaN"
198
- - [ ] No JS error / `[Vue warn]`
199
- - [ ] Interactive ⇒ `scenario` with `click`/`set` + `assert` passes (use `nth`, not `item`/`index`)
200
- - [ ] Self-sizing (chart, table) ⇒ also a low-height `viewport`
201
- - [ ] **Project-level component**: push (`fui component new`/`update`) RIGHT AFTER a clean preview — module `--render` hard-blocks on mismatch
202
-
203
- ---
204
-
205
- ## Import File Checklist
206
-
207
- - [ ] File type matches `ContentType` (`.js` → `application/javascript`, `.css` → `text/css`)
208
- - [ ] `sort` >= 40 for new imports (1–39 reserved)
209
- - [ ] Content tested locally before `fui import upload`
210
- - [ ] No tokens/passwords in JS/CSS
211
- - [ ] Updating ⇒ `fui import get` first
212
-
213
- ---
214
-
215
- ## Debug — errors after publish
216
-
217
- 1. **Re-read every file changed in that publish first**; don't jump elsewhere
218
- 2. Looks right ⇒ `fui module preview` for server vs local diff
219
- 3. Preview shows `Controls: 0` / `Data keys: 0` ⇒ server holds a broken old version — push again
220
- 4. Only when local is confirmed correct: check other files (header.html, script.js, imports)
221
-
222
- ---
223
-
224
- ## Quick Risk Gate
225
-
226
- Before any mutating command:
227
-
228
- | Question | If NO → |
229
- | ------------------------------------------ | ------------------------------ |
230
- | Read-only command? | Confirm intent with user |
231
- | Summary shown to user? | Show it, then wait |
232
- | 🔴 Destructive? | Require explicit confirmation |
233
- | `fui module publish html`: approval token? | Run `fui module preview` first |
234
- | `fui sp deploy`: user saw the SP body? | Show it, wait for OK |
235
-
236
- Per-command classification: [tools-registry.md](tools-registry.md).