spine-framework 0.3.124 → 0.3.126

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 (319) hide show
  1. package/.framework/cli/commands/agents.ts +35 -37
  2. package/.framework/cli/commands/auth.ts +35 -34
  3. package/.framework/cli/commands/create-app.ts +104 -40
  4. package/.framework/cli/commands/dev.ts +104 -69
  5. package/.framework/cli/commands/doctor.ts +179 -69
  6. package/.framework/cli/commands/generate.ts +83 -143
  7. package/.framework/cli/commands/init.ts +72 -34
  8. package/.framework/cli/commands/install-app.ts +260 -125
  9. package/.framework/cli/commands/items.ts +33 -44
  10. package/.framework/cli/commands/migrate.ts +122 -40
  11. package/.framework/cli/commands/migrations.ts +33 -40
  12. package/.framework/cli/commands/pipelines.ts +31 -39
  13. package/.framework/cli/commands/status.ts +47 -23
  14. package/.framework/cli/commands/system.ts +47 -37
  15. package/.framework/cli/commands/test.ts +112 -68
  16. package/.framework/cli/commands/validate-app.ts +215 -121
  17. package/.framework/cli/context.ts +112 -130
  18. package/.framework/cli/env-loader.ts +47 -18
  19. package/.framework/cli/index.ts +81 -42
  20. package/.framework/docs/runtime-types.md +1024 -0
  21. package/.framework/functions/_shared/agent-runner.ts +1296 -961
  22. package/.framework/functions/_shared/app-manifest.ts +82 -68
  23. package/.framework/functions/_shared/audit.ts +135 -83
  24. package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
  25. package/.framework/functions/_shared/db.ts +80 -126
  26. package/.framework/functions/_shared/hash-api-key.ts +63 -0
  27. package/.framework/functions/_shared/index.ts +224 -335
  28. package/.framework/functions/_shared/kb.ts +319 -0
  29. package/.framework/functions/_shared/llm.ts +92 -0
  30. package/.framework/functions/_shared/logging.ts +288 -0
  31. package/.framework/functions/_shared/middleware.ts +329 -365
  32. package/.framework/functions/_shared/outcomes.ts +36 -0
  33. package/.framework/functions/_shared/permissions.ts +359 -643
  34. package/.framework/functions/_shared/pipeline-runner.ts +243 -316
  35. package/.framework/functions/_shared/principal.ts +376 -468
  36. package/.framework/functions/_shared/resolve-credentials.ts +102 -0
  37. package/.framework/functions/_shared/resolve-ids.ts +188 -16
  38. package/.framework/functions/_shared/retry-deliveries.ts +104 -0
  39. package/.framework/functions/_shared/schema-utils.ts +611 -373
  40. package/.framework/functions/_shared/testing.ts +207 -137
  41. package/.framework/functions/_shared/tracing.ts +276 -0
  42. package/.framework/functions/_shared/trigger-engine.ts +159 -211
  43. package/.framework/functions/_shared/webhook-registration.ts +95 -81
  44. package/.framework/functions/_shared/webhook-registry.ts +153 -75
  45. package/.framework/functions/account-nodes.ts +31 -53
  46. package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
  47. package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
  48. package/.framework/functions/adapters/openai-outbound.ts +40 -0
  49. package/.framework/functions/admin-data.ts +685 -537
  50. package/.framework/functions/admin-funnel.ts +31 -20
  51. package/.framework/functions/admin-install-funnel.ts +47 -28
  52. package/.framework/functions/admin-signals.ts +47 -29
  53. package/.framework/functions/ai-agents.ts +122 -147
  54. package/.framework/functions/ai-interactions.ts +180 -90
  55. package/.framework/functions/api-keys.ts +250 -192
  56. package/.framework/functions/apps.ts +203 -197
  57. package/.framework/functions/auth.ts +98 -91
  58. package/.framework/functions/cil-agent-ingest.ts +773 -0
  59. package/.framework/functions/cil-agent.ts +592 -0
  60. package/.framework/functions/cil-callmap.ts +1227 -0
  61. package/.framework/functions/cil-config.ts +583 -0
  62. package/.framework/functions/cil-context.ts +445 -0
  63. package/.framework/functions/cil-doc.ts +1752 -0
  64. package/.framework/functions/cil-embeddings.ts +1202 -0
  65. package/.framework/functions/cil-graph.ts +585 -0
  66. package/.framework/functions/cil-ingest.ts +2416 -0
  67. package/.framework/functions/cil-pipeline.ts +318 -0
  68. package/.framework/functions/cil-project.ts +499 -0
  69. package/.framework/functions/cil-validate.ts +469 -0
  70. package/.framework/functions/debug-auth.ts +73 -53
  71. package/.framework/functions/deliveries.ts +117 -0
  72. package/.framework/functions/embeddings.ts +528 -516
  73. package/.framework/functions/eval-harness.ts +158 -106
  74. package/.framework/functions/integration-outbound.ts +311 -0
  75. package/.framework/functions/integration-routes.ts +240 -466
  76. package/.framework/functions/integrations.ts +132 -140
  77. package/.framework/functions/invites.ts +401 -201
  78. package/.framework/functions/item-progress.ts +113 -53
  79. package/.framework/functions/kb.ts +28 -0
  80. package/.framework/functions/logs.ts +239 -222
  81. package/.framework/functions/observability.ts +308 -259
  82. package/.framework/functions/pipeline-executions.ts +179 -235
  83. package/.framework/functions/pipelines.ts +163 -205
  84. package/.framework/functions/prompt-configs.ts +109 -156
  85. package/.framework/functions/roles.ts +97 -147
  86. package/.framework/functions/system-cron.ts +132 -218
  87. package/.framework/functions/system.ts +112 -52
  88. package/.framework/functions/tests.ts +32 -28
  89. package/.framework/functions/timers.ts +162 -210
  90. package/.framework/functions/triggers.ts +282 -346
  91. package/.framework/functions/types.ts +283 -400
  92. package/.framework/migrations/001_core_schema.sql +630 -0
  93. package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
  94. package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
  95. package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
  96. package/.framework/migrations/005_core_observability.sql +598 -0
  97. package/.framework/migrations/006_security_hardening_rls.sql +97 -0
  98. package/.framework/migrations/007_kb_article_list.sql +237 -0
  99. package/.framework/migrations/008_items_target.sql +8 -0
  100. package/.framework/migrations/009_roles_slug_unique.sql +11 -0
  101. package/.framework/public/spine.config.json +91 -0
  102. package/.framework/scripts/app-install-cli.ts +112 -98
  103. package/.framework/src/App.tsx +67 -20
  104. package/.framework/src/apps/admin/index.tsx +97 -27
  105. package/.framework/src/components/AppWrapper.tsx +50 -11
  106. package/.framework/src/components/CustomAppLoader.tsx +131 -22
  107. package/.framework/src/components/admin/AdminListPage.tsx +75 -8
  108. package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
  109. package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
  110. package/.framework/src/components/admin/PageInstructions.tsx +49 -0
  111. package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
  112. package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
  113. package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
  114. package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
  115. package/.framework/src/components/app-sidebar.tsx +50 -3
  116. package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
  117. package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
  118. package/.framework/src/components/kb/KBArticleList.tsx +557 -0
  119. package/.framework/src/components/layout/AppShell.tsx +54 -16
  120. package/.framework/src/components/layout/Header.tsx +50 -38
  121. package/.framework/src/components/layout/Layout.tsx +48 -32
  122. package/.framework/src/components/layout/Sidebar.tsx +167 -16
  123. package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
  124. package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
  125. package/.framework/src/components/runtime/DataFilters.tsx +78 -1
  126. package/.framework/src/components/runtime/DataHeader.tsx +32 -29
  127. package/.framework/src/components/runtime/DataListPage.tsx +161 -2
  128. package/.framework/src/components/runtime/DataStats.tsx +48 -1
  129. package/.framework/src/components/runtime/DataTable.tsx +153 -1
  130. package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
  131. package/.framework/src/components/runtime/index.ts +16 -9
  132. package/.framework/src/components/search-form.tsx +33 -1
  133. package/.framework/src/components/shared/AgentView.tsx +48 -51
  134. package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
  135. package/.framework/src/components/shared/InviteManager.tsx +113 -52
  136. package/.framework/src/components/shared/MemberList.tsx +182 -0
  137. package/.framework/src/components/shared/SchemaFields.tsx +96 -78
  138. package/.framework/src/components/ui/DataTable.tsx +86 -56
  139. package/.framework/src/components/ui/Form.tsx +188 -109
  140. package/.framework/src/components/ui/ItemCard.tsx +86 -58
  141. package/.framework/src/components/ui/ItemListView.tsx +88 -61
  142. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
  143. package/.framework/src/components/ui/Modal.tsx +81 -4
  144. package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
  145. package/.framework/src/components/ui/accordion.tsx +97 -5
  146. package/.framework/src/components/ui/alert-dialog.tsx +225 -13
  147. package/.framework/src/components/ui/alert.tsx +113 -6
  148. package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
  149. package/.framework/src/components/ui/avatar.tsx +129 -7
  150. package/.framework/src/components/ui/badge.tsx +65 -3
  151. package/.framework/src/components/ui/breadcrumb.tsx +145 -8
  152. package/.framework/src/components/ui/button-group.tsx +81 -4
  153. package/.framework/src/components/ui/button.tsx +49 -2
  154. package/.framework/src/components/ui/calendar.tsx +65 -3
  155. package/.framework/src/components/ui/card.tsx +145 -8
  156. package/.framework/src/components/ui/carousel.tsx +129 -7
  157. package/.framework/src/components/ui/chart.tsx +161 -10
  158. package/.framework/src/components/ui/checkbox.tsx +49 -2
  159. package/.framework/src/components/ui/collapsible.tsx +81 -5
  160. package/.framework/src/components/ui/combobox.tsx +305 -20
  161. package/.framework/src/components/ui/command.tsx +177 -11
  162. package/.framework/src/components/ui/context-menu.tsx +273 -17
  163. package/.framework/src/components/ui/dialog.tsx +209 -27
  164. package/.framework/src/components/ui/direction.tsx +64 -4
  165. package/.framework/src/components/ui/drawer.tsx +193 -12
  166. package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
  167. package/.framework/src/components/ui/empty.tsx +145 -9
  168. package/.framework/src/components/ui/field.tsx +209 -14
  169. package/.framework/src/components/ui/hover-card.tsx +81 -4
  170. package/.framework/src/components/ui/input-group.tsx +162 -10
  171. package/.framework/src/components/ui/input-otp.tsx +98 -5
  172. package/.framework/src/components/ui/input.tsx +49 -2
  173. package/.framework/src/components/ui/item.tsx +225 -13
  174. package/.framework/src/components/ui/kbd.tsx +65 -3
  175. package/.framework/src/components/ui/label.tsx +49 -2
  176. package/.framework/src/components/ui/menubar.tsx +289 -17
  177. package/.framework/src/components/ui/native-select.tsx +97 -5
  178. package/.framework/src/components/ui/navigation-menu.tsx +177 -10
  179. package/.framework/src/components/ui/pagination.tsx +161 -9
  180. package/.framework/src/components/ui/popover.tsx +145 -8
  181. package/.framework/src/components/ui/progress.tsx +49 -2
  182. package/.framework/src/components/ui/radio-group.tsx +65 -3
  183. package/.framework/src/components/ui/resizable.tsx +82 -4
  184. package/.framework/src/components/ui/scroll-area.tsx +65 -3
  185. package/.framework/src/components/ui/select.tsx +193 -11
  186. package/.framework/src/components/ui/separator.tsx +49 -2
  187. package/.framework/src/components/ui/sheet.tsx +193 -11
  188. package/.framework/src/components/ui/sidebar.tsx +481 -38
  189. package/.framework/src/components/ui/skeleton.tsx +49 -2
  190. package/.framework/src/components/ui/slider.tsx +49 -2
  191. package/.framework/src/components/ui/sonner.tsx +49 -2
  192. package/.framework/src/components/ui/spinner.tsx +49 -2
  193. package/.framework/src/components/ui/switch.tsx +49 -2
  194. package/.framework/src/components/ui/table-primitives.tsx +160 -33
  195. package/.framework/src/components/ui/table.tsx +161 -9
  196. package/.framework/src/components/ui/tabs.tsx +113 -6
  197. package/.framework/src/components/ui/textarea.tsx +49 -2
  198. package/.framework/src/components/ui/toggle-group.tsx +81 -4
  199. package/.framework/src/components/ui/toggle.tsx +65 -3
  200. package/.framework/src/components/ui/tooltip.tsx +97 -5
  201. package/.framework/src/contexts/AppContext.tsx +129 -45
  202. package/.framework/src/contexts/AuthContext.tsx +187 -144
  203. package/.framework/src/hooks/use-mobile.ts +48 -2
  204. package/.framework/src/hooks/useApi.ts +208 -159
  205. package/.framework/src/hooks/useAppPath.ts +32 -23
  206. package/.framework/src/hooks/useApps.ts +51 -20
  207. package/.framework/src/hooks/useEntityList.ts +32 -78
  208. package/.framework/src/hooks/useEntityRecord.ts +35 -96
  209. package/.framework/src/hooks/useForm.ts +32 -92
  210. package/.framework/src/hooks/useListSchema.ts +49 -78
  211. package/.framework/src/hooks/useSchemaRecord.ts +114 -105
  212. package/.framework/src/lib/api.ts +195 -116
  213. package/.framework/src/lib/supabase.ts +98 -64
  214. package/.framework/src/lib/utils.ts +287 -151
  215. package/.framework/src/main.tsx +49 -3
  216. package/.framework/src/pages/DashboardPage.tsx +52 -29
  217. package/.framework/src/pages/NotFoundPage.tsx +32 -10
  218. package/.framework/src/pages/SetupPage.tsx +32 -12
  219. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
  220. package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
  221. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
  222. package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
  223. package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
  224. package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
  225. package/.framework/src/pages/admin/AppsPage.tsx +49 -2
  226. package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
  227. package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
  228. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
  229. package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
  230. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
  231. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
  232. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
  233. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
  234. package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
  235. package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
  236. package/.framework/src/pages/admin/LogsPage.tsx +422 -75
  237. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
  238. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
  239. package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
  240. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
  241. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
  242. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
  243. package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
  244. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
  245. package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
  246. package/.framework/src/pages/admin/RolesPage.tsx +171 -18
  247. package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
  248. package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
  249. package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
  250. package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
  251. package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
  252. package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
  253. package/.framework/src/pages/admin/TimersPage.tsx +48 -20
  254. package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
  255. package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
  256. package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
  257. package/.framework/src/pages/admin/TypesPage.tsx +48 -20
  258. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
  259. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
  260. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
  261. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
  262. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
  263. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
  264. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
  265. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
  266. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
  267. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  268. package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
  269. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
  270. package/.framework/src/pages/auth/LoginPage.tsx +50 -23
  271. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
  272. package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
  273. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
  274. package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
  275. package/.framework/src/types/auth.ts +128 -71
  276. package/.framework/src/types/types.ts +373 -157
  277. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
  278. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
  279. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
  280. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
  281. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
  282. package/docs/README.md +9 -130
  283. package/netlify.toml +5 -2
  284. package/package.json +13 -25
  285. package/scripts/kb-ingest-docs.ts +203 -0
  286. package/spine.config.json +65 -4
  287. package/.framework/migrations/001_schema.sql +0 -425
  288. package/.framework/migrations/002_rls_and_functions.sql +0 -763
  289. package/.framework/migrations/004_enhancements.sql +0 -43
  290. package/.framework/migrations/005_auth_user_trigger.sql +0 -105
  291. package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
  292. package/.framework/migrations/016_invites.sql +0 -27
  293. package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
  294. package/.framework/migrations/018_apps_required_roles.sql +0 -17
  295. package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
  296. package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
  297. package/.framework/migrations/021_app_domains.sql +0 -112
  298. package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
  299. package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
  300. package/.framework/migrations/024_messages_account_id.sql +0 -9
  301. package/.framework/migrations/025_retype_threads_messages.sql +0 -240
  302. package/.framework/migrations/026_fix_rls_policies.sql +0 -47
  303. package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
  304. package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
  305. package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
  306. package/.framework/migrations/030_messages_updated_by.sql +0 -6
  307. package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
  308. package/docs/APPS.md +0 -232
  309. package/docs/ARCHITECTURE.md +0 -246
  310. package/docs/INSTALL.md +0 -155
  311. package/docs/design-schema-spec.md +0 -1837
  312. package/docs/dev-guides/01-create-an-app.md +0 -183
  313. package/docs/dev-guides/02-create-a-function.md +0 -178
  314. package/docs/dev-guides/03-create-a-component.md +0 -178
  315. package/docs/dev-guides/04-webhook-handlers.md +0 -129
  316. package/docs/dev-guides/05-testing.md +0 -168
  317. package/docs/dev-guides/README.md +0 -40
  318. package/docs/npm-packages-plan.md +0 -288
  319. package/docs/spine-core--api-reference.md +0 -822
