@elevasis/sdk 1.10.0 → 1.12.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/dist/cli.cjs +52 -149
- package/dist/index.d.ts +468 -198
- package/dist/index.js +225 -147
- package/dist/test-utils/index.d.ts +272 -99
- package/dist/test-utils/index.js +4756 -125
- package/dist/types/worker/adapters/llm.d.ts +1 -1
- package/dist/worker/index.js +14 -6
- package/package.json +2 -2
- package/reference/claude-config/rules/agent-start-here.md +14 -14
- package/reference/claude-config/skills/configure/SKILL.md +3 -3
- package/reference/claude-config/skills/setup/SKILL.md +6 -6
- package/reference/claude-config/sync-notes/2026-04-25-auth-role-system-and-settings-roles.md +55 -0
- package/reference/claude-config/sync-notes/2026-04-27-crm-hitl-action-layer-cutover.md +101 -0
- package/reference/cli.mdx +57 -0
- package/reference/deployment/provided-features.mdx +40 -267
- package/reference/examples/organization-model.ts +99 -564
- package/reference/packages/core/src/organization-model/README.md +102 -97
- package/reference/resources/types.mdx +72 -163
- package/reference/scaffold/core/organization-graph.mdx +92 -272
- package/reference/scaffold/core/organization-model.mdx +155 -320
- package/reference/scaffold/index.mdx +3 -0
- package/reference/scaffold/operations/propagation-pipeline.md +4 -1
- package/reference/scaffold/operations/scaffold-maintenance.md +3 -0
- package/reference/scaffold/operations/workflow-recipes.md +13 -10
- package/reference/scaffold/recipes/add-a-feature.md +105 -158
- package/reference/scaffold/recipes/add-a-resource.md +88 -158
- package/reference/scaffold/recipes/customize-organization-model.md +144 -400
- package/reference/scaffold/recipes/extend-a-base-entity.md +11 -8
- package/reference/scaffold/recipes/gate-by-feature-or-admin.md +117 -158
- package/reference/scaffold/recipes/index.md +3 -0
- package/reference/scaffold/reference/contracts.md +107 -435
- package/reference/scaffold/reference/feature-registry.md +11 -8
- package/reference/scaffold/reference/glossary.md +74 -105
- package/reference/scaffold/ui/composition-extensibility.mdx +3 -0
- package/reference/scaffold/ui/customization.md +3 -0
- package/reference/scaffold/ui/feature-flags-and-gating.md +29 -231
- package/reference/scaffold/ui/feature-shell.mdx +53 -219
- package/reference/scaffold/ui/recipes.md +65 -397
- package/reference/claude-config/logs/pre-edit-vibe-gate.log +0 -40
- package/reference/claude-config/logs/scaffold-registry-reminder.log +0 -38
|
@@ -1,158 +1,117 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Gate by Feature or Admin
|
|
3
|
-
description: Decision table and
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
|
19
|
-
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
{ label: 'Analytics', icon: IconChartBar, link: '/analytics', featureKey: 'analytics' }
|
|
119
|
-
{ label: 'Admin', icon: IconShield, link: '/admin', requiresAdmin: true }
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
`featureKey` on a nav entry is a display hint only -- it does not protect the route. Always pair with a route-level `FeatureGuard`. See [glossary.md](../reference/glossary.md) under **featureId vs featureKey** for the distinction. When the `featureKey` is one of the 7 platform features, prefer the typed constant (e.g., `featureKey: SALES_FEATURE_ID`) over a string literal to catch renames at compile time.
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## 6. Per-member override
|
|
127
|
-
|
|
128
|
-
`MembershipFeatureConfig.features` (stored in `org_memberships.config`) overrides org-level defaults per member. Full shape is in [contracts.md](../reference/contracts.md#membershipfeatureconfig).
|
|
129
|
-
|
|
130
|
-
```ts
|
|
131
|
-
// Disable analytics for a specific member (stored in their membership record):
|
|
132
|
-
{
|
|
133
|
-
features: { analytics: false }
|
|
134
|
-
}
|
|
135
|
-
```
|
|
136
|
-
|
|
137
|
-
`MembershipFeatureConfig.features` is `Record<string, boolean>` -- a dynamic map keyed by feature ID. Any feature ID from the org model can be overridden per member without schema changes.
|
|
138
|
-
|
|
139
|
-
**Settings asymmetry -- read this before writing membership config.** The `settings` feature is intentionally excluded from per-member overrides: settings access is controlled by `requiresAdmin` and `AdminGuard`, not per-member feature flags. Writing a `settings` key to `org_memberships.config` has no effect. See [contracts.md](../reference/contracts.md#membershipfeatureconfig) for the full callout, and [glossary.md](../reference/glossary.md) under **Settings asymmetry**.
|
|
140
|
-
|
|
141
|
-
Membership config is read/written directly via the Supabase client (`org_memberships.config` column). There is no dedicated API route for bulk updates.
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
## 7. Verify
|
|
146
|
-
|
|
147
|
-
State matrix -- confirm each combination:
|
|
148
|
-
|
|
149
|
-
| Org feature enabled | Member override | Admin | Expected result |
|
|
150
|
-
| ------------------- | --------------- | --------- | --------------------------------------------- |
|
|
151
|
-
| true | (absent) | any | Route accessible, nav visible |
|
|
152
|
-
| true | false | any | Route redirects, nav hidden |
|
|
153
|
-
| false | (absent) | any | Route redirects, nav hidden |
|
|
154
|
-
| false | true | any | Route redirects (org gate wins) |
|
|
155
|
-
| true | (absent) | non-admin | Admin-gated route redirects, admin nav hidden |
|
|
156
|
-
| true | (absent) | admin | Admin-gated route accessible, nav visible |
|
|
157
|
-
|
|
158
|
-
Check each gate independently: feature toggle in `core/config/organization-model.ts`, membership config in `org_memberships.config`, and admin status in the user profile.
|
|
1
|
+
---
|
|
2
|
+
title: Gate by Feature or Admin
|
|
3
|
+
description: Decision table and recipes for gating routes, sidebar entries, and UI elements by Organization Model feature ID or admin role.
|
|
4
|
+
---
|
|
5
|
+
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
6
|
+
<!-- Regenerate: pnpm scaffold:sync -->
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
# Gate by Feature or Admin
|
|
10
|
+
|
|
11
|
+
Feature visibility starts in `core/config/organization-model.ts`. Routes still enforce access with guards.
|
|
12
|
+
|
|
13
|
+
## Decide the gate
|
|
14
|
+
|
|
15
|
+
| Scenario | Gate to use |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| Surface can be enabled or disabled per organization/member | `FeatureGuard` with the feature ID |
|
|
18
|
+
| Surface is always available to members but restricted to admins | `AdminGuard` plus `requiresAdmin: true` on the feature node |
|
|
19
|
+
| Surface is both feature-gated and admin-only | Both guards, plus `requiresAdmin: true` on the feature node |
|
|
20
|
+
|
|
21
|
+
## Feature gate in the org model
|
|
22
|
+
|
|
23
|
+
Add or update the feature in `features`.
|
|
24
|
+
|
|
25
|
+
```ts
|
|
26
|
+
features: [
|
|
27
|
+
{
|
|
28
|
+
id: 'analytics',
|
|
29
|
+
label: 'Analytics',
|
|
30
|
+
enabled: false,
|
|
31
|
+
path: '/analytics',
|
|
32
|
+
icon: 'chart',
|
|
33
|
+
uiPosition: 'sidebar-primary'
|
|
34
|
+
}
|
|
35
|
+
]
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Set `enabled: true` to enable it for all members by default. Dotted IDs such as `analytics.reports` inherit feature state and shell placement from their ancestors unless they declare their own value.
|
|
39
|
+
|
|
40
|
+
## Route-level feature gate
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { ProtectedRoute } from '@/features/auth'
|
|
44
|
+
import { FeatureGuard } from '@/features/auth/guards/FeatureGuard'
|
|
45
|
+
import { createFileRoute, Outlet } from '@tanstack/react-router'
|
|
46
|
+
|
|
47
|
+
export const Route = createFileRoute('/analytics')({ component: AnalyticsLayout })
|
|
48
|
+
|
|
49
|
+
function AnalyticsLayout() {
|
|
50
|
+
return (
|
|
51
|
+
<ProtectedRoute>
|
|
52
|
+
<FeatureGuard featureKey="analytics">
|
|
53
|
+
<Outlet />
|
|
54
|
+
</FeatureGuard>
|
|
55
|
+
</ProtectedRoute>
|
|
56
|
+
)
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
The sidebar is derived from `OrganizationModel.features`; hiding a node there is display behavior only. Keep route guards in place for direct URL access.
|
|
61
|
+
|
|
62
|
+
## Admin-only route
|
|
63
|
+
|
|
64
|
+
```tsx
|
|
65
|
+
import { ProtectedRoute } from '@/features/auth'
|
|
66
|
+
import { AdminGuard } from '@elevasis/ui/auth'
|
|
67
|
+
import { createFileRoute, Outlet } from '@tanstack/react-router'
|
|
68
|
+
|
|
69
|
+
export const Route = createFileRoute('/admin')({ component: AdminLayout })
|
|
70
|
+
|
|
71
|
+
function AdminLayout() {
|
|
72
|
+
return (
|
|
73
|
+
<ProtectedRoute>
|
|
74
|
+
<AdminGuard>
|
|
75
|
+
<Outlet />
|
|
76
|
+
</AdminGuard>
|
|
77
|
+
</ProtectedRoute>
|
|
78
|
+
)
|
|
79
|
+
}
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Pair the route guard with the feature node:
|
|
83
|
+
|
|
84
|
+
```ts
|
|
85
|
+
{
|
|
86
|
+
id: 'admin',
|
|
87
|
+
label: 'Admin',
|
|
88
|
+
enabled: true,
|
|
89
|
+
path: '/admin',
|
|
90
|
+
uiPosition: 'sidebar-bottom',
|
|
91
|
+
requiresAdmin: true
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Per-member override
|
|
96
|
+
|
|
97
|
+
`MembershipFeatureConfig.features` in `org_memberships.config` overrides enabled state per member.
|
|
98
|
+
|
|
99
|
+
```ts
|
|
100
|
+
{
|
|
101
|
+
features: { analytics: false }
|
|
102
|
+
}
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Settings and admin-only pages should use admin checks, not per-member feature flags.
|
|
106
|
+
|
|
107
|
+
## Verify
|
|
108
|
+
|
|
109
|
+
Check the state matrix:
|
|
110
|
+
|
|
111
|
+
| Org feature enabled | Member override | Admin | Expected result |
|
|
112
|
+
| --- | --- | --- | --- |
|
|
113
|
+
| true | absent | any | Route accessible, sidebar visible |
|
|
114
|
+
| true | false | any | Route redirects, sidebar hidden |
|
|
115
|
+
| false | absent | any | Route redirects, sidebar hidden |
|
|
116
|
+
| true | absent | non-admin | Admin route redirects, admin sidebar hidden |
|
|
117
|
+
| true | absent | admin | Admin route accessible, admin sidebar visible |
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
title: Pathway Recipes
|
|
3
3
|
description: Terse end-to-end walkthroughs for the three most common authoring tasks -- adding a feature, adding a resource, and gating access.
|
|
4
4
|
---
|
|
5
|
+
<!-- @generated by packages/sdk/scripts/copy-reference-docs.mjs -- DO NOT EDIT -->
|
|
6
|
+
<!-- Regenerate: pnpm scaffold:sync -->
|
|
7
|
+
|
|
5
8
|
|
|
6
9
|
# Pathway Recipes
|
|
7
10
|
|