@fui-org/fui-cli 0.2.0 → 0.3.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.
- package/README.md +13 -1
- package/dist/fui.js +160 -43
- package/package.json +4 -2
- package/skills/fui/SKILL.md +131 -66
- package/skills/fui-skill/README.md +112 -0
- package/skills/fui-skill/SKILL.md +269 -0
- package/skills/fui-skill/assets/projectdefaultstyle.css +518 -0
- package/skills/fui-skill/design-md/airbnb/DESIGN.md +545 -0
- package/skills/fui-skill/design-md/airbnb/README.md +5 -0
- package/skills/fui-skill/design-md/airtable/DESIGN.md +554 -0
- package/skills/fui-skill/design-md/airtable/README.md +5 -0
- package/skills/fui-skill/design-md/apple/DESIGN.md +562 -0
- package/skills/fui-skill/design-md/apple/README.md +5 -0
- package/skills/fui-skill/design-md/asu/DESIGN.md +179 -0
- package/skills/fui-skill/design-md/asu/README.md +107 -0
- package/skills/fui-skill/design-md/binance/DESIGN.md +634 -0
- package/skills/fui-skill/design-md/binance/README.md +5 -0
- package/skills/fui-skill/design-md/bmw/DESIGN.md +544 -0
- package/skills/fui-skill/design-md/bmw/README.md +5 -0
- package/skills/fui-skill/design-md/bmw-m/DESIGN.md +503 -0
- package/skills/fui-skill/design-md/bmw-m/README.md +5 -0
- package/skills/fui-skill/design-md/bugatti/DESIGN.md +454 -0
- package/skills/fui-skill/design-md/bugatti/README.md +5 -0
- package/skills/fui-skill/design-md/cal/DESIGN.md +542 -0
- package/skills/fui-skill/design-md/cal/README.md +5 -0
- package/skills/fui-skill/design-md/claude/DESIGN.md +589 -0
- package/skills/fui-skill/design-md/claude/README.md +5 -0
- package/skills/fui-skill/design-md/clay/DESIGN.md +541 -0
- package/skills/fui-skill/design-md/clay/README.md +5 -0
- package/skills/fui-skill/design-md/clickhouse/DESIGN.md +544 -0
- package/skills/fui-skill/design-md/clickhouse/README.md +5 -0
- package/skills/fui-skill/design-md/cohere/DESIGN.md +451 -0
- package/skills/fui-skill/design-md/cohere/README.md +5 -0
- package/skills/fui-skill/design-md/coinbase/DESIGN.md +570 -0
- package/skills/fui-skill/design-md/coinbase/README.md +5 -0
- package/skills/fui-skill/design-md/composio/DESIGN.md +506 -0
- package/skills/fui-skill/design-md/composio/README.md +5 -0
- package/skills/fui-skill/design-md/cursor/DESIGN.md +537 -0
- package/skills/fui-skill/design-md/cursor/README.md +5 -0
- package/skills/fui-skill/design-md/elevenlabs/DESIGN.md +504 -0
- package/skills/fui-skill/design-md/elevenlabs/README.md +5 -0
- package/skills/fui-skill/design-md/expo/DESIGN.md +526 -0
- package/skills/fui-skill/design-md/expo/README.md +5 -0
- package/skills/fui-skill/design-md/ferrari/DESIGN.md +531 -0
- package/skills/fui-skill/design-md/ferrari/README.md +5 -0
- package/skills/fui-skill/design-md/figma/DESIGN.md +578 -0
- package/skills/fui-skill/design-md/figma/README.md +5 -0
- package/skills/fui-skill/design-md/framer/DESIGN.md +544 -0
- package/skills/fui-skill/design-md/framer/README.md +5 -0
- package/skills/fui-skill/design-md/fui/DESIGN.md +532 -0
- package/skills/fui-skill/design-md/hashicorp/DESIGN.md +575 -0
- package/skills/fui-skill/design-md/hashicorp/README.md +5 -0
- package/skills/fui-skill/design-md/ibm/DESIGN.md +550 -0
- package/skills/fui-skill/design-md/ibm/README.md +5 -0
- package/skills/fui-skill/design-md/intercom/DESIGN.md +546 -0
- package/skills/fui-skill/design-md/intercom/README.md +5 -0
- package/skills/fui-skill/design-md/kraken/DESIGN.md +125 -0
- package/skills/fui-skill/design-md/kraken/README.md +5 -0
- package/skills/fui-skill/design-md/lamborghini/DESIGN.md +288 -0
- package/skills/fui-skill/design-md/lamborghini/README.md +5 -0
- package/skills/fui-skill/design-md/linear.app/DESIGN.md +548 -0
- package/skills/fui-skill/design-md/linear.app/README.md +5 -0
- package/skills/fui-skill/design-md/lovable/DESIGN.md +298 -0
- package/skills/fui-skill/design-md/lovable/README.md +5 -0
- package/skills/fui-skill/design-md/mastercard/DESIGN.md +365 -0
- package/skills/fui-skill/design-md/mastercard/README.md +5 -0
- package/skills/fui-skill/design-md/meta/DESIGN.md +683 -0
- package/skills/fui-skill/design-md/meta/README.md +5 -0
- package/skills/fui-skill/design-md/minimax/DESIGN.md +746 -0
- package/skills/fui-skill/design-md/minimax/README.md +5 -0
- package/skills/fui-skill/design-md/mintlify/DESIGN.md +852 -0
- package/skills/fui-skill/design-md/mintlify/README.md +5 -0
- package/skills/fui-skill/design-md/miro/DESIGN.md +825 -0
- package/skills/fui-skill/design-md/miro/README.md +5 -0
- package/skills/fui-skill/design-md/mistral.ai/DESIGN.md +773 -0
- package/skills/fui-skill/design-md/mistral.ai/README.md +5 -0
- package/skills/fui-skill/design-md/mongodb/DESIGN.md +767 -0
- package/skills/fui-skill/design-md/mongodb/README.md +5 -0
- package/skills/fui-skill/design-md/nike/DESIGN.md +575 -0
- package/skills/fui-skill/design-md/nike/README.md +5 -0
- package/skills/fui-skill/design-md/notion/DESIGN.md +821 -0
- package/skills/fui-skill/design-md/notion/README.md +5 -0
- package/skills/fui-skill/design-md/nvidia/DESIGN.md +640 -0
- package/skills/fui-skill/design-md/nvidia/README.md +5 -0
- package/skills/fui-skill/design-md/ollama/DESIGN.md +539 -0
- package/skills/fui-skill/design-md/ollama/README.md +5 -0
- package/skills/fui-skill/design-md/opencode.ai/DESIGN.md +521 -0
- package/skills/fui-skill/design-md/opencode.ai/README.md +5 -0
- package/skills/fui-skill/design-md/pinterest/DESIGN.md +597 -0
- package/skills/fui-skill/design-md/pinterest/README.md +5 -0
- package/skills/fui-skill/design-md/playstation/DESIGN.md +661 -0
- package/skills/fui-skill/design-md/playstation/README.md +5 -0
- package/skills/fui-skill/design-md/posthog/DESIGN.md +690 -0
- package/skills/fui-skill/design-md/posthog/README.md +5 -0
- package/skills/fui-skill/design-md/raycast/DESIGN.md +669 -0
- package/skills/fui-skill/design-md/raycast/README.md +5 -0
- package/skills/fui-skill/design-md/renault/DESIGN.md +589 -0
- package/skills/fui-skill/design-md/renault/README.md +5 -0
- package/skills/fui-skill/design-md/replicate/DESIGN.md +616 -0
- package/skills/fui-skill/design-md/replicate/README.md +5 -0
- package/skills/fui-skill/design-md/resend/DESIGN.md +585 -0
- package/skills/fui-skill/design-md/resend/README.md +5 -0
- package/skills/fui-skill/design-md/revolut/DESIGN.md +636 -0
- package/skills/fui-skill/design-md/revolut/README.md +5 -0
- package/skills/fui-skill/design-md/runwayml/DESIGN.md +244 -0
- package/skills/fui-skill/design-md/runwayml/README.md +5 -0
- package/skills/fui-skill/design-md/sanity/DESIGN.md +357 -0
- package/skills/fui-skill/design-md/sanity/README.md +5 -0
- package/skills/fui-skill/design-md/sentry/DESIGN.md +551 -0
- package/skills/fui-skill/design-md/sentry/README.md +5 -0
- package/skills/fui-skill/design-md/shopify/DESIGN.md +516 -0
- package/skills/fui-skill/design-md/shopify/README.md +5 -0
- package/skills/fui-skill/design-md/slack/DESIGN.md +482 -0
- package/skills/fui-skill/design-md/spacex/DESIGN.md +363 -0
- package/skills/fui-skill/design-md/spacex/README.md +5 -0
- package/skills/fui-skill/design-md/spotify/DESIGN.md +246 -0
- package/skills/fui-skill/design-md/spotify/README.md +5 -0
- package/skills/fui-skill/design-md/starbucks/DESIGN.md +580 -0
- package/skills/fui-skill/design-md/starbucks/README.md +5 -0
- package/skills/fui-skill/design-md/stripe/DESIGN.md +487 -0
- package/skills/fui-skill/design-md/stripe/README.md +5 -0
- package/skills/fui-skill/design-md/supabase/DESIGN.md +462 -0
- package/skills/fui-skill/design-md/supabase/README.md +5 -0
- package/skills/fui-skill/design-md/superhuman/DESIGN.md +448 -0
- package/skills/fui-skill/design-md/superhuman/README.md +5 -0
- package/skills/fui-skill/design-md/tesla/DESIGN.md +286 -0
- package/skills/fui-skill/design-md/tesla/README.md +5 -0
- package/skills/fui-skill/design-md/theverge/DESIGN.md +339 -0
- package/skills/fui-skill/design-md/theverge/README.md +5 -0
- package/skills/fui-skill/design-md/together.ai/DESIGN.md +633 -0
- package/skills/fui-skill/design-md/together.ai/README.md +5 -0
- package/skills/fui-skill/design-md/uber/DESIGN.md +636 -0
- package/skills/fui-skill/design-md/uber/README.md +5 -0
- package/skills/fui-skill/design-md/vercel/DESIGN.md +736 -0
- package/skills/fui-skill/design-md/vercel/README.md +5 -0
- package/skills/fui-skill/design-md/vodafone/DESIGN.md +538 -0
- package/skills/fui-skill/design-md/vodafone/README.md +5 -0
- package/skills/fui-skill/design-md/voltagent/DESIGN.md +521 -0
- package/skills/fui-skill/design-md/voltagent/README.md +5 -0
- package/skills/fui-skill/design-md/warp/DESIGN.md +526 -0
- package/skills/fui-skill/design-md/warp/README.md +5 -0
- package/skills/fui-skill/design-md/webflow/DESIGN.md +588 -0
- package/skills/fui-skill/design-md/webflow/README.md +5 -0
- package/skills/fui-skill/design-md/wired/DESIGN.md +497 -0
- package/skills/fui-skill/design-md/wired/README.md +5 -0
- package/skills/fui-skill/design-md/wise/DESIGN.md +544 -0
- package/skills/fui-skill/design-md/wise/README.md +5 -0
- package/skills/fui-skill/design-md/x.ai/DESIGN.md +465 -0
- package/skills/fui-skill/design-md/x.ai/README.md +5 -0
- package/skills/fui-skill/design-md/zapier/DESIGN.md +537 -0
- package/skills/fui-skill/design-md/zapier/README.md +5 -0
- package/skills/fui-skill/examples/component.vue +162 -0
- package/skills/fui-skill/examples/f-table-patterns.json +331 -0
- package/skills/fui-skill/examples/module-patterns.json +973 -0
- package/skills/fui-skill/examples/project-patterns.json +222 -0
- package/skills/fui-skill/metadata.json +75 -0
- package/skills/fui-skill/references/INDEX.md +144 -0
- package/skills/fui-skill/references/advanced-techniques.md +160 -0
- package/skills/fui-skill/references/coding-standards.md +112 -0
- package/skills/fui-skill/references/component-design.md +455 -0
- package/skills/fui-skill/references/component-quickref.md +77 -0
- package/skills/fui-skill/references/component-table.md +276 -0
- package/skills/fui-skill/references/components-dialog.md +192 -0
- package/skills/fui-skill/references/components-display.md +147 -0
- package/skills/fui-skill/references/components-echart.md +391 -0
- package/skills/fui-skill/references/components-input.md +359 -0
- package/skills/fui-skill/references/controls-patterns.md +847 -0
- package/skills/fui-skill/references/controls-styling-vocabulary.md +140 -0
- package/skills/fui-skill/references/db-table-design.md +77 -0
- package/skills/fui-skill/references/db-workflow.md +504 -0
- package/skills/fui-skill/references/default-function.md +415 -0
- package/skills/fui-skill/references/design-modes.md +85 -0
- package/skills/fui-skill/references/echart-templates.md +481 -0
- package/skills/fui-skill/references/fastproject.md +97 -0
- package/skills/fui-skill/references/fsheet.md +218 -0
- package/skills/fui-skill/references/fullstack-workflow.md +351 -0
- package/skills/fui-skill/references/module-data-patterns.md +126 -0
- package/skills/fui-skill/references/module-json-anatomy.md +137 -0
- package/skills/fui-skill/references/module-structure.md +260 -0
- package/skills/fui-skill/references/new-session.md +108 -0
- package/skills/fui-skill/references/pdfmake.md +60 -0
- package/skills/fui-skill/references/permission-system.md +169 -0
- package/skills/fui-skill/references/platform-architecture.md +294 -0
- package/skills/fui-skill/references/project-config.md +335 -0
- package/skills/fui-skill/references/project-provisioning.md +383 -0
- package/skills/fui-skill/references/script-map.md +296 -0
- package/skills/fui-skill/references/sql-clr-functions.md +224 -0
- package/skills/fui-skill/references/system-design.md +116 -0
- package/skills/fui-skill/references/tapi-file-api.md +191 -0
- package/skills/fui-skill/references/tapi-permission-patterns.md +158 -0
- package/skills/fui-skill/references/tapi-reference.md +549 -0
- package/skills/fui-skill/references/tools-registry.md +460 -0
- package/skills/fui-skill/references/ui-crosswindow-patterns.md +317 -0
- package/skills/fui-skill/references/ui-dialog-patterns.md +229 -0
- package/skills/fui-skill/references/ui-layout-patterns.md +176 -0
- package/skills/fui-skill/references/ui-patterns.md +315 -0
- package/skills/fui-skill/references/ui-screenshot-review.md +94 -0
- package/skills/fui-skill/references/ui-table-cell-patterns.md +316 -0
- package/skills/fui-skill/references/ui-templates.md +29 -0
- package/skills/fui-skill/references/verification.md +246 -0
- package/skills/fui-skill/references/watcher-patterns.md +196 -0
- package/skills/fui-skill/references/websocket-realtime.md +254 -0
- package/skills/fui-skill/scripts/component-3.0.js +2549 -0
- package/skills/fui-skill/scripts/component.js +3142 -0
- package/skills/fui-skill/scripts/componentTable-3.0.js +909 -0
- package/skills/fui-skill/scripts/componentTable.js +769 -0
- package/skills/fui-skill/scripts/defaultfunction-3.0.js +781 -0
- package/skills/fui-skill/scripts/defaultfunction.js +966 -0
- package/skills/fui-skill/scripts/fastproject-3.0.js +870 -0
- package/skills/fui-skill/scripts/fastproject.js +828 -0
- package/skills/fui-skill/scripts/fechart.js +890 -0
- package/skills/fui-skill/scripts/fsheet.js +1330 -0
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
{
|
|
2
|
+
"_comment": "Project Config Patterns Reference — Tổng hợp cấu trúc project.json và quan hệ với module.json set. Dùng làm tài liệu tham chiếu khi thiết kế hoặc cập nhật cấu hình project.",
|
|
3
|
+
"_patterns": {
|
|
4
|
+
"project_json_fields": [
|
|
5
|
+
"ProjectName — tên project hiển thị",
|
|
6
|
+
"title — tiêu đề mặc định cho các trang",
|
|
7
|
+
"apiDomain — base URL tAPI kèm apiName, ví dụ: https://tapi.example2.vn/ hoặc https://tapi.example.vn/acc/",
|
|
8
|
+
"login — URL trang đăng nhập",
|
|
9
|
+
"userInfo — endpoint lấy thông tin user đã đăng nhập",
|
|
10
|
+
"apiFile — endpoint upload file (tùy chọn)",
|
|
11
|
+
"menuStyle — màu sắc topmenu/leftmenu",
|
|
12
|
+
"menu — false (ẩn header) hoặc array (menu ngang trên header)",
|
|
13
|
+
"menuLeft — array menu sidebar trái",
|
|
14
|
+
"menuComponent — component tùy chỉnh nhúng vào vùng menu",
|
|
15
|
+
"domainSetting — override config theo từng domain (đa domain)"
|
|
16
|
+
],
|
|
17
|
+
"menu_item_fields": [
|
|
18
|
+
"name — tên hiển thị (bắt buộc)",
|
|
19
|
+
"url — đường dẫn module, bỏ qua nếu chỉ là nhóm cha",
|
|
20
|
+
"icon — Material Design icon (mdi-*)",
|
|
21
|
+
"submenu — mảng menu con (cùng cấu trúc)",
|
|
22
|
+
"right — điều kiện hiển thị; thiếu = hiển thị cho tất cả user đã đăng nhập"
|
|
23
|
+
],
|
|
24
|
+
"right_rules": [
|
|
25
|
+
"SystemRight: [1,2,3,9] — user.SystemRight phải nằm trong mảng này",
|
|
26
|
+
"FunctionRight: ['10','20'] — user.FunctionRight phải chứa ít nhất một code",
|
|
27
|
+
"Khi cả hai cùng có: user phải thỏa ĐồNG THỜI cả SystemRight VÀ FunctionRight",
|
|
28
|
+
"Không khai báo right — hiển thị cho tất cả user đã đăng nhập"
|
|
29
|
+
],
|
|
30
|
+
"set_override": [
|
|
31
|
+
"module.json set kế thừa project.json data làm mặc định",
|
|
32
|
+
"effective = { ...project.json data, ...module.json set } — module set được ưu tiên",
|
|
33
|
+
"Chỉ khai báo field cần override, không cần lặp lại toàn bộ project config",
|
|
34
|
+
"menu: false trong set — ẩn header menu chỉ cho trang đó",
|
|
35
|
+
"title: 'Tên trang' trong set — đổi tiêu đề riêng cho trang"
|
|
36
|
+
],
|
|
37
|
+
"domain_setting": [
|
|
38
|
+
"Key là hostname domain (ví dụ: sec.example.vn)",
|
|
39
|
+
"Runtime tự phát hiện domain hiện tại và áp dụng override tương ứng",
|
|
40
|
+
"Mỗi domain có thể có apiDomain, fileDomain, login, userInfo riêng"
|
|
41
|
+
]
|
|
42
|
+
},
|
|
43
|
+
|
|
44
|
+
"_note_structure": "project.json chứa một object 'data' duy nhất (khác với module.json có 4 section data/watch/controls/set)",
|
|
45
|
+
|
|
46
|
+
"data_single_domain": {
|
|
47
|
+
"_note": "Pattern 1 — Project một domain (phổ biến)",
|
|
48
|
+
"ProjectName": "Tên Project",
|
|
49
|
+
"title": "TIÊU ĐỀ HIỂN THỊ",
|
|
50
|
+
"apiDomain": "https://tapi.example.vn/acc/",
|
|
51
|
+
"login": "https://app.example.vn/",
|
|
52
|
+
"userInfo": "https://tapi.example.vn/acc/UserInfo/acc",
|
|
53
|
+
"apiFile": "https://file.example.vn/acc/upload/FileData",
|
|
54
|
+
"menuStyle": {
|
|
55
|
+
"_note": "Tùy chỉnh màu menu — bỏ qua nếu dùng màu mặc định",
|
|
56
|
+
"topmenu": {
|
|
57
|
+
"bgcolor": "#217D46",
|
|
58
|
+
"textcolor": "white"
|
|
59
|
+
},
|
|
60
|
+
"leftmenu": {
|
|
61
|
+
"bgcolor": "#217D46",
|
|
62
|
+
"textcolor": "white"
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
"menu": false,
|
|
66
|
+
"_note_menu_false": "menu: false = ẩn hoàn toàn header menu; thay bằng array nếu muốn menu ngang",
|
|
67
|
+
"menuLeft": [
|
|
68
|
+
{
|
|
69
|
+
"_note": "Item đơn — không có submenu",
|
|
70
|
+
"name": "Trang chủ",
|
|
71
|
+
"icon": "mdi-home",
|
|
72
|
+
"url": "/trang-chu"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"_note": "Item nhóm — có submenu, right cho cả nhóm",
|
|
76
|
+
"name": "Quản lý dữ liệu",
|
|
77
|
+
"icon": "mdi-database",
|
|
78
|
+
"right": {
|
|
79
|
+
"SystemRight": [1, 2, 3, 5, 9]
|
|
80
|
+
},
|
|
81
|
+
"submenu": [
|
|
82
|
+
{
|
|
83
|
+
"name": "Danh sách",
|
|
84
|
+
"url": "/danh-sach"
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"_note": "Submenu item có right riêng — phải thỏa right nhóm CHA trước",
|
|
88
|
+
"name": "Quản trị",
|
|
89
|
+
"url": "/quan-tri",
|
|
90
|
+
"right": {
|
|
91
|
+
"SystemRight": [3, 5, 9]
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
]
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
"_note": "Item yêu cầu cả SystemRight VÀ FunctionRight cùng lúc",
|
|
98
|
+
"name": "Cấp 1 - Giáo viên",
|
|
99
|
+
"icon": "mdi-human-male-board",
|
|
100
|
+
"right": {
|
|
101
|
+
"FunctionRight": ["10"],
|
|
102
|
+
"SystemRight": [1, 2, 5, 9]
|
|
103
|
+
},
|
|
104
|
+
"submenu": [
|
|
105
|
+
{ "name": "Danh sách học sinh", "url": "/ds-hoc-sinh?capid=1" },
|
|
106
|
+
{
|
|
107
|
+
"name": "Nhập điểm",
|
|
108
|
+
"url": "/nhap-diem?capid=1",
|
|
109
|
+
"right": { "SystemRight": [1, 2, 5, 9] }
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"_note": "URL ngoài — link tuyệt đối",
|
|
115
|
+
"name": "Hướng dẫn sử dụng",
|
|
116
|
+
"icon": "mdi-book",
|
|
117
|
+
"url": "https://docs.example.com/huong-dan"
|
|
118
|
+
},
|
|
119
|
+
{
|
|
120
|
+
"_note": "Item không có url, không có submenu — placeholder/disabled",
|
|
121
|
+
"name": "Hỗ trợ sự cố",
|
|
122
|
+
"icon": "mdi-help-circle-outline",
|
|
123
|
+
"url": "/support"
|
|
124
|
+
}
|
|
125
|
+
],
|
|
126
|
+
"menuComponent": [
|
|
127
|
+
{
|
|
128
|
+
"_note": "Component nhúng vào vùng menu — ví dụ: dropdown chọn niên khóa, chọn vai trò",
|
|
129
|
+
"el": "uc-nien-khoa"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"el": "uc-vaitro"
|
|
133
|
+
}
|
|
134
|
+
]
|
|
135
|
+
},
|
|
136
|
+
|
|
137
|
+
"data_multi_domain": {
|
|
138
|
+
"_note": "Pattern 2 — Project chạy trên nhiều domain, mỗi domain một DB/tAPI riêng",
|
|
139
|
+
"ProjectName": "Security Manager",
|
|
140
|
+
"title": "Quản lý phân quyền",
|
|
141
|
+
"login": "https://login.fui.vn",
|
|
142
|
+
"apiDomain": "https://api.fui.vn/fp/",
|
|
143
|
+
"userInfo": "https://api.fui.vn/fp/UserInfo/fp",
|
|
144
|
+
"_note_domain": "domainSetting override config khi user truy cập từ domain tương ứng",
|
|
145
|
+
"domainSetting": {
|
|
146
|
+
"sec.example3.vn": {
|
|
147
|
+
"login": "https://login.example3.vn",
|
|
148
|
+
"apiDomain": "https://api.example3.vn/acc/",
|
|
149
|
+
"fileDomain": "https://file.example3.vn/acc/",
|
|
150
|
+
"userInfo": "https://api.example3.vn/acc/UserInfo/acc"
|
|
151
|
+
},
|
|
152
|
+
"sec.example.vn": {
|
|
153
|
+
"login": "https://app.example.vn",
|
|
154
|
+
"apiDomain": "https://tapi.example.vn/acc/",
|
|
155
|
+
"fileDomain": "https://file.example.vn/acc/",
|
|
156
|
+
"userInfo": "https://tapi.example.vn/acc/UserInfo/acc"
|
|
157
|
+
},
|
|
158
|
+
"sec.example2.vn": {
|
|
159
|
+
"login": "https://login.example2.vn",
|
|
160
|
+
"apiDomain": "https://tapi.example2.vn/acc/",
|
|
161
|
+
"fileDomain": "https://file.example2.vn/acc/",
|
|
162
|
+
"userInfo": "https://tapi.example2.vn/acc/UserInfo/acc"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"menu": [
|
|
166
|
+
{
|
|
167
|
+
"_note": "menu (array) = header ngang — khác với menuLeft (sidebar)",
|
|
168
|
+
"name": "Users",
|
|
169
|
+
"right": { "SystemRight": [1, 2, 3, 9] },
|
|
170
|
+
"url": "/UserManager"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"name": "Permission",
|
|
174
|
+
"right": { "SystemRight": [2, 3, 9] },
|
|
175
|
+
"url": "/Permission"
|
|
176
|
+
},
|
|
177
|
+
{
|
|
178
|
+
"_note": "Menu ngang cũng có thể có submenu",
|
|
179
|
+
"name": "Rights",
|
|
180
|
+
"right": { "SystemRight": [2, 3, 9] },
|
|
181
|
+
"submenu": [
|
|
182
|
+
{ "name": "System Right", "url": "/SystemRight" },
|
|
183
|
+
{ "name": "Function Right", "url": "/FunctionRight" }
|
|
184
|
+
]
|
|
185
|
+
}
|
|
186
|
+
]
|
|
187
|
+
},
|
|
188
|
+
|
|
189
|
+
"module_set_examples": {
|
|
190
|
+
"_note": "Các ví dụ về module.json set — override project config cho từng trang riêng",
|
|
191
|
+
|
|
192
|
+
"set_hide_menu": {
|
|
193
|
+
"_note": "Trang ẩn header menu (ví dụ: trang nhúng, trang in, landing page)",
|
|
194
|
+
"set": {
|
|
195
|
+
"menu": false
|
|
196
|
+
}
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
"set_custom_title": {
|
|
200
|
+
"_note": "Trang có tiêu đề riêng",
|
|
201
|
+
"set": {
|
|
202
|
+
"title": "Nhập điểm Tiểu học - Cấp 1"
|
|
203
|
+
}
|
|
204
|
+
},
|
|
205
|
+
|
|
206
|
+
"set_no_menu_at_all": {
|
|
207
|
+
"_note": "Trang ẩn hoàn toàn cả header lẫn sidebar (module con mở qua openWindow)",
|
|
208
|
+
"set": {
|
|
209
|
+
"menu": false,
|
|
210
|
+
"menuLeft": []
|
|
211
|
+
}
|
|
212
|
+
},
|
|
213
|
+
|
|
214
|
+
"set_override_api": {
|
|
215
|
+
"_note": "Trang dùng apiDomain khác project (hiếm, nhưng có thể override)",
|
|
216
|
+
"set": {
|
|
217
|
+
"title": "Trang đặc biệt",
|
|
218
|
+
"apiDomain": "https://other-api.example.com/apiName/"
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "fui-skill",
|
|
3
|
+
"version": "1.5.0",
|
|
4
|
+
"description": "AI operating manual for FUI (Framework UI) low-code module development. Covers module.json authoring, action engine, UI layout system, component selection, tAPI SP design, MCP tool workflows, and publish safety protocols. Documentation-only manifest — the server reads SKILL.md + references/ directly, not this file.",
|
|
5
|
+
"authoring_rule": "Mỗi reference mở đầu bằng một dòng '> File này sở hữu: ...' khai báo phạm vi (canonical owner). Một sự thật chỉ được viết đầy đủ ở đúng một file; nơi khác chỉ để link + 1 câu tóm tắt. SKILL.md là văn bản chính sách (quy tắc cứng + cổng quyết định), KHÔNG dạy cách làm — mọi hướng dẫn nằm ở references/, tra qua references/INDEX.md.",
|
|
6
|
+
"activation_triggers": [
|
|
7
|
+
"module", "module.json", "fui", "f-table", "f-dialog", "f-echart",
|
|
8
|
+
"controls", "data", "watch", "CALL", "API", "CALLBACK", "OUT",
|
|
9
|
+
"menuChucNang", "ctrl-update", "hidden-container",
|
|
10
|
+
"spAPI_", "stored procedure", "tAPI",
|
|
11
|
+
"session_set", "module_get", "module_publish_html",
|
|
12
|
+
"websocket", "webSocket_Send", "webSocketJoinGroup", "signalr", "real-time",
|
|
13
|
+
"httpCall", "httpAPI", "sendMail", "SQL CLR", "ImageResize", "ImageCrop",
|
|
14
|
+
"FileReader", "FileWriter", "RegexMatch", "RegexReplace"
|
|
15
|
+
],
|
|
16
|
+
"context_loading": {
|
|
17
|
+
"router": "references/INDEX.md",
|
|
18
|
+
"tier1_always": [
|
|
19
|
+
"SKILL.md",
|
|
20
|
+
"references/controls-patterns.md",
|
|
21
|
+
"references/module-structure.md",
|
|
22
|
+
"references/INDEX.md"
|
|
23
|
+
],
|
|
24
|
+
"tier3_on_demand": {
|
|
25
|
+
"platform": "references/platform-architecture.md, references/module-json-anatomy.md, references/module-data-patterns.md",
|
|
26
|
+
"system_design": "references/system-design.md",
|
|
27
|
+
"design_system": "references/design-modes.md, references/controls-styling-vocabulary.md",
|
|
28
|
+
"ui_patterns": "references/ui-patterns.md, references/ui-table-cell-patterns.md, references/ui-dialog-patterns.md, references/ui-crosswindow-patterns.md, references/ui-layout-patterns.md",
|
|
29
|
+
"ui_review": "references/ui-screenshot-review.md",
|
|
30
|
+
"component_selection": "references/component-quickref.md, references/components-input.md, references/components-display.md, references/components-dialog.md, references/component-table.md",
|
|
31
|
+
"component_design": "references/component-design.md, references/coding-standards.md",
|
|
32
|
+
"charts": "references/components-echart.md, references/echart-templates.md",
|
|
33
|
+
"spreadsheet": "references/fsheet.md",
|
|
34
|
+
"tapi_sp": "references/tapi-reference.md, references/tapi-permission-patterns.md, references/tapi-file-api.md",
|
|
35
|
+
"permissions": "references/permission-system.md",
|
|
36
|
+
"database": "references/db-workflow.md, references/db-table-design.md",
|
|
37
|
+
"project_provisioning": "references/project-provisioning.md",
|
|
38
|
+
"fullstack": "references/fullstack-workflow.md",
|
|
39
|
+
"project_config": "references/project-config.md",
|
|
40
|
+
"pdf_generation": "references/pdfmake.md",
|
|
41
|
+
"advanced_scripting": "references/advanced-techniques.md, references/default-function.md, references/script-map.md, references/fastproject.md",
|
|
42
|
+
"watcher_patterns": "references/watcher-patterns.md",
|
|
43
|
+
"realtime_messaging": "references/websocket-realtime.md",
|
|
44
|
+
"sql_clr_functions": "references/sql-clr-functions.md",
|
|
45
|
+
"tool_safety": "references/tools-registry.md",
|
|
46
|
+
"new_session": "references/new-session.md",
|
|
47
|
+
"definition_of_done": "references/verification.md",
|
|
48
|
+
"templates": "references/ui-templates.md, examples/"
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
"tool_safety": {
|
|
52
|
+
"registry": "references/tools-registry.md",
|
|
53
|
+
"default_stance": "RequiresConfirm",
|
|
54
|
+
"destructive_tools": [
|
|
55
|
+
"module_publish_html",
|
|
56
|
+
"module_delete",
|
|
57
|
+
"db_sp_deploy",
|
|
58
|
+
"db_sp_delete",
|
|
59
|
+
"db_sql_execute_nonquery",
|
|
60
|
+
"file_import_delete",
|
|
61
|
+
"component_delete"
|
|
62
|
+
],
|
|
63
|
+
"mandatory_workflows": {
|
|
64
|
+
"module_publish_html": "module_preview → user approves → module_publish_html",
|
|
65
|
+
"module_delete": "show summary → explicit user confirmation → module_delete",
|
|
66
|
+
"db_sp_deploy": "show summary → explicit user confirmation → db_sp_deploy"
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
"verification": {
|
|
70
|
+
"checklist": "references/verification.md",
|
|
71
|
+
"gates": ["module_structure", "action_correctness", "sp_naming", "component_api", "publish_workflow"]
|
|
72
|
+
},
|
|
73
|
+
"maintainer": "FUI MCP Team",
|
|
74
|
+
"last_updated": "2026-07-29"
|
|
75
|
+
}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# FUI Skill — Reference Router (INDEX)
|
|
2
|
+
|
|
3
|
+
> File này sở hữu: **bảng định tuyến tình huống / component / từ khóa → file reference cần load**. Không chứa nội dung kỹ thuật — mọi quy tắc đều nằm ở file đích. *(Tier A — luôn nạp cùng `skill_get`.)*
|
|
4
|
+
|
|
5
|
+
**Bản đồ tra cứu: tình huống / component / từ khóa → file cần load.** Đây là file luôn được nạp cùng `skill_get`. Trước khi xử lý bất kỳ việc gì, tra bảng dưới để biết cần `skill_reference_get({ refs: [...] })` file nào — **đừng dựa vào trí nhớ, hãy load đúng file**.
|
|
6
|
+
|
|
7
|
+
> Cách dùng: `skill_reference_get({ refs: ["references/<tên-file>.md"] })`. Có thể load nhiều file một lần.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Luôn có sẵn (Tier A — đã nạp cùng skill_get)
|
|
12
|
+
|
|
13
|
+
| File | Nội dung |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `controls-patterns.md` | Action engine (**§QUY TẮC NỀN: một `{}` = một lệnh; nhiều lệnh tuần tự = mảng `[{…},{…}]`**), value resolution, key notation, layout grid — **nền tảng** |
|
|
16
|
+
| `module-structure.md` | Cấu trúc file module/project, layout rules |
|
|
17
|
+
| `INDEX.md` | (file này) — bản đồ router |
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Hiểu nền tảng / cấu tạo FUI (đọc sớm)
|
|
22
|
+
|
|
23
|
+
| Tình huống | Load file |
|
|
24
|
+
|---|---|
|
|
25
|
+
| Cấu tạo FUI, phân cấp Project→Module (import/component/set trộn thế nào), runtime, vueData/v_Set | `platform-architecture.md` |
|
|
26
|
+
| 4 thành phần module.json (data/watch/controls/set) — vai trò, cấu hình, tương tác | `module-json-anatomy.md` |
|
|
27
|
+
| **`HTMLOnly: true`** — server KHÔNG nhúng sẵn thư viện nào (Vue/Vuetify/jQuery/lodash/MDI/`projectdefaultstyle.css` đều vắng); cần gì phải tự khai trong chính module, và `script-map.md` KHÔNG áp dụng | `module-structure.md` §HTMLOnly=true: KHÔNG có thư viện nào được nhúng sẵn (Tier A, đã nạp sẵn) |
|
|
28
|
+
|
|
29
|
+
## Thiết kế UI / chọn component
|
|
30
|
+
|
|
31
|
+
| Tình huống | Load file |
|
|
32
|
+
|---|---|
|
|
33
|
+
| **Layout controls — class/prop/style ĐƯỢC DÙNG (đừng tự thêm style)** | `controls-styling-vocabulary.md` |
|
|
34
|
+
| Bắt đầu thiết kế UI, chọn component nào | `component-quickref.md` |
|
|
35
|
+
| Khai báo `data[]` — ba loại phần tử, thứ tự state → named action → auto-startup | `module-data-patterns.md` (value resolution + key lồng nhau: `controls-patterns.md` §0/§1, Tier A) |
|
|
36
|
+
| Pattern UI thực tế (data/watch/toolbar/filter/permission) | `ui-patterns.md` |
|
|
37
|
+
| **Hàng nhiều control / canh phải nhóm nút** — chuẩn `shrink` cho mọi cột trừ `v-spacer`; `w` px | `controls-patterns.md` (Tier A, đã nạp sẵn) |
|
|
38
|
+
| **f-table** — **hiển thị dữ liệu dạng datatable** (list/CRUD qua form dialog, cả readonly lẫn có `:update-api`) + điều khiển trong ô: t-check/t-button/t-select/t-menu, ctrl-update, show-select, chip-group | `ui-table-cell-patterns.md` |
|
|
39
|
+
| Bảng dữ liệu chuyên sâu (mọi props, header types, auto-headers khi bỏ `:headers`, **tổng cột `sum-format`** — object=hàng tổng trong bảng / string=dòng text dưới bảng, readonly table) | `component-table.md` |
|
|
40
|
+
| **f-sheet** — **nhập liệu trực tiếp trên bảng kiểu Excel** (sửa ô tại chỗ, dán từ Excel, không qua dialog) — component có sẵn (nền tảng AG Grid), KHÔNG tự viết bảng nhập liệu bằng `uc-*.vue`; import, props, columns, wiring API | `fsheet.md` |
|
|
41
|
+
| Dialog / form popup (hidden-container, mở dialog với row, checkbox-list) | `ui-dialog-patterns.md` |
|
|
42
|
+
| Mở sub-window & trao đổi dữ liệu (`openWindow`, `#PARENT`/`#Win`) | `ui-crosswindow-patterns.md` |
|
|
43
|
+
| Layout: page-container, master-detail, v-switch, date init, dynamic label | `ui-layout-patterns.md` |
|
|
44
|
+
| Input controls (f-date, f-time, f-search, f-radiobox, text-field...) | `components-input.md` |
|
|
45
|
+
| Display components (f-label, f-title, f-box, f-header, chip, badge...) | `components-display.md` |
|
|
46
|
+
| Dialog components (f-dialog, v-dialog chi tiết) | `components-dialog.md` |
|
|
47
|
+
| Custom Vue component (`uc-*.vue`) — scope, props/events, **ưu tiên class Vuetify có sẵn (cấm _injectStyle)**, dialog chuẩn hoá, tận dụng ajaxCALL/confirm/showMessage | `component-design.md` |
|
|
48
|
+
| **Kiểm chứng `uc-*.vue` trong không gian riêng** (`component_preview`) + luật push component cấp project trước khi render module | `component-design.md` |
|
|
49
|
+
| **Tra component project-scope đã có** trước khi tạo mới — quy ước `{projectId}/COMPONENTS.md` + vòng tích luỹ | `component-design.md` §1a |
|
|
50
|
+
| Template/ví dụ tham chiếu nhanh | `ui-templates.md` + `examples/` |
|
|
51
|
+
| **User gửi ảnh chụp màn hình giao diện** vào chat, hoặc đọc screenshot từ `renderUI` — đánh giá lỗi hiển thị, màu sắc, padding/margin, căn chỉnh, vị trí nút | `ui-screenshot-review.md` |
|
|
52
|
+
|
|
53
|
+
## Biểu đồ / báo cáo / dashboard
|
|
54
|
+
|
|
55
|
+
| Tình huống | Load file |
|
|
56
|
+
|---|---|
|
|
57
|
+
| Dùng f-echart (nền tảng Apache ECharts) — import, props, config, theme, DataView, `grid` padding, `boundaryGap`, lỗi | `components-echart.md` |
|
|
58
|
+
| Chọn/vẽ loại chart cụ thể + pattern module.json | `echart-templates.md` |
|
|
59
|
+
| Xuất PDF (f-pdfmake) | `pdfmake.md` |
|
|
60
|
+
|
|
61
|
+
## API / Stored Procedure / tAPI
|
|
62
|
+
|
|
63
|
+
| Tình huống | Load file |
|
|
64
|
+
|---|---|
|
|
65
|
+
| Đặt tên SP, params, URL, response format, error, wiring | `tapi-reference.md` |
|
|
66
|
+
| **API trả 200 nhưng dữ liệu rỗng/sai**, hoặc sắp đổi/xoá tham số của một SP đã có module gọi — ghép tham số tAPI khoan dung (thiếu → `NULL`, thừa → bỏ qua, **không bao giờ báo lỗi**) | `tapi-reference.md` §2 |
|
|
67
|
+
| **Đọc HTTP header trong SP** (`User-Agent`, `Cookie`, `X-Forwarded-For`, IP client, thiết bị/trình duyệt) — họ `@sys_header_*`, mỗi dấu `-` đổi thành `_` | `tapi-reference.md` §2 |
|
|
68
|
+
| Kiểm tra quyền trong SP (5 pattern, `@sys_SystemRight`, `getSystemRight`) | `tapi-permission-patterns.md` |
|
|
69
|
+
| Upload/download/xem file qua SP (`spAPIFILE_`, `fileContent`, `tblFileData`) | `tapi-file-api.md` |
|
|
70
|
+
| Hàm SQL CLR: httpCall, sendMail, ImageResize, FileReader, RegexMatch... | `sql-clr-functions.md` |
|
|
71
|
+
|
|
72
|
+
## Phân quyền người dùng
|
|
73
|
+
|
|
74
|
+
| Tình huống | Load file |
|
|
75
|
+
|---|---|
|
|
76
|
+
| Khái niệm `SystemRight` (cấp bậc) vs `FunctionRight` (quyền theo chức năng), `v-if`/menu `right`, và 8 tool quản lý định nghĩa quyền (`right_system_list/new/update/delete`, `right_function_list/new/update/delete`) | `permission-system.md` |
|
|
77
|
+
| **Sắp gác một control/menu/SP bằng mã quyền** — mã đó có tồn tại thật không, tạo thế nào | `permission-system.md` (§"mã quyền phải TỒN TẠI trước khi đem gác") |
|
|
78
|
+
| Kiểm tra quyền trong thân SP (5 pattern SQL) | `tapi-permission-patterns.md` |
|
|
79
|
+
|
|
80
|
+
## Database
|
|
81
|
+
|
|
82
|
+
| Tình huống | Load file |
|
|
83
|
+
|---|---|
|
|
84
|
+
| **Database CHƯA tồn tại** — tạo DB SQL Server mới, hai loại tài khoản SQL, đăng ký alias tAPI vào `acc` | `project-provisioning.md` |
|
|
85
|
+
| **Sắp chạy `CREATE DATABASE` / `CREATE LOGIN`** — kiểm quyền cấp máy chủ trước (`sysadmin`, hoặc `CREATE ANY DATABASE` + `ALTER ANY LOGIN`); thiếu quyền thì từ chối chứ đừng chạy thử | `project-provisioning.md` §Bước 0 |
|
|
86
|
+
| Kết nối DB, dbToken, schema, workflow SP | `db-workflow.md` |
|
|
87
|
+
| **Project gọi nhiều database** (module.json có `"API": "/{alias}/…"` với nhiều alias khác nhau) — mỗi alias một `db_connect`, tham số `db` chọn kết nối, tool trả MENU khi nhập nhằng | `db-workflow.md` (§1, §4) |
|
|
88
|
+
| **SSO xuyên domain** — userToken cùng domain cha dùng được ngay, không cần hỏi lại hay xác minh | `db-workflow.md` §6a |
|
|
89
|
+
| **Linked Server** — SP qua ranh giới linked server, quy ước đặt tên `spIO_IN_` / `spIO_OUT_` | `db-workflow.md` §8a |
|
|
90
|
+
| Quy tắc thiết kế bảng (đặt tên, PK/FK, cột audit) | `db-table-design.md` |
|
|
91
|
+
|
|
92
|
+
## Quy trình / thiết kế hệ thống
|
|
93
|
+
|
|
94
|
+
| Tình huống | Load file |
|
|
95
|
+
|---|---|
|
|
96
|
+
| **"Tạo dự án mới" / "tạo DB + project FUI mới"** — dựng hạ tầng từ số 0: CREATE DATABASE, tài khoản ứng dụng vs dev, alias `acc`, `project_new`, cấp quyền quản trị. Làm TRƯỚC `system-design.md` | `project-provisioning.md` |
|
|
97
|
+
| **Cấp/thu hồi quyền SỬA PROJECT trong IDE FUI** cho một lập trình viên (`UserRight`, 5 tool `project_user_*`) — khác hẳn quyền người dùng cuối ở `permission-system.md` | `project-provisioning.md` (§Bước 6) |
|
|
98
|
+
| **Thiết kế cả app nhiều module từ mô tả** (phân rã, schema-first, menu, quyền) | `system-design.md` |
|
|
99
|
+
| Tạo một module fullstack (UI + API) — quy trình 6 bước UI-first | `fullstack-workflow.md` |
|
|
100
|
+
| Cấu hình project.json: menu, điều hướng, phân quyền, domain | `project-config.md` |
|
|
101
|
+
|
|
102
|
+
## Scripting / kỹ thuật nâng cao
|
|
103
|
+
|
|
104
|
+
| Tình huống | Load file |
|
|
105
|
+
|---|---|
|
|
106
|
+
| **Cần chạy nhiều lệnh có thứ tự** (reset state → reload → báo toast) trong `CALLBACK`/`:action`/`watch`/`THEN` | `controls-patterns.md` §QUY TẮC NỀN (Tier A, đã nạp sẵn) |
|
|
107
|
+
| Watcher patterns (v_old, deep-watch, cascading) | `watcher-patterns.md` |
|
|
108
|
+
| Kỹ thuật nâng cao (EXE, MAP, expression phức tạp) | `advanced-techniques.md` |
|
|
109
|
+
| **Trang trắng / app rỗng dù 0 JS error, 0 Vue warn**, hoặc cần đặt logic phức tạp vào `:attr` `:option` `:config` | `advanced-techniques.md` §1 + chạy `module_validate` |
|
|
110
|
+
| **`… is not defined` lúc render**, hoặc một `EXE`/`FUN` "chạy xong mà không làm gì" | `advanced-techniques.md` §2 (hàm phải có thật trong `script.js` — nhớ `module_publish_script`). ⚠️ `module_validate` KHÔNG bắt được ca này, phải `module_simulate({renderUI:true})` |
|
|
111
|
+
| Hàm tiện ích FUI có sẵn (openWindow, ajaxCALL, jsonToExcel, groupBy...) | `default-function.md` |
|
|
112
|
+
| **Thư viện đã bundled sẵn** (jQuery, lodash, moment, numeral, toast, jquery-confirm) — biết trước khi định thêm CDN. ⚠️ Chỉ đúng với `HTMLOnly=false` | `script-map.md` §0 |
|
|
113
|
+
| Bản đồ script FUI (defaultfunction.js, component.js...) | `script-map.md` |
|
|
114
|
+
| FUI project bootstrapper (fastproject) | `fastproject.md` |
|
|
115
|
+
| Coding standards | `coding-standards.md` |
|
|
116
|
+
| Real-time / SignalR (webSocketJoinGroup, webSocket_Send) | `websocket-realtime.md` |
|
|
117
|
+
|
|
118
|
+
## Vận hành / publish / deploy
|
|
119
|
+
|
|
120
|
+
| Tình huống | Load file |
|
|
121
|
+
|---|---|
|
|
122
|
+
| **"new session" / "phiên mới" / "cửa sổ mới"** — mở thêm một phiên Claude Code CLI ở cửa sổ terminal riêng (lấy workspace root động, KHÔNG hard-code đường dẫn) | `new-session.md` |
|
|
123
|
+
| Mức độ an toàn của từng MCP tool (R/M, Safe/Confirm/Destructive), strict mode, `db_sp_verify`, error log | `tools-registry.md` |
|
|
124
|
+
| Checklist definition-of-done trước khi publish (kèm bước `module_validate` + `module_outline` + `module_simulate` + `db_sp_verify` tĩnh) | `verification.md` |
|
|
125
|
+
| **UI hỏng mà chưa biết vì sao — chọn tầng kiểm chứng nào cho rẻ nhất** (ma trận triệu chứng → tầng; đọc TRƯỚC khi chạy `renderUI`, và đọc lại khi đã render ≥2 lượt mà chưa khá hơn) | `verification.md` §Chọn tầng kiểm chứng |
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## Design system
|
|
130
|
+
|
|
131
|
+
**Hai chế độ tách bạch — xác định TRƯỚC khi viết controls. Chủ sở hữu: `design-modes.md`.**
|
|
132
|
+
|
|
133
|
+
| Chế độ | Khi nào | Nguồn thẩm mỹ |
|
|
134
|
+
|---|---|---|
|
|
135
|
+
| **App-mode** (mặc định) | Phần mềm quản lý: CRUD, form, danh sách, dashboard nội bộ | **DUY NHẤT** `design_read("fui")` + `controls-styling-vocabulary.md` — CẤM brand DESIGN.md, CẤM style tự chế |
|
|
136
|
+
| **Web-mode** | Landing page / trang giới thiệu / công khai (thường `HTMLOnly: true`) | `design_list` → `design_read("<brand>")` theo tone/ngành; CSS tự do trong header.html |
|
|
137
|
+
|
|
138
|
+
| Tình huống | Load file |
|
|
139
|
+
|---|---|
|
|
140
|
+
| Chọn App-mode hay Web-mode, giới hạn `border-radius`, vòng tích luỹ `{projectId}/DESIGN.md` | `design-modes.md` |
|
|
141
|
+
| Anatomy dialog/form/bảng màu chuẩn App-mode | tool `design_read("fui")` (không qua `skill_reference_get`) |
|
|
142
|
+
|
|
143
|
+
- `{projectId}/DESIGN.md` (nếu có) **ghi đè** quy tắc cùng chủ đề của chế độ đang dùng — kiểm tra trước khi thiết kế.
|
|
144
|
+
- User góp ý UI → ghi quy tắc vào `{projectId}/DESIGN.md` (vòng tích luỹ — `design-modes.md` §3).
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
# Advanced FUI Techniques
|
|
2
|
+
|
|
3
|
+
> File này sở hữu: **kỹ thuật nâng cao: `EXE`, `MAP`, expression phức tạp, luật expression thuần cho `:attr`, luật hàm gọi trong `EXE`/`FUN` phải tồn tại thật**. Action engine cơ bản xem [controls-patterns.md](controls-patterns.md).
|
|
4
|
+
|
|
5
|
+
This document captures advanced patterns and techniques for FUI development, extracted from real-world implementations.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 1. `:attr` CHỈ NHẬN EXPRESSION THUẦN — không bao giờ nhét statement
|
|
10
|
+
|
|
11
|
+
**Luật cứng.** Mọi giá trị binding trong `module.json` — `:option`, `:config`, `:items`, `:headers`, `:style`, và mọi `v-bind:*` — đi **thẳng vào template compiler của Vue**, nơi chỉ chấp nhận **một biểu thức**. Tuyệt đối không được chứa:
|
|
12
|
+
|
|
13
|
+
- `function(){ ... }` hay IIFE `(function(){...})()`
|
|
14
|
+
- `return`
|
|
15
|
+
- `var` / `let` / `const`
|
|
16
|
+
- dấu `;` nối nhiều câu lệnh
|
|
17
|
+
|
|
18
|
+
### Vì sao nghiêm trọng hơn vẻ ngoài của nó
|
|
19
|
+
|
|
20
|
+
Statement trong `:attr` làm **compile template hỏng**, và Vue **nuốt lỗi đó**: kết quả là **trang trắng với 0 JS error, 0 `[Vue warn]`**. Không có stack trace, không có dòng nào để lần — chỉ mò ra được sau nhiều vòng `module_simulate({renderUI:true})`. Đây là lý do nó là **error** trong `module_validate` chứ không phải warning.
|
|
21
|
+
|
|
22
|
+
> Khác hẳn `data[]` / `IN` / `{{ }}`: những chỗ đó đi qua `getVueData()` của FUI (xem [controls-patterns.md](controls-patterns.md) §0 Value Resolution) và có luật riêng. `:attr` **không** đi qua đó.
|
|
23
|
+
|
|
24
|
+
### Được phép trong `:attr`
|
|
25
|
+
|
|
26
|
+
| Dạng | Ví dụ |
|
|
27
|
+
|---|---|
|
|
28
|
+
| Object / array literal | `":config": "{ height: 300, legend: { show: true } }"` |
|
|
29
|
+
| Ternary | `":color": "ok ? 'primary' : 'warning'"` |
|
|
30
|
+
| Chuỗi arrow `.map` / `.filter` | `":items": "ds.filter(x => x.Active).map(x => x.Name)"` |
|
|
31
|
+
| Truy cập thuộc tính / biến vueData | `":option": "optThe"` |
|
|
32
|
+
|
|
33
|
+
### Logic phức tạp → chuyển sang `script.js` + `EXE`
|
|
34
|
+
|
|
35
|
+
Nhiều bước biến đổi, biến trung gian, vòng lặp, điều kiện phức tạp → **đừng đặt trong `:attr`**. Bốn bước:
|
|
36
|
+
|
|
37
|
+
1. Viết một hàm thường trong `script.js`: `function tenHam(){ ... }`
|
|
38
|
+
2. Hàm **gán thẳng vào `vueData.xxx`** (không `return` giá trị cho JSON đọc)
|
|
39
|
+
3. Gọi hàm qua `EXE` — thường trong `CALLBACK` của action nạp dữ liệu: `"EXE": "tenHam()"`
|
|
40
|
+
4. `:attr` trong `module.json` chỉ trỏ tới biến đó: `":option": "optThe"`
|
|
41
|
+
|
|
42
|
+
❌ **Sai** — IIFE trong `:attr`:
|
|
43
|
+
```json
|
|
44
|
+
":option": "(function(){ var src = vueData.ds.filter(r => r.id===1); return { series:[{data: src}] }; })();"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
✅ **Đúng**:
|
|
48
|
+
```javascript
|
|
49
|
+
// script.js
|
|
50
|
+
function buildChart() {
|
|
51
|
+
var src = vueData.ds.filter(function (r) { return r.id === 1; });
|
|
52
|
+
vueData.optThe = { series: [{ data: src }] };
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
```json
|
|
56
|
+
// module.json — action nạp dữ liệu
|
|
57
|
+
"CALLBACK": { "EXE": "buildChart()" },
|
|
58
|
+
// module.json — control
|
|
59
|
+
":option": "optThe"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`:option` khai báo trong `data[]` là `{}` để lần render đầu không vỡ; `buildChart()` gán bản thật sau khi API trả về.
|
|
63
|
+
|
|
64
|
+
### Chẩn đoán trang trắng khi "0 JS error, 0 Vue warn"
|
|
65
|
+
|
|
66
|
+
Triệu chứng đó **không phải lỗi runtime** — nghi **compile template trong `:attr`** trước tiên, đừng đi tìm trong `script.js` hay action engine.
|
|
67
|
+
|
|
68
|
+
Cách khoanh vùng nhanh: tạm thay biểu thức nghi ngờ bằng một giá trị tĩnh đơn giản (`":option": "{}"` hoặc bỏ hẳn attr đó) rồi render lại. **Trang hiện lại ⇒ chính biểu thức đó là thủ phạm.** Lặp lại cho từng `:attr` khả nghi cho tới khi khoanh đúng một cái.
|
|
69
|
+
|
|
70
|
+
Chạy `module_validate` trước khi render sẽ bắt được hầu hết các ca này ở dạng error, không cần mò.
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## 2. Hàm gọi trong `EXE` / `FUN` phải TỒN TẠI THẬT trong `script.js`
|
|
75
|
+
|
|
76
|
+
**Luật cứng.** `"EXE": "buildChart()"` và `"FUN": "buildChart"` chỉ chạy được nếu `buildChart` là một hàm **toàn cục có thật** lúc runtime — nghĩa là khai trong `{moduleDir}/script.js`, trong một file import `.js`, hoặc là hàm sẵn có của nền tảng ([default-function.md](default-function.md), [script-map.md](script-map.md)).
|
|
77
|
+
|
|
78
|
+
Đây là mặt kia của §1: §1 bảo *"logic phức tạp thì đẩy sang `script.js` rồi gọi qua `EXE`"* — và bước đẩy đó **rất hay bị quên nửa sau**. Module.json được sửa, `EXE` được viết, `module_publish_json` chạy xong; `script.js` thì không ai viết và `module_publish_script` không ai gọi.
|
|
79
|
+
|
|
80
|
+
### Vì sao không có gì báo cho bạn biết
|
|
81
|
+
|
|
82
|
+
Hai lệnh, hai kiểu hỏng, **cả hai đều không nói tên hàm ở chỗ dễ thấy**:
|
|
83
|
+
|
|
84
|
+
| Lệnh | Cơ chế | Biểu hiện khi hàm thiếu |
|
|
85
|
+
|---|---|---|
|
|
86
|
+
| `EXE` | Chạy qua `templateCompiled(\`<% … %>\`)` — tức lodash `_.template`. Do lỗi toán tử phẩy ở `fastproject-3.0.js:490`, **object dữ liệu không bao giờ được truyền vào**, nên định danh trần trong chuỗi EXE phân giải thẳng vào **global** | `ReferenceError: buildChart is not defined` — chỉ lộ ra ở `module_simulate({renderUI:true})`, và ở đó nó chỉ là **"1 JS error"** trong một report dài |
|
|
87
|
+
| `FUN` | `runFunction()` tra `window[obj.FUN]`, không thấy thì `console.log("Func:", …, "not found")` rồi **đi tiếp** | **Hỏng hoàn toàn im lặng.** Không error, không `[Vue warn]`, action vẫn "chạy xong" — chỉ là không làm gì cả |
|
|
88
|
+
|
|
89
|
+
Giá thật đã đo trong log: một module tốn **36 lượt `renderUI` liên tiếp trong 5 ngày** vì đúng lớp lỗi này (`buildKPI8Columns is not defined`).
|
|
90
|
+
|
|
91
|
+
### Tầng bắt được: **`module_simulate({ renderUI: true })`** — và chỉ tầng đó
|
|
92
|
+
|
|
93
|
+
`module_validate` **KHÔNG** kiểm việc này: nó không đọc `script.js`. (Đã từng có một luật tĩnh làm việc đó, đã gỡ — để không báo oan, luật phải biết trước **mọi** hàm toàn cục của nền tảng, và danh sách đó không bao giờ nuôi đủ; mỗi tên bỏ sót là một lần chặn publish một module chạy được.) `module_simulate` ở chế độ vm cũng không phải tầng bắt được — nó không nạp `script.js` vào sandbox nên báo ReferenceError cho **mọi** module dùng hàm `script.js`, kể cả module đúng.
|
|
94
|
+
|
|
95
|
+
Nên đường kiểm chứng là **renderUI**: trình duyệt thật ném `ReferenceError: buildChart is not defined`, và từ nay **mọi JS error đều làm tool trả `isError`** (không riêng lỗi lúc init — lỗi phát sinh khi bấm nút cũng tính). Câu lỗi nằm trong khối `═══ CHẨN ĐOÁN ═══` ở **đầu** report, dòng `[MODULE]`.
|
|
96
|
+
|
|
97
|
+
⚠️ **Vế `FUN` thì renderUI cũng không bắt được** — `runFunction` không thấy hàm thì `console.log` rồi đi tiếp, không ném gì cả. Với `FUN` phải **tự soát tên hàm** đối chiếu `script.js`; triệu chứng duy nhất là "action chạy xong mà không có gì xảy ra".
|
|
98
|
+
|
|
99
|
+
### Cách sửa
|
|
100
|
+
|
|
101
|
+
1. Viết hàm trong `script.js`: `function buildChart(){ … vueData.optThe = …; }`
|
|
102
|
+
2. **`module_publish_script`** — bước hay bị quên nhất. `module_publish_json` **không** đẩy `script.js`.
|
|
103
|
+
3. Gõ nhầm tên thì sửa tên, đừng thêm hàm rỗng cho hết lỗi.
|
|
104
|
+
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## 3. Advanced Logic & Scripting
|
|
108
|
+
|
|
109
|
+
FUI's JSON-based logic has limitations. Use `script.js` for complex operations.
|
|
110
|
+
|
|
111
|
+
### Computed Properties Workaround
|
|
112
|
+
FUI `module.json` does not natively support computed properties.
|
|
113
|
+
**Solution:** Define calculation functions in `script.js` and call them directly in `module.json`.
|
|
114
|
+
|
|
115
|
+
**script.js**:
|
|
116
|
+
```javascript
|
|
117
|
+
function getTongTien() {
|
|
118
|
+
return vueData.items.reduce((sum, item) => sum + (item.amount || 0), 0);
|
|
119
|
+
}
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
**module.json**:
|
|
123
|
+
```json
|
|
124
|
+
{
|
|
125
|
+
"innerHTML": "Total: {{getTongTien().toLocaleString()}} VNĐ"
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Complex Validation
|
|
130
|
+
Avoid writing long logic strings in JSON. Move validation logic to `script.js`.
|
|
131
|
+
|
|
132
|
+
**script.js**:
|
|
133
|
+
```javascript
|
|
134
|
+
function validateStep1() {
|
|
135
|
+
const d = vueData;
|
|
136
|
+
if (!d.name || !d.email) {
|
|
137
|
+
alert("Missing required fields!");
|
|
138
|
+
return false;
|
|
139
|
+
}
|
|
140
|
+
return true;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function nextStep() {
|
|
144
|
+
if (vueData.step === 1 && !validateStep1()) return;
|
|
145
|
+
vueData.step++;
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
**module.json**:
|
|
150
|
+
```json
|
|
151
|
+
"v-on:click": "nextStep()"
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
### Action Binding
|
|
155
|
+
You can bind direct JS functions to events instead of using the `CALL` action protocol if needed for simple UI logic.
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
"v-on:click": "prevBuoc()"
|
|
159
|
+
```
|
|
160
|
+
|