@@ -1,31 +1,3 @@
1
- /**
2
- * @module roles
3
- * @audience core-contributor
4
- * @layer api-handler
5
- * @stability stable
6
- *
7
- * CRUD API for the `roles` table. Roles define permission sets (`permissions`
8
- * JSONB) that are assigned to people within an account.
9
- *
10
- * **Routed by:** `GET/POST/PATCH/DELETE /.netlify/functions/roles`
11
- *
12
- * **Authorization model:**
13
- * - All reads use `ctx.db` (RLS-scoped). System admins see raw records;
14
- * others get field-level sanitization via `sanitizeRecordData`.
15
- * - `create`: requires system admin OR first-surface `canCreate` permission.
16
- * Creating a role with `slug === 'system_admin'` is system-admin-only.
17
- * - `update` / `remove`: require authenticated principal. RLS controls row
18
- * access; field-level permissions validated via `validateUpdatePermissions`.
19
- * - Slug uniqueness is enforced per-app: checked against `adminDb`.
20
- *
21
- * INVARIANT: `system_admin` role slug can only be created by system admins.
22
- * INVARIANT: soft delete only — roles are set to `is_active = false`.
23
- *
24
- * @seeAlso middleware.ts (createHandler)
25
- * @seeAlso permissions.ts (PermissionEngine, sanitizeRecordData)
26
- * @seeAlso audit.ts (emitLog for role.created / role.updated / role.deleted)
27
- */
28
-
29
1
  import { createHandler } from './_shared/middleware'
