@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.
- package/README.md +27 -7
- package/dist/fui-qrb1j9jz.js +397 -0
- package/dist/fui.js +1 -1
- package/package.json +1 -1
- package/skills/fui/SKILL.md +143 -38
- package/skills/fui/agents/fui-builder.md +62 -0
- package/skills/fui/agents/fui-tester.md +77 -0
- package/skills/{fui-skill → fui}/assets/projectdefaultstyle.css +489 -489
- package/skills/{fui-skill → fui}/examples/component.vue +162 -162
- package/skills/{fui-skill → fui}/references/INDEX.md +5 -4
- package/skills/{fui-skill → fui}/references/advanced-techniques.md +170 -168
- package/skills/{fui-skill → fui}/references/component-design.md +2 -2
- package/skills/{fui-skill → fui}/references/component-quickref.md +78 -78
- package/skills/{fui-skill → fui}/references/component-table.md +287 -287
- package/skills/{fui-skill → fui}/references/components-dialog.md +191 -191
- package/skills/{fui-skill → fui}/references/components-display.md +141 -141
- package/skills/{fui-skill → fui}/references/components-echart.md +316 -316
- package/skills/{fui-skill → fui}/references/components-input.md +335 -335
- package/skills/{fui-skill → fui}/references/controls-patterns.md +2 -2
- package/skills/{fui-skill → fui}/references/controls-styling-vocabulary.md +173 -173
- package/skills/{fui-skill → fui}/references/db-workflow.md +9 -9
- package/skills/{fui-skill → fui}/references/default-function.md +456 -456
- package/skills/{fui-skill → fui}/references/design-modes.md +57 -57
- package/skills/{fui-skill → fui}/references/echart-templates.md +489 -489
- package/skills/{fui-skill → fui}/references/fastproject.md +99 -99
- package/skills/{fui-skill → fui}/references/fullstack-workflow.md +314 -313
- package/skills/{fui-skill → fui}/references/module-data-patterns.md +117 -117
- package/skills/{fui-skill → fui}/references/module-json-anatomy.md +132 -132
- package/skills/{fui-skill → fui}/references/module-structure.md +144 -144
- package/skills/{fui-skill → fui}/references/new-session.md +1 -2
- package/skills/{fui-skill → fui}/references/pdfmake.md +60 -60
- package/skills/{fui-skill → fui}/references/permission-system.md +1 -1
- package/skills/{fui-skill → fui}/references/platform-architecture.md +269 -269
- package/skills/{fui-skill → fui}/references/project-config.md +303 -303
- package/skills/{fui-skill → fui}/references/project-provisioning.md +4 -4
- package/skills/{fui-skill → fui}/references/script-map.md +262 -262
- package/skills/{fui-skill → fui}/references/sql-clr-functions.md +225 -225
- package/skills/{fui-skill → fui}/references/system-design.md +2 -2
- package/skills/{fui-skill → fui}/references/tapi-permission-patterns.md +156 -156
- package/skills/{fui-skill → fui}/references/tapi-reference.md +474 -474
- package/skills/fui/references/team-run.md +141 -0
- package/skills/fui/references/tools-registry.md +211 -0
- package/skills/{fui-skill → fui}/references/ui-crosswindow-patterns.md +321 -321
- package/skills/{fui-skill → fui}/references/ui-dialog-patterns.md +255 -255
- package/skills/{fui-skill → fui}/references/ui-layout-patterns.md +176 -176
- package/skills/{fui-skill → fui}/references/ui-patterns.md +303 -303
- package/skills/{fui-skill → fui}/references/ui-screenshot-review.md +95 -95
- package/skills/{fui-skill → fui}/references/ui-table-cell-patterns.md +318 -318
- package/skills/{fui-skill → fui}/references/verification.md +11 -11
- package/skills/{fui-skill → fui}/references/watcher-patterns.md +163 -163
- package/skills/{fui-skill → fui}/references/websocket-realtime.md +271 -271
- package/skills/{fui-skill → fui}/scripts/component-3.0.js +2715 -2715
- package/skills/{fui-skill → fui}/scripts/component.js +3147 -3147
- package/skills/{fui-skill → fui}/scripts/componentTable-3.0.js +1038 -1038
- package/skills/{fui-skill → fui}/scripts/componentTable.js +891 -891
- package/skills/{fui-skill → fui}/scripts/defaultfunction-3.0.js +866 -866
- package/skills/{fui-skill → fui}/scripts/defaultfunction.js +1051 -1051
- package/skills/{fui-skill → fui}/scripts/fastproject-3.0.js +870 -870
- package/skills/{fui-skill → fui}/scripts/fastproject.js +828 -828
- package/skills/fui-target/hooks/register.tsx +2 -0
- package/skills/fui-target/types/index.d.ts +1 -0
- package/dist/fui-hk5frcn2.js +0 -381
- package/skills/fui-skill/SKILL.md +0 -139
- package/skills/fui-skill/references/tools-registry.md +0 -84
- /package/skills/{fui-skill → fui}/assets/projectdefaultstyle-3.0.css +0 -0
- /package/skills/{fui-skill → fui}/design-md/airbnb/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airbnb/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airtable/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/airtable/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/apple/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/apple/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/asu/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/asu/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/binance/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/binance/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw-m/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bmw-m/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bugatti/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/bugatti/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cal/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cal/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/claude/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/claude/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clay/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clay/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clickhouse/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/clickhouse/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cohere/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cohere/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/coinbase/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/coinbase/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/composio/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/composio/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cursor/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/cursor/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/elevenlabs/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/elevenlabs/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/expo/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/expo/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ferrari/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ferrari/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/figma/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/figma/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/framer/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/framer/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/fui/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/hashicorp/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/hashicorp/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ibm/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ibm/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/intercom/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/intercom/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/kraken/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/kraken/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lamborghini/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lamborghini/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/linear.app/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/linear.app/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lovable/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/lovable/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mastercard/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mastercard/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/meta/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/meta/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/minimax/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/minimax/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mintlify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mintlify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/miro/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/miro/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mistral.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mistral.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mongodb/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/mongodb/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nike/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nike/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/notion/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/notion/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nvidia/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/nvidia/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ollama/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/ollama/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/opencode.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/opencode.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/pinterest/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/pinterest/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/playstation/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/playstation/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/posthog/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/posthog/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/raycast/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/raycast/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/renault/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/renault/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/replicate/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/replicate/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/resend/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/resend/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/revolut/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/revolut/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/runwayml/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/runwayml/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sanity/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sanity/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sentry/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/sentry/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/shopify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/shopify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/slack/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spacex/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spacex/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spotify/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/spotify/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/starbucks/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/starbucks/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/stripe/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/stripe/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/supabase/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/supabase/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/superhuman/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/superhuman/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/tesla/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/tesla/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/theverge/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/theverge/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/together.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/together.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/uber/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/uber/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vercel/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vercel/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vodafone/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/vodafone/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/voltagent/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/voltagent/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/warp/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/warp/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/webflow/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/webflow/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wired/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wired/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wise/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/wise/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/x.ai/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/x.ai/README.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/zapier/DESIGN.md +0 -0
- /package/skills/{fui-skill → fui}/design-md/zapier/README.md +0 -0
- /package/skills/{fui-skill → fui}/examples/f-table-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/examples/module-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/examples/project-patterns.json +0 -0
- /package/skills/{fui-skill → fui}/references/coding-standards.md +0 -0
- /package/skills/{fui-skill → fui}/references/db-table-design.md +0 -0
- /package/skills/{fui-skill → fui}/references/fsheet.md +0 -0
- /package/skills/{fui-skill → fui}/references/tapi-file-api.md +0 -0
- /package/skills/{fui-skill → fui}/references/ui-templates.md +0 -0
- /package/skills/{fui-skill → fui}/scripts/fechart.js +0 -0
- /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.
|