@fui-org/fui-cli 2.1.3 → 2.2.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 (219) hide show
  1. package/README.md +27 -7
  2. package/dist/fui-qrb1j9jz.js +397 -0
  3. package/dist/fui.js +1 -1
  4. package/package.json +1 -1
  5. package/skills/fui/SKILL.md +143 -38
  6. package/skills/fui/agents/fui-builder.md +62 -0
  7. package/skills/fui/agents/fui-tester.md +77 -0
  8. package/skills/{fui-skill → fui}/assets/projectdefaultstyle.css +489 -489
  9. package/skills/{fui-skill → fui}/examples/component.vue +162 -162
  10. package/skills/{fui-skill → fui}/references/INDEX.md +5 -4
  11. package/skills/{fui-skill → fui}/references/advanced-techniques.md +170 -168
  12. package/skills/{fui-skill → fui}/references/component-design.md +2 -2
  13. package/skills/{fui-skill → fui}/references/component-quickref.md +78 -78
  14. package/skills/{fui-skill → fui}/references/component-table.md +287 -287
  15. package/skills/{fui-skill → fui}/references/components-dialog.md +191 -191
  16. package/skills/{fui-skill → fui}/references/components-display.md +141 -141
  17. package/skills/{fui-skill → fui}/references/components-echart.md +316 -316
  18. package/skills/{fui-skill → fui}/references/components-input.md +335 -335
  19. package/skills/{fui-skill → fui}/references/controls-patterns.md +2 -2
  20. package/skills/{fui-skill → fui}/references/controls-styling-vocabulary.md +173 -173
  21. package/skills/{fui-skill → fui}/references/db-workflow.md +9 -9
  22. package/skills/{fui-skill → fui}/references/default-function.md +456 -456
  23. package/skills/{fui-skill → fui}/references/design-modes.md +57 -57
  24. package/skills/{fui-skill → fui}/references/echart-templates.md +489 -489
  25. package/skills/{fui-skill → fui}/references/fastproject.md +99 -99
  26. package/skills/{fui-skill → fui}/references/fullstack-workflow.md +314 -313
  27. package/skills/{fui-skill → fui}/references/module-data-patterns.md +117 -117
  28. package/skills/{fui-skill → fui}/references/module-json-anatomy.md +132 -132
  29. package/skills/{fui-skill → fui}/references/module-structure.md +144 -144
  30. package/skills/{fui-skill → fui}/references/new-session.md +1 -2
  31. package/skills/{fui-skill → fui}/references/pdfmake.md +60 -60
  32. package/skills/{fui-skill → fui}/references/permission-system.md +1 -1
  33. package/skills/{fui-skill → fui}/references/platform-architecture.md +269 -269
  34. package/skills/{fui-skill → fui}/references/project-config.md +303 -303
  35. package/skills/{fui-skill → fui}/references/project-provisioning.md +4 -4
  36. package/skills/{fui-skill → fui}/references/script-map.md +262 -262
  37. package/skills/{fui-skill → fui}/references/sql-clr-functions.md +225 -225
  38. package/skills/{fui-skill → fui}/references/system-design.md +2 -2
  39. package/skills/{fui-skill → fui}/references/tapi-permission-patterns.md +156 -156
  40. package/skills/{fui-skill → fui}/references/tapi-reference.md +474 -474
  41. package/skills/fui/references/team-run.md +141 -0
  42. package/skills/fui/references/tools-registry.md +211 -0
  43. package/skills/{fui-skill → fui}/references/ui-crosswindow-patterns.md +321 -321
  44. package/skills/{fui-skill → fui}/references/ui-dialog-patterns.md +255 -255
  45. package/skills/{fui-skill → fui}/references/ui-layout-patterns.md +176 -176
  46. package/skills/{fui-skill → fui}/references/ui-patterns.md +303 -303
  47. package/skills/{fui-skill → fui}/references/ui-screenshot-review.md +95 -95
  48. package/skills/{fui-skill → fui}/references/ui-table-cell-patterns.md +318 -318
  49. package/skills/{fui-skill → fui}/references/verification.md +11 -11
  50. package/skills/{fui-skill → fui}/references/watcher-patterns.md +163 -163
  51. package/skills/{fui-skill → fui}/references/websocket-realtime.md +271 -271
  52. package/skills/{fui-skill → fui}/scripts/component-3.0.js +2715 -2715
  53. package/skills/{fui-skill → fui}/scripts/component.js +3147 -3147
  54. package/skills/{fui-skill → fui}/scripts/componentTable-3.0.js +1038 -1038
  55. package/skills/{fui-skill → fui}/scripts/componentTable.js +891 -891
  56. package/skills/{fui-skill → fui}/scripts/defaultfunction-3.0.js +866 -866
  57. package/skills/{fui-skill → fui}/scripts/defaultfunction.js +1051 -1051
  58. package/skills/{fui-skill → fui}/scripts/fastproject-3.0.js +870 -870
  59. package/skills/{fui-skill → fui}/scripts/fastproject.js +828 -828
  60. package/skills/fui-target/hooks/register.tsx +2 -0
  61. package/skills/fui-target/types/index.d.ts +1 -0
  62. package/dist/fui-hk5frcn2.js +0 -381
  63. package/skills/fui-skill/SKILL.md +0 -139
  64. package/skills/fui-skill/references/tools-registry.md +0 -84
  65. /package/skills/{fui-skill → fui}/assets/projectdefaultstyle-3.0.css +0 -0
  66. /package/skills/{fui-skill → fui}/design-md/airbnb/DESIGN.md +0 -0
  67. /package/skills/{fui-skill → fui}/design-md/airbnb/README.md +0 -0
  68. /package/skills/{fui-skill → fui}/design-md/airtable/DESIGN.md +0 -0
  69. /package/skills/{fui-skill → fui}/design-md/airtable/README.md +0 -0
  70. /package/skills/{fui-skill → fui}/design-md/apple/DESIGN.md +0 -0
  71. /package/skills/{fui-skill → fui}/design-md/apple/README.md +0 -0
  72. /package/skills/{fui-skill → fui}/design-md/asu/DESIGN.md +0 -0
  73. /package/skills/{fui-skill → fui}/design-md/asu/README.md +0 -0
  74. /package/skills/{fui-skill → fui}/design-md/binance/DESIGN.md +0 -0
  75. /package/skills/{fui-skill → fui}/design-md/binance/README.md +0 -0
  76. /package/skills/{fui-skill → fui}/design-md/bmw/DESIGN.md +0 -0
  77. /package/skills/{fui-skill → fui}/design-md/bmw/README.md +0 -0
  78. /package/skills/{fui-skill → fui}/design-md/bmw-m/DESIGN.md +0 -0
  79. /package/skills/{fui-skill → fui}/design-md/bmw-m/README.md +0 -0
  80. /package/skills/{fui-skill → fui}/design-md/bugatti/DESIGN.md +0 -0
  81. /package/skills/{fui-skill → fui}/design-md/bugatti/README.md +0 -0
  82. /package/skills/{fui-skill → fui}/design-md/cal/DESIGN.md +0 -0
  83. /package/skills/{fui-skill → fui}/design-md/cal/README.md +0 -0
  84. /package/skills/{fui-skill → fui}/design-md/claude/DESIGN.md +0 -0
  85. /package/skills/{fui-skill → fui}/design-md/claude/README.md +0 -0
  86. /package/skills/{fui-skill → fui}/design-md/clay/DESIGN.md +0 -0
  87. /package/skills/{fui-skill → fui}/design-md/clay/README.md +0 -0
  88. /package/skills/{fui-skill → fui}/design-md/clickhouse/DESIGN.md +0 -0
  89. /package/skills/{fui-skill → fui}/design-md/clickhouse/README.md +0 -0
  90. /package/skills/{fui-skill → fui}/design-md/cohere/DESIGN.md +0 -0
  91. /package/skills/{fui-skill → fui}/design-md/cohere/README.md +0 -0
  92. /package/skills/{fui-skill → fui}/design-md/coinbase/DESIGN.md +0 -0
  93. /package/skills/{fui-skill → fui}/design-md/coinbase/README.md +0 -0
  94. /package/skills/{fui-skill → fui}/design-md/composio/DESIGN.md +0 -0
  95. /package/skills/{fui-skill → fui}/design-md/composio/README.md +0 -0
  96. /package/skills/{fui-skill → fui}/design-md/cursor/DESIGN.md +0 -0
  97. /package/skills/{fui-skill → fui}/design-md/cursor/README.md +0 -0
  98. /package/skills/{fui-skill → fui}/design-md/elevenlabs/DESIGN.md +0 -0
  99. /package/skills/{fui-skill → fui}/design-md/elevenlabs/README.md +0 -0
  100. /package/skills/{fui-skill → fui}/design-md/expo/DESIGN.md +0 -0
  101. /package/skills/{fui-skill → fui}/design-md/expo/README.md +0 -0
  102. /package/skills/{fui-skill → fui}/design-md/ferrari/DESIGN.md +0 -0
  103. /package/skills/{fui-skill → fui}/design-md/ferrari/README.md +0 -0
  104. /package/skills/{fui-skill → fui}/design-md/figma/DESIGN.md +0 -0
  105. /package/skills/{fui-skill → fui}/design-md/figma/README.md +0 -0
  106. /package/skills/{fui-skill → fui}/design-md/framer/DESIGN.md +0 -0
  107. /package/skills/{fui-skill → fui}/design-md/framer/README.md +0 -0
  108. /package/skills/{fui-skill → fui}/design-md/fui/DESIGN.md +0 -0
  109. /package/skills/{fui-skill → fui}/design-md/hashicorp/DESIGN.md +0 -0
  110. /package/skills/{fui-skill → fui}/design-md/hashicorp/README.md +0 -0
  111. /package/skills/{fui-skill → fui}/design-md/ibm/DESIGN.md +0 -0
  112. /package/skills/{fui-skill → fui}/design-md/ibm/README.md +0 -0
  113. /package/skills/{fui-skill → fui}/design-md/intercom/DESIGN.md +0 -0
  114. /package/skills/{fui-skill → fui}/design-md/intercom/README.md +0 -0
  115. /package/skills/{fui-skill → fui}/design-md/kraken/DESIGN.md +0 -0
  116. /package/skills/{fui-skill → fui}/design-md/kraken/README.md +0 -0
  117. /package/skills/{fui-skill → fui}/design-md/lamborghini/DESIGN.md +0 -0
  118. /package/skills/{fui-skill → fui}/design-md/lamborghini/README.md +0 -0
  119. /package/skills/{fui-skill → fui}/design-md/linear.app/DESIGN.md +0 -0
  120. /package/skills/{fui-skill → fui}/design-md/linear.app/README.md +0 -0
  121. /package/skills/{fui-skill → fui}/design-md/lovable/DESIGN.md +0 -0
  122. /package/skills/{fui-skill → fui}/design-md/lovable/README.md +0 -0
  123. /package/skills/{fui-skill → fui}/design-md/mastercard/DESIGN.md +0 -0
  124. /package/skills/{fui-skill → fui}/design-md/mastercard/README.md +0 -0
  125. /package/skills/{fui-skill → fui}/design-md/meta/DESIGN.md +0 -0
  126. /package/skills/{fui-skill → fui}/design-md/meta/README.md +0 -0
  127. /package/skills/{fui-skill → fui}/design-md/minimax/DESIGN.md +0 -0
  128. /package/skills/{fui-skill → fui}/design-md/minimax/README.md +0 -0
  129. /package/skills/{fui-skill → fui}/design-md/mintlify/DESIGN.md +0 -0
  130. /package/skills/{fui-skill → fui}/design-md/mintlify/README.md +0 -0
  131. /package/skills/{fui-skill → fui}/design-md/miro/DESIGN.md +0 -0
  132. /package/skills/{fui-skill → fui}/design-md/miro/README.md +0 -0
  133. /package/skills/{fui-skill → fui}/design-md/mistral.ai/DESIGN.md +0 -0
  134. /package/skills/{fui-skill → fui}/design-md/mistral.ai/README.md +0 -0
  135. /package/skills/{fui-skill → fui}/design-md/mongodb/DESIGN.md +0 -0
  136. /package/skills/{fui-skill → fui}/design-md/mongodb/README.md +0 -0
  137. /package/skills/{fui-skill → fui}/design-md/nike/DESIGN.md +0 -0
  138. /package/skills/{fui-skill → fui}/design-md/nike/README.md +0 -0
  139. /package/skills/{fui-skill → fui}/design-md/notion/DESIGN.md +0 -0
  140. /package/skills/{fui-skill → fui}/design-md/notion/README.md +0 -0
  141. /package/skills/{fui-skill → fui}/design-md/nvidia/DESIGN.md +0 -0
  142. /package/skills/{fui-skill → fui}/design-md/nvidia/README.md +0 -0
  143. /package/skills/{fui-skill → fui}/design-md/ollama/DESIGN.md +0 -0
  144. /package/skills/{fui-skill → fui}/design-md/ollama/README.md +0 -0
  145. /package/skills/{fui-skill → fui}/design-md/opencode.ai/DESIGN.md +0 -0
  146. /package/skills/{fui-skill → fui}/design-md/opencode.ai/README.md +0 -0
  147. /package/skills/{fui-skill → fui}/design-md/pinterest/DESIGN.md +0 -0
  148. /package/skills/{fui-skill → fui}/design-md/pinterest/README.md +0 -0
  149. /package/skills/{fui-skill → fui}/design-md/playstation/DESIGN.md +0 -0
  150. /package/skills/{fui-skill → fui}/design-md/playstation/README.md +0 -0
  151. /package/skills/{fui-skill → fui}/design-md/posthog/DESIGN.md +0 -0
  152. /package/skills/{fui-skill → fui}/design-md/posthog/README.md +0 -0
  153. /package/skills/{fui-skill → fui}/design-md/raycast/DESIGN.md +0 -0
  154. /package/skills/{fui-skill → fui}/design-md/raycast/README.md +0 -0
  155. /package/skills/{fui-skill → fui}/design-md/renault/DESIGN.md +0 -0
  156. /package/skills/{fui-skill → fui}/design-md/renault/README.md +0 -0
  157. /package/skills/{fui-skill → fui}/design-md/replicate/DESIGN.md +0 -0
  158. /package/skills/{fui-skill → fui}/design-md/replicate/README.md +0 -0
  159. /package/skills/{fui-skill → fui}/design-md/resend/DESIGN.md +0 -0
  160. /package/skills/{fui-skill → fui}/design-md/resend/README.md +0 -0
  161. /package/skills/{fui-skill → fui}/design-md/revolut/DESIGN.md +0 -0
  162. /package/skills/{fui-skill → fui}/design-md/revolut/README.md +0 -0
  163. /package/skills/{fui-skill → fui}/design-md/runwayml/DESIGN.md +0 -0
  164. /package/skills/{fui-skill → fui}/design-md/runwayml/README.md +0 -0
  165. /package/skills/{fui-skill → fui}/design-md/sanity/DESIGN.md +0 -0
  166. /package/skills/{fui-skill → fui}/design-md/sanity/README.md +0 -0
  167. /package/skills/{fui-skill → fui}/design-md/sentry/DESIGN.md +0 -0
  168. /package/skills/{fui-skill → fui}/design-md/sentry/README.md +0 -0
  169. /package/skills/{fui-skill → fui}/design-md/shopify/DESIGN.md +0 -0
  170. /package/skills/{fui-skill → fui}/design-md/shopify/README.md +0 -0
  171. /package/skills/{fui-skill → fui}/design-md/slack/DESIGN.md +0 -0
  172. /package/skills/{fui-skill → fui}/design-md/spacex/DESIGN.md +0 -0
  173. /package/skills/{fui-skill → fui}/design-md/spacex/README.md +0 -0
  174. /package/skills/{fui-skill → fui}/design-md/spotify/DESIGN.md +0 -0
  175. /package/skills/{fui-skill → fui}/design-md/spotify/README.md +0 -0
  176. /package/skills/{fui-skill → fui}/design-md/starbucks/DESIGN.md +0 -0
  177. /package/skills/{fui-skill → fui}/design-md/starbucks/README.md +0 -0
  178. /package/skills/{fui-skill → fui}/design-md/stripe/DESIGN.md +0 -0
  179. /package/skills/{fui-skill → fui}/design-md/stripe/README.md +0 -0
  180. /package/skills/{fui-skill → fui}/design-md/supabase/DESIGN.md +0 -0
  181. /package/skills/{fui-skill → fui}/design-md/supabase/README.md +0 -0
  182. /package/skills/{fui-skill → fui}/design-md/superhuman/DESIGN.md +0 -0
  183. /package/skills/{fui-skill → fui}/design-md/superhuman/README.md +0 -0
  184. /package/skills/{fui-skill → fui}/design-md/tesla/DESIGN.md +0 -0
  185. /package/skills/{fui-skill → fui}/design-md/tesla/README.md +0 -0
  186. /package/skills/{fui-skill → fui}/design-md/theverge/DESIGN.md +0 -0
  187. /package/skills/{fui-skill → fui}/design-md/theverge/README.md +0 -0
  188. /package/skills/{fui-skill → fui}/design-md/together.ai/DESIGN.md +0 -0
  189. /package/skills/{fui-skill → fui}/design-md/together.ai/README.md +0 -0
  190. /package/skills/{fui-skill → fui}/design-md/uber/DESIGN.md +0 -0
  191. /package/skills/{fui-skill → fui}/design-md/uber/README.md +0 -0
  192. /package/skills/{fui-skill → fui}/design-md/vercel/DESIGN.md +0 -0
  193. /package/skills/{fui-skill → fui}/design-md/vercel/README.md +0 -0
  194. /package/skills/{fui-skill → fui}/design-md/vodafone/DESIGN.md +0 -0
  195. /package/skills/{fui-skill → fui}/design-md/vodafone/README.md +0 -0
  196. /package/skills/{fui-skill → fui}/design-md/voltagent/DESIGN.md +0 -0
  197. /package/skills/{fui-skill → fui}/design-md/voltagent/README.md +0 -0
  198. /package/skills/{fui-skill → fui}/design-md/warp/DESIGN.md +0 -0
  199. /package/skills/{fui-skill → fui}/design-md/warp/README.md +0 -0
  200. /package/skills/{fui-skill → fui}/design-md/webflow/DESIGN.md +0 -0
  201. /package/skills/{fui-skill → fui}/design-md/webflow/README.md +0 -0
  202. /package/skills/{fui-skill → fui}/design-md/wired/DESIGN.md +0 -0
  203. /package/skills/{fui-skill → fui}/design-md/wired/README.md +0 -0
  204. /package/skills/{fui-skill → fui}/design-md/wise/DESIGN.md +0 -0
  205. /package/skills/{fui-skill → fui}/design-md/wise/README.md +0 -0
  206. /package/skills/{fui-skill → fui}/design-md/x.ai/DESIGN.md +0 -0
  207. /package/skills/{fui-skill → fui}/design-md/x.ai/README.md +0 -0
  208. /package/skills/{fui-skill → fui}/design-md/zapier/DESIGN.md +0 -0
  209. /package/skills/{fui-skill → fui}/design-md/zapier/README.md +0 -0
  210. /package/skills/{fui-skill → fui}/examples/f-table-patterns.json +0 -0
  211. /package/skills/{fui-skill → fui}/examples/module-patterns.json +0 -0
  212. /package/skills/{fui-skill → fui}/examples/project-patterns.json +0 -0
  213. /package/skills/{fui-skill → fui}/references/coding-standards.md +0 -0
  214. /package/skills/{fui-skill → fui}/references/db-table-design.md +0 -0
  215. /package/skills/{fui-skill → fui}/references/fsheet.md +0 -0
  216. /package/skills/{fui-skill → fui}/references/tapi-file-api.md +0 -0
  217. /package/skills/{fui-skill → fui}/references/ui-templates.md +0 -0
  218. /package/skills/{fui-skill → fui}/scripts/fechart.js +0 -0
  219. /package/skills/{fui-skill → fui}/scripts/fsheet.js +0 -0
