@elevasis/core 0.35.1 → 0.37.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 (32) hide show
  1. package/dist/auth/index.d.ts +124 -2
  2. package/dist/auth/index.js +14 -1
  3. package/dist/index.d.ts +334 -3
  4. package/dist/index.js +21 -5
  5. package/dist/knowledge/index.d.ts +81 -0
  6. package/dist/organization-model/index.d.ts +334 -3
  7. package/dist/organization-model/index.js +21 -5
  8. package/dist/test-utils/index.d.ts +97 -0
  9. package/dist/test-utils/index.js +19 -4
  10. package/package.json +1 -1
  11. package/src/_gen/__tests__/__snapshots__/contracts.md.snap +67 -0
  12. package/src/auth/multi-tenancy/invitations/api-schemas.ts +24 -9
  13. package/src/auth/multi-tenancy/invitations/index.ts +11 -9
  14. package/src/auth/multi-tenancy/organizations/__tests__/api-schemas.test.ts +39 -3
  15. package/src/auth/multi-tenancy/organizations/api-schemas.ts +36 -8
  16. package/src/auth/multi-tenancy/organizations/index.ts +13 -11
  17. package/src/business/acquisition/build-templates.test.ts +34 -0
  18. package/src/business/acquisition/build-templates.ts +8 -1
  19. package/src/organization-model/__tests__/domains/navigation-topbar.test.ts +282 -0
  20. package/src/organization-model/__tests__/migration-helpers.test.ts +11 -11
  21. package/src/organization-model/defaults.ts +2 -1
  22. package/src/organization-model/domains/navigation.ts +176 -139
  23. package/src/organization-model/icons.ts +1 -0
  24. package/src/organization-model/migration-helpers.ts +8 -1
  25. package/src/organization-model/published.ts +6 -6
  26. package/src/organization-model/types.ts +5 -1
  27. package/src/platform/constants/versions.ts +1 -1
  28. package/src/platform/registry/__tests__/resource-registry.test.ts +2053 -2054
  29. package/src/reference/_generated/contracts.md +67 -0
  30. package/src/scaffold-registry/index.ts +4 -4
  31. package/src/supabase/database.types.ts +15 -0
  32. package/src/test-utils/rls/RLSTestContext.ts +3 -3
@@ -135,6 +135,18 @@ export type OrganizationModelSidebarSurfaceNode = Extract<OrganizationModelSideb
135
135
  export type OrganizationModelSidebarGroupNode = Extract<OrganizationModelSidebarNode, { type: 'group' }>
136
136
  ```
137
137
 
138
+ ### `OrganizationModelTopbarActionNode`
139
+
140
+ ```typescript
141
+ export type OrganizationModelTopbarActionNode = z.infer<typeof TopbarActionNodeSchema>
142
+ ```
143
+
144
+ ### `OrganizationModelTopbarSection`
145
+
146
+ ```typescript
147
+ export type OrganizationModelTopbarSection = z.infer<typeof TopbarSectionSchema>
148
+ ```
149
+
138
150
  ### `OrganizationModelTechStackEntry`
139
151
 
140
152
  ```typescript
@@ -845,6 +857,57 @@ export interface ShellRuntime {
845
857
  }
846
858
  ```
847
859
 
860
+ ### `ResolvedTopbarAction`
861
+
862
+ ```typescript
863
+ /**
864
+ * A resolved topbar action — the OM node after gating/filtering, with icon resolved
865
+ * from the semantic icon registry. Passed to `TopbarActionModule.render`.
866
+ */
867
+ export interface ResolvedTopbarAction {
868
+ id: string
869
+ label: string
870
+ tooltip?: string
871
+ icon: TablerIconComponent
872
+ order: number
873
+ }
874
+ ```
875
+
876
+ ### `TopbarActionModule`
877
+
878
+ ```typescript
879
+ /**
880
+ * A topbar action module — binds a registry key to UI behavior (a render callback).
881
+ * The key must match `navigation.topbar[id]`. The OM supplies data + visibility;
882
+ * the module supplies behavior.
883
+ */
884
+ export interface TopbarActionModule {
885
+ /** Stable key that matches the `id` of a `navigation.topbar` node. */
886
+ key: string
887
+ /** Render the topbar action. Receives the resolved OM node (icon pre-resolved). */
888
+ render: (ctx: { node: ResolvedTopbarAction }) => ReactNode
889
+ }
890
+ ```
891
+
892
+ ### `ResolvedTopbarActionEntry`
893
+
894
+ ```typescript
895
+ /** A joined entry emitted by `getTopbarActions`: resolved OM node + module behavior. */
896
+ export interface ResolvedTopbarActionEntry {
897
+ node: ResolvedTopbarAction
898
+ render: TopbarActionModule['render']
899
+ }
900
+ ```
901
+
902
+ ### `TopbarActionsProjectionOptions`
903
+
904
+ ```typescript
905
+ export interface TopbarActionsProjectionOptions {
906
+ isPlatformAdmin?: boolean
907
+ isDev?: boolean
908
+ }
909
+ ```
910
+
848
911
  ### `OrganizationGraphSystemBridge`
849
912
 
850
913
  ```typescript