30
2
  import { adminDb } from './_shared/db'
31
3
  import { emitLog } from './_shared/audit'
@@ -33,27 +5,30 @@ import { PermissionEngine, sanitizeRecordData } from './_shared/permissions'
33
5
 
34
6
  const permissions = PermissionEngine as any
35
7
 
36
- // ─── HANDLERS ─────────────────────────────────────────────────────────────────
37
-
38
- // ─── CHUNK_START: ROLES_LIST ──────────────────────────────────────────────
39
- /**
40
- * @chunk-id ROLES_LIST_1_0_0
41
- * @version 1.0.0
42
- * @hash b643852233c87c20abd7d62b3f51be9ba7f0f2a4ff02154be239ceef6184811b
43
- * @macro Roles List Handler
44
- * @micro Lists active roles with filtering and permission-based sanitization
45
- * @inputs ctx: CoreContext — Request context with principal and database
46
- * @inputs _body: any — Request body (unused for GET)
47
- * @outputs Array of role records with app join, sanitized for non-admins
48
- * @depends-on [createHandler, PermissionEngine, sanitizeRecordData]
49
- * @depended-by [Netlify function routing]
50
- * @side-effects [DB queries, permission sanitization]
51
- * @tags roles, list, crud, pagination, permissions
52
- */
8
+
9
+
10
+
11
+
12
+
13
+
14
+ // CIL[BEGIN chunk_id="roles_module_header_1783932909" type="module_header" identity="module_header" parent="none"]
15
+ // CIL[DOC-MACRO purpose="Lists roles with filtering and permission-based sanitization"]
16
+ // CIL[DOC-RESPONSIBILITY responsibility="Handle role listing with app and system filters"]
17
+ // CIL[DOC-CONTEXT module="roles" layer="api-handler" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
18
+ // CIL[DOC-CONTRACT inputs="ctx, _body" outputs="Array of role records" errors="Throws on DB errors" side_effects="Database queries, permission checks"]
19
+ // CIL[DOC-MICRO logic_summary="Filters roles, applies permission sanitization for non-admins" notable_decisions="[]"]
20
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
21
+ // CIL[DOC-STABILITY stability="stable"]
22
+ // CIL[DOC-AUDIENCE audience="developer"]
23
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, \."]
24
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
25
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
26
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
27
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
28
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
53
29
  export const list = createHandler(async (ctx, _body) => {
54
30
  const { app_id, is_system, limit = '50', offset = '0' } = ctx.query || {}
55
31
 
56
- // RLS automatically filters to accessible roles
57
32
  let query = ctx.db
58
33
  .from('roles')
59
34
  .select(`
@@ -79,12 +54,10 @@ export const list = createHandler(async (ctx, _body) => {
79
54
 
80
55
  if (err) throw err
81
56
 
82
- // System admin sees everything without additional filtering
83
57
  if (permissions.isSystemAdmin(ctx)) {
84
58
  return data
85
59
  }
86
60
 
87
- // Filter each role based on field-level permissions
88
61
  const filteredData = []
89
62
  for (const role of data || []) {
90
63
  const roleWithType = { ...role, type: 'role' }
@@ -94,23 +67,21 @@ export const list = createHandler(async (ctx, _body) => {
94
67
 
95
68
  return filteredData
96
69
  })
97
- // ─── CHUNK_END: ROLES_LIST ────────────────────────────────────────────────
98
-
99
- // ─── CHUNK_START: ROLES_GET ──────────────────────────────────────────────
100
- /**
101
- * @chunk-id ROLES_GET_1_0_0
102
- * @version 1.0.0
103
- * @hash 94607bad8b9ff929233ce1b29b6563062d439365ed0413726c5a8d8d0f58474b
104
- * @macro Role Get Handler
105
- * @micro Returns single role record with joins and permission sanitization
106
- * @inputs ctx: CoreContext — Request context with principal and database
107
- * @inputs _body: any — Request body (unused for GET)
108
- * @outputs Sanitized role record with app join
109
- * @depends-on [createHandler, sanitizeRecordData]
110
- * @depended-by [Netlify function routing]
111
- * @side-effects [DB single row query, permission sanitization]
112
- * @tags roles, get, crud, single-record, permissions
113
- */
70
+ // CIL[END chunk_id="roles_module_header_1783932909"]
71
+ // CIL[BEGIN chunk_id="roles_get_1783932909" type="function" identity="get" parent="none"]
72
+ // CIL[DOC-MACRO purpose="Retrieves single role by ID with sanitization"]
73
+ // CIL[DOC-RESPONSIBILITY responsibility="Handle individual role retrieval"]
74
+ // CIL[DOC-CONTEXT module="roles" layer="api-handler" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
75
+ // CIL[DOC-CONTRACT inputs="none" outputs="Single role record" errors="Throws if ID missing or DB error" side_effects="Database query, permission sanitization"]
76
+ // CIL[DOC-MICRO logic_summary="Fetches role by ID, applies permission sanitization" notable_decisions="[]"]
77
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
78
+ // CIL[DOC-STABILITY stability="stable"]
79
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/RolesPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
80
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
81
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
82
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
83
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
84
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
114
85
  export const get = createHandler(async (ctx, _body) => {
115
86
  const { id } = ctx.query || {}
116
87
 
@@ -118,7 +89,6 @@ export const get = createHandler(async (ctx, _body) => {
118
89
  throw new Error('Role ID is required')
119
90
  }
120
91
 
121
- // RLS ensures user can only access roles in their accessible accounts
122
92
  const { data, error: err } = await ctx.db
123
93
  .from('roles')
124
94
  .select(`
@@ -131,27 +101,24 @@ export const get = createHandler(async (ctx, _body) => {
131
101
 
132
102
  if (err) throw err
133
103
 
134
- // Return sanitized data based on field-level permissions
135
104
  const roleWithType = { ...data, type: 'role' }
136
105
  return await sanitizeRecordData(ctx, roleWithType, 'role')
137
106
  })
138
- // ─── CHUNK_END: ROLES_GET ────────────────────────────────────────────────
139
-
140
- // ─── CHUNK_START: ROLES_CREATE ──────────────────────────────────────────────
141
- /**
142
- * @chunk-id ROLES_CREATE_1_0_0
143
- * @version 1.0.0
144
- * @hash 7f6646fee88ed72d997eb710feb3778aad114f3a96819390166c8ecbc6eeaa0e
145
- * @macro Role Create Handler
146
- * @micro Creates role with permission validation and audit logging
147
- * @inputs ctx: CoreContext — Request context with principal and database
148
- * @inputs body: object — Role data including slug, name, and optional fields
149
- * @outputs Inserted role record
150
- * @depends-on [createHandler, PermissionEngine, adminDb, emitLog]
151
- * @depended-by [Netlify function routing]
152
- * @side-effects [DB insert, permission validation, audit logging]
153
- * @tags roles, create, crud, permissions, audit
154
- */
107
+ // CIL[END chunk_id="roles_get_1783932909"]
108
+ // CIL[BEGIN chunk_id="roles_create_1783932909" type="function" identity="create" parent="none"]
109
+ // CIL[DOC-MACRO purpose="Creates new role with permission validation"]
110
+ // CIL[DOC-RESPONSIBILITY responsibility="Handle role creation with security checks"]
111
+ // CIL[DOC-CONTEXT module="roles" layer="api-handler" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
112
+ // CIL[DOC-CONTRACT inputs="none" outputs="Created role record" errors="Throws on validation, permission, or DB errors" side_effects="Database insert, audit logging"]
113
+ // CIL[DOC-MICRO logic_summary="Validates permissions, checks uniqueness, creates role" notable_decisions="[]"]
114
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
115
+ // CIL[DOC-STABILITY stability="stable"]
116
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/RolesPage.tsx, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, \."]
117
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
118
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
119
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
120
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
121
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
155
122
  export const create = createHandler(async (ctx, body) => {
156
123
  const { app_id, slug, name, description, permissions: rolePermissions, is_system } = body
157
124
 
@@ -163,12 +130,10 @@ export const create = createHandler(async (ctx, body) => {
163
130
  throw new Error('User context (person and account) required')
164
131
  }
165
132
 
166
- // Guard: system_admin role can only be created by system admins
167
133
  if (slug === 'system_admin' && !permissions.isSystemAdmin(ctx)) {
168
134
  throw new Error('system_admin role can only be created by system administrators')
169
135
  }
170
136
 
171
- // Check create permissions using PermissionEngine
172
137
  if (!permissions.isSystemAdmin(ctx)) {
173
138
  const perms = await permissions.resolveFirstSurfacePermissions(
174
139
  ctx.principal.id,
@@ -182,7 +147,6 @@ export const create = createHandler(async (ctx, body) => {
182
147
  }
183
148
  }
184
149
 
185
- // Check if slug is unique within app using service role (validating uniqueness is a system concern)
186
150
  let query = adminDb
187
151
  .from('roles')
188
152
  .select('id')
@@ -200,7 +164,6 @@ export const create = createHandler(async (ctx, body) => {
200
164
  throw new Error('Role slug already exists for this app')
201
165
  }
202
166
 
203
- // Insert with RLS enforcement
204
167
  const { data, error: err } = await ctx.db
205
168
  .from('roles')
206
169
  .insert({
@@ -221,23 +184,21 @@ export const create = createHandler(async (ctx, body) => {
221
184
 
222
185
  return data
223
186
  })
224
- // ─── CHUNK_END: ROLES_CREATE ────────────────────────────────────────────────
225
-
226
- // ─── CHUNK_START: ROLES_UPDATE ──────────────────────────────────────────────
227
- /**
228
- * @chunk-id ROLES_UPDATE_1_0_0
229
- * @version 1.0.0
230
- * @hash 19803de116b38af5e27bf542ca642228f4661bbf428a4846ed565d0667767580
231
- * @macro Role Update Handler
232
- * @micro Updates role with field-level permission validation and audit logging
233
- * @inputs ctx: CoreContext — Request context with principal and database
234
- * @inputs body: object — Role updates including id and updatable fields
235
- * @outputs Updated role record
236
- * @depends-on [createHandler, PermissionEngine, emitLog]
237
- * @depended-by [Netlify function routing]
238
- * @side-effects [DB update, permission validation, audit logging]
239
- * @tags roles, update, crud, permissions, audit
240
- */
187
+ // CIL[END chunk_id="roles_create_1783932909"]
188
+ // CIL[BEGIN chunk_id="roles_update_1783932909" type="function" identity="update" parent="none"]
189
+ // CIL[DOC-MACRO purpose="Updates role with field-level permission validation"]
190
+ // CIL[DOC-RESPONSIBILITY responsibility="Handle role updates with security validation"]
191
+ // CIL[DOC-CONTEXT module="roles" layer="api-handler" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
192
+ // CIL[DOC-CONTRACT inputs="none" outputs="Updated role record" errors="Throws on validation, permission, or DB errors" side_effects="Database update, audit logging"]
193
+ // CIL[DOC-MICRO logic_summary="Validates update permissions, applies changes with audit trail" notable_decisions="[]"]
194
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
195
+ // CIL[DOC-STABILITY stability="stable"]
196
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/RolesPage.tsx, .framework/functions/_shared/principal.ts, \."]
197
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
198
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
199
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
200
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
201
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
241
202
  export const update = createHandler(async (ctx, body) => {
242
203
  const { id, ...updates } = body
243
204
 
@@ -249,7 +210,6 @@ export const update = createHandler(async (ctx, body) => {
249
210
  throw new Error('User context (person and account) required')
250
211
  }
251
212
 
252
- // Get current state for audit via RLS
253
213
  const { data: current, error: fetchErr } = await ctx.db
254
214
  .from('roles')
255
215
  .select('*')
@@ -260,7 +220,6 @@ export const update = createHandler(async (ctx, body) => {
260
220
  throw new Error('Role not found or access denied')
261
221
  }
262
222
 
263
- // Validate field-level permissions
264
223
  const fieldValidation = await permissions.validateUpdatePermissions(
265
224
  ctx,
266
225
  updates,
@@ -272,7 +231,6 @@ export const update = createHandler(async (ctx, body) => {
272
231
  throw new Error(fieldValidation.error)
273
232
  }
274
233
 
275
- // Update via RLS
276
234
  const { data, error: err } = await ctx.db
277
235
  .from('roles')
278
236
  .update({
@@ -289,23 +247,21 @@ export const update = createHandler(async (ctx, body) => {
289
247
 
290
248
  return data
291
249
  })
292
- // ─── CHUNK_END: ROLES_UPDATE ────────────────────────────────────────────────
293
-
294
- // ─── CHUNK_START: ROLES_REMOVE ──────────────────────────────────────────────
295
- /**
296
- * @chunk-id ROLES_REMOVE_1_0_0
297
- * @version 1.0.0
298
- * @hash 9194c78a60e7d12b7acf6981bbc56afdfbe9e922c52739394240fca5adcfa069
299
- * @macro Role Remove Handler
300
- * @micro Soft-deletes role with audit logging
301
- * @inputs ctx: CoreContext — Request context with principal and database
302
- * @inputs body: object — Role id for deletion
303
- * @outputs Updated role record with is_active: false
304
- * @depends-on [createHandler, emitLog]
305
- * @depended-by [Netlify function routing]
306
- * @side-effects [DB soft delete, audit logging]
307
- * @tags roles, remove, soft-delete, audit
308
- */
250
+ // CIL[END chunk_id="roles_update_1783932909"]
251
+ // CIL[BEGIN chunk_id="roles_remove_1783932909" type="function" identity="remove" parent="none"]
252
+ // CIL[DOC-MACRO purpose="Soft deletes role by setting is_active to false"]
253
+ // CIL[DOC-RESPONSIBILITY responsibility="Handle role deletion with audit trail"]
254
+ // CIL[DOC-CONTEXT module="roles" layer="api-handler" related_files="[]"]
255
+ // CIL[DOC-CONTRACT inputs="none" outputs="Deactivated role record" errors="Throws on validation or DB errors" side_effects="Database update, audit logging"]
256
+ // CIL[DOC-MICRO logic_summary="Soft deletes role, maintains audit trail" notable_decisions="[]"]
257
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
258
+ // CIL[DOC-STABILITY stability="stable"]
259
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
260
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
261
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
262
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
263
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
264
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
309
265
  export const remove = createHandler(async (ctx, body) => {
310
266
  const { id } = body
311
267
 
@@ -317,7 +273,6 @@ export const remove = createHandler(async (ctx, body) => {
317
273
  throw new Error('User context (person and account) required')
318
274
  }
319
275
 
320
- // Verify access via RLS fetch
321
276
  const { data: current, error: fetchErr } = await ctx.db
322
277
  .from('roles')
323
278
  .select('*')
@@ -328,7 +283,6 @@ export const remove = createHandler(async (ctx, body) => {
328
283
  throw new Error('Role not found or access denied')
329
284
  }
330
285
 
331
- // Soft delete via RLS
332
286
  const { data, error: err } = await ctx.db
333
287
  .from('roles')
334
288
  .update({
@@ -345,25 +299,21 @@ export const remove = createHandler(async (ctx, body) => {
345
299
 
346
300
  return data
347
301
  })
348
- // ─── CHUNK_END: ROLES_REMOVE ────────────────────────────────────────────────
349
-
350
- // ─── MAIN HANDLER ────────────────────────────────────────────────────────────
351
-
352
- // ─── CHUNK_START: ROLES_HANDLER ──────────────────────────────────────────────
353
- /**
354
- * @chunk-id ROLES_HANDLER_1_0_0
355
- * @version 1.0.0
356
- * @hash 14c00f276a22287ed65c019efe327cbb513f860a408191e299864b05c641833c
357
- * @macro Roles Router
358
- * @micro Routes HTTP methods to appropriate role handlers
359
- * @inputs ctx: CoreContext — Request context with principal and database
360
- * @inputs body: any — Request body for POST/PATCH/DELETE operations
361
- * @outputs Varies — Depends on routed handler (list/get/create/update/remove)
362
- * @depends-on [createHandler, list, get, create, update, remove]
363
- * @depended-by [Netlify function routing]
364
- * @side-effects [Delegates to appropriate handler]
365
- * @tags roles, router, crud, netlify-function
366
- */
302
+ // CIL[END chunk_id="roles_remove_1783932909"]
303
+ // CIL[BEGIN chunk_id="roles_handler_1783932909" type="function" identity="handler" parent="none"]
304
+ // CIL[DOC-MACRO purpose="Routes HTTP methods to appropriate role handlers"]
305
+ // CIL[DOC-RESPONSIBILITY responsibility="Handle request routing for role CRUD operations"]
306
+ // CIL[DOC-CONTEXT module="roles" layer="api-handler" related_files="[]"]
307
+ // CIL[DOC-CONTRACT inputs="none" outputs="Varies by handler" errors="Throws on unsupported methods" side_effects="Delegates to appropriate handler"]
308
+ // CIL[DOC-MICRO logic_summary="Routes based on HTTP method, delegates to CRUD handlers" notable_decisions="[]"]
309
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
310
+ // CIL[DOC-STABILITY stability="stable"]
311
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
312
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
313
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
314
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
315
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
316
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
367
317
  export const handler = createHandler(async (ctx, body) => {
368
318
  const method = ctx.query?.method || 'GET'
369
319
 
@@ -384,4 +334,4 @@ export const handler = createHandler(async (ctx, body) => {
384
334
  throw new Error(`Unsupported method: ${method}`)
385
335
  }
386
336
  })
387
- // ─── CHUNK_END: ROLES_HANDLER ────────────────────────────────────────────────
337
+ // CIL[END chunk_id="roles_handler_1783932909"]