@@ -1,156 +1,156 @@
1
- # tAPI — Permission Check Patterns
2
-
3
- > Owns: **5 permission-check patterns in SP bodies (`@sys_SystemRight`, `getSystemRight`, RAISERROR)**. Load when an SP needs authorization. SP basics (naming, params, response, RAISERROR): [tapi-reference.md](tapi-reference.md). `SystemRight`/`FunctionRight` concepts, `tblSysRight`/`tblFunction`, right-definition commands: [permission-system.md](permission-system.md).
4
-
5
- ---
6
-
7
- ## Permission-related system params
8
-
9
- Injected by tAPI — the client never sends them:
10
-
11
- | Param | Type | Meaning |
12
- | -------------------- | ------------- | ------------------------------------- |
13
- | `@sys_UserID` | varchar(9) | Logged-in user ID |
14
- | `@sys_SystemRight` | int | User's level on the current module |
15
- | `@sys_FunctionRight` | varchar(2000) | Function rights like `[AD][RPT][MGR]` |
16
-
17
- **Declare** at the end of the param list. **No default on any param, including `@sys_*`** ([tapi-reference.md](tapi-reference.md) §2 — tAPI always passes every param, `NULL` when missing, so `DEFAULT` is never used; `fui sp deploy` hard-blocks it):
18
-
19
- ```sql
20
- CREATE PROCEDURE spAPI_EntityAction
21
- @BusinessParam1 int,
22
- @BusinessParam2 nvarchar(100),
23
- @sys_UserID varchar(9),
24
- @sys_SystemRight int
25
- AS
26
- ```
27
-
28
- ## `@sys_SystemRight` levels
29
-
30
- Meaning is **defined per project** (`tblSysRight.Note`, managed via `fui right system list`/`update` — [permission-system.md](permission-system.md)). Common convention for SP checks — not platform-fixed, except `9` is always Project Admin:
31
-
32
- | Value | Common meaning |
33
- | ----- | -------------------------------------------------- |
34
- | `0` | No right / not granted on the module |
35
- | `1` | Basic view |
36
- | `2` | Standard operations (read, add, normal edit) |
37
- | `3` | Advanced (internal management, sensitive ops) |
38
- | `9` | Module Admin / Project Admin (fixed platform-wide) |
39
-
40
- ## Helper: rights on a specific module
41
-
42
- ```sql
43
- dbo.getSystemRight(@ModuleID, @sys_UserID)
44
- ```
45
-
46
- Returns the user's `SysRight` on a given module — use to check rights on a module **other than** the current one.
47
-
48
- ---
49
-
50
- ## Pattern 1 — Basic access block (READ)
51
-
52
- Every read SP that needs login. Requires `SysRight >= 2`.
53
-
54
- ```sql
55
- If @sys_SystemRight < 2
56
- Begin
57
- Raiserror(N'[Unauthorized]Bạn không có quyền trên chức năng này.', 16, 1)
58
- Return
59
- End
60
- ```
61
-
62
- ## Pattern 2 — Block only users with no right (minimal)
63
-
64
- Allows `SysRight = 1`; blocks only `SysRight = 0`.
65
-
66
- ```sql
67
- If @sys_SystemRight = 0
68
- Begin
69
- Raiserror(N'[Unauthorized]Bạn không có quyền trên chức năng này.', 16, 1)
70
- Return
71
- End
72
- ```
73
-
74
- ## Pattern 3 — 2-tier: global + module admin (WRITE)
75
-
76
- Writes affecting module config or other users' data. User must meet **either**:
77
-
78
- - `@sys_SystemRight >= 3` (high global right), **or**
79
- - Module Admin (`getSystemRight >= 9`) of that module.
80
-
81
- ```sql
82
- -- Tầng 1: phải có quyền cơ bản
83
- If @sys_SystemRight < 2
84
- Begin
85
- Raiserror(N'[Unauthorized]Bạn không có quyền trên chức năng này.', 16, 1)
86
- Return
87
- End
88
-
89
- -- Tầng 2: phải là admin hệ thống hoặc admin của module đó
90
- If @sys_SystemRight < 3 and dbo.getSystemRight(@ModuleID, @sys_UserID) < 9
91
- Begin
92
- Raiserror(N'[Unauthorized]Bạn không có quyền trên Module này.', 16, 1)
93
- Return
94
- End
95
- ```
96
-
97
- ## Pattern 4 — Business-rule check before executing
98
-
99
- Authorized but violates a data constraint (e.g. deleting a parent that still has children).
100
-
101
- ```sql
102
- -- Kiểm tra ràng buộc trước khi xóa
103
- If exists(Select * from tblChild WHERE ParentID = @ParentID)
104
- Begin
105
- Raiserror(N'Phải xóa dữ liệu liên quan trước khi thực hiện thao tác này.', 16, 1)
106
- Return
107
- End
108
-
109
- DELETE tblParent WHERE ParentID = @ParentID
110
- ```
111
-
112
- ## Pattern 5 — `@sys_FunctionRight` check
113
-
114
- Authorization by specific function (not just numeric level).
115
-
116
- ```sql
117
- If CHARINDEX('[ADMIN]', @sys_FunctionRight) = 0
118
- Begin
119
- Raiserror(N'[Unauthorized]Bạn không có quyền thực hiện chức năng này.', 16, 1)
120
- Return
121
- End
122
- ```
123
-
124
- ---
125
-
126
- ## Check order
127
-
128
- ```
129
- 1. Kiểm tra quyền hệ thống (@sys_SystemRight) ← luôn đầu tiên
130
- 2. Kiểm tra quyền module (getSystemRight) ← nếu cần 2 tầng
131
- 3. Kiểm tra quyền chức năng (@sys_FunctionRight) ← nếu dùng FunctionRight
132
- 4. Kiểm tra ràng buộc nghiệp vụ ← sau cùng, trước khi ghi
133
- ```
134
-
135
- ## Error message conventions
136
-
137
- | Case | Standard message |
138
- | ---------------------------------------- | --------------------------------------------------------------------- |
139
- | Missing global right | `N'[Unauthorized]Bạn không có quyền trên chức năng này.'` |
140
- | Missing module right | `N'[Unauthorized]Bạn không có quyền trên Module này.'` |
141
- | Missing function right (`FunctionRight`) | `N'[Unauthorized]Bạn không có quyền thực hiện chức năng này.'` |
142
- | Constraint violation | Specific description, **no** prefix: `N'Phải xóa X trước khi xóa Y.'` |
143
- | Invalid data | `N'Dữ liệu không hợp lệ.'` or specific description, **no** prefix |
144
-
145
- **Mandatory `RAISERROR` format:**
146
-
147
- ```sql
148
- RAISERROR(N'Thông báo lỗi tiếng Việt.', 16, 1)
149
- RETURN
150
- ```
151
-
152
- - **Severity always `16`** — every error kind (validation, unauthorized, business logic)
153
- - `N` prefix required for Vietnamese Unicode
154
- - `RETURN` required right after `RAISERROR` — without it the SP keeps running after the error
155
- - Client receives `{ "Message": "..." }`
156
- - **Every missing-right error in the 5 patterns must start with `[Unauthorized]`** (e.g. `N'[Unauthorized]Bạn không có quyền...'`) — tAPI uses this prefix to return HTTP `401` instead of the default, and strips `[Unauthorized]` from `Message` before returning. Constraint/business errors (Pattern 4) do **not** use it — mechanism + client 401 handling: [tapi-reference.md](tapi-reference.md) §5.
1
+ # tAPI — Permission Check Patterns
2
+
3
+ > Owns: **5 permission-check patterns in SP bodies (`@sys_SystemRight`, `getSystemRight`, RAISERROR)**. Load when an SP needs authorization. SP basics (naming, params, response, RAISERROR): [tapi-reference.md](tapi-reference.md). `SystemRight`/`FunctionRight` concepts, `tblSysRight`/`tblFunction`, right-definition commands: [permission-system.md](permission-system.md).
4
+
5
+ ---
6
+
7
+ ## Permission-related system params
8
+
9
+ Injected by tAPI — the client never sends them:
10
+
11
+ | Param | Type | Meaning |
12
+ | -------------------- | ------------- | ------------------------------------- |
13
+ | `@sys_UserID` | varchar(9) | Logged-in user ID |
14
+ | `@sys_SystemRight` | int | User's level on the current module |
15
+ | `@sys_FunctionRight` | varchar(2000) | Function rights like `[AD][RPT][MGR]` |
16
+
17
+ **Declare** at the end of the param list. **No default on any param, including `@sys_*`** ([tapi-reference.md](tapi-reference.md) §2 — tAPI always passes every param, `NULL` when missing, so `DEFAULT` is never used; `fui sp deploy` hard-blocks it):
18
+
19
+ ```sql
20
+ CREATE PROCEDURE spAPI_EntityAction
21
+ @BusinessParam1 int,
22
+ @BusinessParam2 nvarchar(100),
23
+ @sys_UserID varchar(9),
24
+ @sys_SystemRight int
25
+ AS
26
+ ```
27
+
28
+ ## `@sys_SystemRight` levels
29
+
30
+ Meaning is **defined per project** (`tblSysRight.Note`, managed via `fui right system list`/`update` — [permission-system.md](permission-system.md)). Common convention for SP checks — not platform-fixed, except `9` is always Project Admin:
31
+
32
+ | Value | Common meaning |
33
+ | ----- | -------------------------------------------------- |
34
+ | `0` | No right / not granted on the module |
35
+ | `1` | Basic view |
36
+ | `2` | Standard operations (read, add, normal edit) |
37
+ | `3` | Advanced (internal management, sensitive ops) |
38
+ | `9` | Module Admin / Project Admin (fixed platform-wide) |
39
+
40
+ ## Helper: rights on a specific module
41
+
42
+ ```sql
43
+ dbo.getSystemRight(@ModuleID, @sys_UserID)
44
+ ```
45
+
46
+ Returns the user's `SysRight` on a given module — use to check rights on a module **other than** the current one.
47
+
48
+ ---
49
+
50
+ ## Pattern 1 — Basic access block (READ)
51
+
52
+ Every read SP that needs login. Requires `SysRight >= 2`.
53
+
54
+ ```sql
55
+ If @sys_SystemRight < 2
56
+ Begin
57
+ Raiserror(N'[Unauthorized]Bạn không có quyền trên chức năng này.', 16, 1)
58
+ Return
59
+ End
60
+ ```
61
+
62
+ ## Pattern 2 — Block only users with no right (minimal)
63
+
64
+ Allows `SysRight = 1`; blocks only `SysRight = 0`.
65
+
66
+ ```sql
67
+ If @sys_SystemRight = 0
68
+ Begin
69
+ Raiserror(N'[Unauthorized]Bạn không có quyền trên chức năng này.', 16, 1)
70
+ Return
71
+ End
72
+ ```
73
+
74
+ ## Pattern 3 — 2-tier: global + module admin (WRITE)
75
+
76
+ Writes affecting module config or other users' data. User must meet **either**:
77
+
78
+ - `@sys_SystemRight >= 3` (high global right), **or**
79
+ - Module Admin (`getSystemRight >= 9`) of that module.
80
+
81
+ ```sql
82
+ -- Tầng 1: phải có quyền cơ bản
83
+ If @sys_SystemRight < 2
84
+ Begin
85
+ Raiserror(N'[Unauthorized]Bạn không có quyền trên chức năng này.', 16, 1)
86
+ Return
87
+ End
88
+
89
+ -- Tầng 2: phải là admin hệ thống hoặc admin của module đó
90
+ If @sys_SystemRight < 3 and dbo.getSystemRight(@ModuleID, @sys_UserID) < 9
91
+ Begin
92
+ Raiserror(N'[Unauthorized]Bạn không có quyền trên Module này.', 16, 1)
93
+ Return
94
+ End
95
+ ```
96
+
97
+ ## Pattern 4 — Business-rule check before executing
98
+
99
+ Authorized but violates a data constraint (e.g. deleting a parent that still has children).
100
+
101
+ ```sql
102
+ -- Kiểm tra ràng buộc trước khi xóa
103
+ If exists(Select * from tblChild WHERE ParentID = @ParentID)
104
+ Begin
105
+ Raiserror(N'Phải xóa dữ liệu liên quan trước khi thực hiện thao tác này.', 16, 1)
106
+ Return
107
+ End
108
+
109
+ DELETE tblParent WHERE ParentID = @ParentID
110
+ ```
111
+
112
+ ## Pattern 5 — `@sys_FunctionRight` check
113
+
114
+ Authorization by specific function (not just numeric level).
115
+
116
+ ```sql
117
+ If CHARINDEX('[ADMIN]', @sys_FunctionRight) = 0
118
+ Begin
119
+ Raiserror(N'[Unauthorized]Bạn không có quyền thực hiện chức năng này.', 16, 1)
120
+ Return
121
+ End
122
+ ```
123
+
124
+ ---
125
+
126
+ ## Check order
127
+
128
+ ```
129
+ 1. Kiểm tra quyền hệ thống (@sys_SystemRight) ← luôn đầu tiên
130
+ 2. Kiểm tra quyền module (getSystemRight) ← nếu cần 2 tầng
131
+ 3. Kiểm tra quyền chức năng (@sys_FunctionRight) ← nếu dùng FunctionRight
132
+ 4. Kiểm tra ràng buộc nghiệp vụ ← sau cùng, trước khi ghi
133
+ ```
134
+
135
+ ## Error message conventions
136
+
137
+ | Case | Standard message |
138
+ | ---------------------------------------- | --------------------------------------------------------------------- |
139
+ | Missing global right | `N'[Unauthorized]Bạn không có quyền trên chức năng này.'` |
140
+ | Missing module right | `N'[Unauthorized]Bạn không có quyền trên Module này.'` |
141
+ | Missing function right (`FunctionRight`) | `N'[Unauthorized]Bạn không có quyền thực hiện chức năng này.'` |
142
+ | Constraint violation | Specific description, **no** prefix: `N'Phải xóa X trước khi xóa Y.'` |
143
+ | Invalid data | `N'Dữ liệu không hợp lệ.'` or specific description, **no** prefix |
144
+
145
+ **Mandatory `RAISERROR` format:**
146
+
147
+ ```sql
148
+ RAISERROR(N'Thông báo lỗi tiếng Việt.', 16, 1)
149
+ RETURN
150
+ ```
151
+
152
+ - **Severity always `16`** — every error kind (validation, unauthorized, business logic)
153
+ - `N` prefix required for Vietnamese Unicode
154
+ - `RETURN` required right after `RAISERROR` — without it the SP keeps running after the error
155
+ - Client receives `{ "Message": "..." }`
156
+ - **Every missing-right error in the 5 patterns must start with `[Unauthorized]`** (e.g. `N'[Unauthorized]Bạn không có quyền...'`) — tAPI uses this prefix to return HTTP `401` instead of the default, and strips `[Unauthorized]` from `Message` before returning. Constraint/business errors (Pattern 4) do **not** use it — mechanism + client 401 handling: [tapi-reference.md](tapi-reference.md) §5.