@@ -868,6 +931,8 @@ export interface OrganizationGraphContextValue {
868
931
  ```typescript
869
932
  export interface ElevasisSystemsProviderProps {
870
933
  systems?: SystemModule[]
934
+ /** Registered topbar action modules. OM node presence controls visibility; module supplies behavior. */
935
+ topbarActions?: TopbarActionModule[]
871
936
  organizationModel?: ElevasisOrganizationModel
872
937
  timeRange?: TimeRange
873
938
  operationsApiUrl?: string
@@ -886,6 +951,8 @@ export interface ElevasisSystemsContextValue {
886
951
  shellModel: ResolvedShellModel
887
952
  shellRuntime: ShellRuntime
888
953
  getSidebarLinks: (options?: ShellSidebarProjectionOptions) => ShellSidebarLinkGroup[]
954
+ /** Returns the list of topbar actions visible to the current user, in order. */
955
+ getTopbarActions: (options?: TopbarActionsProjectionOptions) => ResolvedTopbarActionEntry[]
889
956
  enabledResolvedSystems: ResolvedSystemModule[]
890
957
  resolvedSystems: ResolvedSystemModule[]
891
958
  organizationGraph: OrganizationGraphContextValue
@@ -50,15 +50,15 @@ function monorepoRoot(): string {
50
50
  )
51
51
  }
52
52
 
53
- const YAML_FILENAME = '.claude/scaffold-registry.yml'
54
- const JSON_FILENAME = '.claude/scaffold-registry.compiled.json'
53
+ const YAML_FILENAME = '.claude/registries/scaffold-registry.yml'
54
+ const JSON_FILENAME = '.claude/registries/scaffold-registry.compiled.json'
55
55
 
56
56
  // ---------------------------------------------------------------------------
57
57
  // Load + validate
58
58
  // ---------------------------------------------------------------------------
59
59
 
60
60
  /**
61
- * Load and Zod-validate the scaffold registry from `.claude/scaffold-registry.yml`.
61
+ * Load and Zod-validate the scaffold registry from `.claude/registries/scaffold-registry.yml`.
62
62
  *
63
63
  * Throws if:
64
64
  * - The YAML file is missing or unreadable
@@ -123,7 +123,7 @@ export function loadScaffoldRegistry(): ScaffoldRegistry {
123
123
 
124
124
  /**
125
125
  * Load, validate, and write the pre-compiled JSON lookup file.
126
- * Run this whenever `.claude/scaffold-registry.yml` changes.
126
+ * Run this whenever `.claude/registries/scaffold-registry.yml` changes.
127
127
  *
128
128
  * Called by the `pnpm scaffold:compile-registry` script (wired in Step 2 CI).
129
129
  */
@@ -3063,6 +3063,17 @@ export type Database = {
3063
3063
  }
3064
3064
  process_due_schedules: { Args: never; Returns: Json }
3065
3065
  recompute_all_memberships: { Args: never; Returns: undefined }
3066
+ repair_membership_role_assignments: {
3067
+ Args: never
3068
+ Returns: {
3069
+ membership_id: string
3070
+ organization_id: string
3071
+ repaired: boolean
3072
+ role_id: string
3073
+ role_slug: string
3074
+ user_id: string
3075
+ }[]
3076
+ }
3066
3077
  sync_all_memberships_with_role: {
3067
3078
  Args: { p_role_id: string }
3068
3079
  Returns: undefined
@@ -3071,6 +3082,10 @@ export type Database = {
3071
3082
  Args: { p_membership_id: string }
3072
3083
  Returns: undefined
3073
3084
  }
3085
+ update_membership_role_assignment: {
3086
+ Args: { p_role_slug: string; p_workos_membership_id: string }
3087
+ Returns: string
3088
+ }
3074
3089
  upsert_user_profile: {
3075
3090
  Args: never
3076
3091
  Returns: {
@@ -249,9 +249,9 @@ export class RLSTestContext {
249
249
  throw new Error(`Failed to look up system role '${slug}': ${roleErr?.message ?? 'not found'}`)
250
250
  }
251
251
 
252
- const { error: assignErr } = await this.adminClient
253
- .from('org_rol_assignments')
254
- .insert({ membership_id: membershipId, role_id: roleDef.id })
252
+ const { error: assignErr } = await this.adminClient
253
+ .from('org_rol_assignments')
254
+ .upsert({ membership_id: membershipId, role_id: roleDef.id }, { onConflict: 'membership_id,role_id' })
255
255
 
256
256
  if (assignErr) {
257
257
  throw new Error(`Failed to assign system role '${slug}' to membership: ${assignErr.message}`)