spine-framework 0.3.145 → 0.4.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 (451) hide show
  1. package/.env.example +76 -0
  2. package/.framework/.spine-manifest.json +19 -0
  3. package/.framework/cli/commands/agents.ts +61 -33
  4. package/.framework/cli/commands/auth.ts +60 -28
  5. package/.framework/cli/commands/create-app.ts +212 -80
  6. package/.framework/cli/commands/dev.ts +184 -68
  7. package/.framework/cli/commands/doctor.ts +324 -152
  8. package/.framework/cli/commands/generate.ts +119 -68
  9. package/.framework/cli/commands/init.ts +141 -242
  10. package/.framework/cli/commands/install-app.ts +1336 -314
  11. package/.framework/cli/commands/items.ts +31 -29
  12. package/.framework/cli/commands/migrate.ts +299 -156
  13. package/.framework/cli/commands/migrations.ts +62 -30
  14. package/.framework/cli/commands/pipelines.ts +31 -29
  15. package/.framework/cli/commands/status.ts +105 -45
  16. package/.framework/cli/commands/system.ts +47 -42
  17. package/.framework/cli/commands/test.ts +161 -102
  18. package/.framework/cli/commands/upgrade.ts +260 -0
  19. package/.framework/cli/commands/validate-app.ts +517 -161
  20. package/.framework/cli/context.ts +117 -85
  21. package/.framework/cli/env-loader.ts +74 -43
  22. package/.framework/cli/index.ts +70 -46
  23. package/.framework/cli/lib/project-files.ts +404 -0
  24. package/.framework/docs/guides/testing-guide.md +1 -1
  25. package/.framework/docs/runtime-types.md +72 -72
  26. package/.framework/functions/_shared/access.ts +84 -0
  27. package/.framework/functions/_shared/agent-runner.ts +5051 -1026
  28. package/.framework/functions/_shared/app-manifest.ts +214 -94
  29. package/.framework/functions/_shared/ast.ts +214 -0
  30. package/.framework/functions/_shared/audit.ts +91 -55
  31. package/.framework/functions/_shared/cil.ts +368 -127
  32. package/.framework/functions/_shared/db.ts +337 -68
  33. package/.framework/functions/_shared/funnel.ts +228 -0
  34. package/.framework/functions/_shared/geo.ts +105 -0
  35. package/.framework/functions/_shared/hash-api-key.ts +94 -17
  36. package/.framework/functions/_shared/index.ts +22 -224
  37. package/.framework/functions/_shared/kb.ts +832 -58
  38. package/.framework/functions/_shared/llm.ts +118 -18
  39. package/.framework/functions/_shared/logging.ts +317 -19
  40. package/.framework/functions/_shared/middleware.ts +701 -131
  41. package/.framework/functions/_shared/notify.ts +70 -0
  42. package/.framework/functions/_shared/outcomes.ts +34 -19
  43. package/.framework/functions/_shared/permissions.ts +501 -315
  44. package/.framework/functions/_shared/pipeline-runner.ts +704 -155
  45. package/.framework/functions/_shared/principal.ts +436 -263
  46. package/.framework/functions/_shared/rate-limit.ts +233 -0
  47. package/.framework/functions/_shared/resolve-credentials.ts +86 -19
  48. package/.framework/functions/_shared/resolve-ids.ts +203 -139
  49. package/.framework/functions/_shared/retry-deliveries.ts +51 -16
  50. package/.framework/functions/_shared/schema-utils.ts +602 -521
  51. package/.framework/functions/_shared/security.ts +345 -0
  52. package/.framework/functions/_shared/testing.ts +197 -172
  53. package/.framework/functions/_shared/tracing.ts +351 -21
  54. package/.framework/functions/_shared/trigger-engine.ts +425 -136
  55. package/.framework/functions/_shared/webhook-registration.ts +71 -70
  56. package/.framework/functions/_shared/webhook-registry.ts +126 -83
  57. package/.framework/functions/account-nodes.ts +30 -30
  58. package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
  59. package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
  60. package/.framework/functions/adapters/openai-outbound.ts +15 -16
  61. package/.framework/functions/admin-data.ts +596 -173
  62. package/.framework/functions/admin-funnel.ts +64 -60
  63. package/.framework/functions/admin-install-funnel.ts +84 -66
  64. package/.framework/functions/admin-signals.ts +69 -51
  65. package/.framework/functions/ai-agents.ts +431 -106
  66. package/.framework/functions/ai-interactions.ts +186 -112
  67. package/.framework/functions/api-keys.ts +107 -107
  68. package/.framework/functions/apps.ts +154 -136
  69. package/.framework/functions/auth.ts +83 -65
  70. package/.framework/functions/cil-agent-ingest.ts +189 -232
  71. package/.framework/functions/cil-agent.ts +433 -177
  72. package/.framework/functions/cil-callmap.ts +642 -430
  73. package/.framework/functions/cil-config.ts +139 -135
  74. package/.framework/functions/cil-context.ts +214 -127
  75. package/.framework/functions/cil-doc.ts +587 -458
  76. package/.framework/functions/cil-embeddings.ts +453 -364
  77. package/.framework/functions/cil-graph.ts +427 -142
  78. package/.framework/functions/cil-ingest.ts +1418 -1154
  79. package/.framework/functions/cil-pipeline.ts +276 -21
  80. package/.framework/functions/cil-project.ts +659 -132
  81. package/.framework/functions/cil-validate.ts +198 -164
  82. package/.framework/functions/debug-auth.ts +57 -55
  83. package/.framework/functions/deliveries.ts +80 -21
  84. package/.framework/functions/embeddings.ts +1023 -318
  85. package/.framework/functions/eval-harness.ts +146 -108
  86. package/.framework/functions/integration-outbound.ts +205 -75
  87. package/.framework/functions/integration-routes.ts +128 -23
  88. package/.framework/functions/integrations.ts +125 -100
  89. package/.framework/functions/invites.ts +1095 -460
  90. package/.framework/functions/item-progress.ts +158 -102
  91. package/.framework/functions/kb.ts +34 -10
  92. package/.framework/functions/logs.ts +133 -133
  93. package/.framework/functions/observability.ts +152 -122
  94. package/.framework/functions/pipeline-executions.ts +147 -132
  95. package/.framework/functions/pipelines.ts +134 -119
  96. package/.framework/functions/prompt-configs.ts +96 -80
  97. package/.framework/functions/roles.ts +112 -82
  98. package/.framework/functions/security.ts +450 -0
  99. package/.framework/functions/system-cron.ts +117 -80
  100. package/.framework/functions/system.ts +158 -98
  101. package/.framework/functions/tests.ts +29 -29
  102. package/.framework/functions/timers.ts +94 -95
  103. package/.framework/functions/trigger-scheduler.ts +10 -0
  104. package/.framework/functions/triggers.ts +179 -149
  105. package/.framework/functions/types.ts +137 -125
  106. package/.framework/mcp/index.ts +133 -0
  107. package/.framework/mcp/load-env.ts +60 -0
  108. package/.framework/mcp/shared/app-manifest.ts +275 -0
  109. package/.framework/mcp/shared/db.ts +477 -0
  110. package/.framework/mcp/shared/kb.ts +118 -0
  111. package/.framework/mcp/tools/architect.ts +431 -0
  112. package/.framework/mcp/tools/cil/context.ts +345 -0
  113. package/.framework/mcp/tools/cil/graph.ts +242 -0
  114. package/.framework/mcp/tools/cil/ingest.ts +1217 -0
  115. package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
  116. package/.framework/mcp/tools/cil/pipeline.ts +767 -0
  117. package/.framework/mcp/tools/cil/project.ts +791 -0
  118. package/.framework/mcp/tools/cil/retrieval.ts +336 -0
  119. package/.framework/mcp/tools/cil/search-core.ts +454 -0
  120. package/.framework/mcp/tools/cil/search.ts +97 -0
  121. package/.framework/mcp/tools/cil/suggest.ts +186 -0
  122. package/.framework/mcp/tools/cil/validate.ts +1369 -0
  123. package/.framework/mcp/tools/kb/delete.ts +139 -0
  124. package/.framework/mcp/tools/kb/index.ts +52 -0
  125. package/.framework/mcp/tools/kb/ingest.ts +84 -0
  126. package/.framework/mcp/tools/kb/list-types.ts +102 -0
  127. package/.framework/mcp/tools/kb/publish.ts +100 -0
  128. package/.framework/mcp/tools/kb/reindex.ts +86 -0
  129. package/.framework/mcp/tools/kb/revoke.ts +85 -0
  130. package/.framework/mcp/tools/kb/search.ts +101 -0
  131. package/.framework/mcp/tools/kb/upsert.ts +125 -0
  132. package/.framework/mcp/tools/observability.ts +510 -0
  133. package/.framework/migrations/001_core_schema.sql +15 -0
  134. package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
  135. package/.framework/migrations/003_core_system_data.sql +16 -1
  136. package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
  137. package/.framework/migrations/005_core_observability.sql +17 -1
  138. package/.framework/migrations/006_security_hardening_rls.sql +15 -0
  139. package/.framework/migrations/007_kb_article_list.sql +17 -1
  140. package/.framework/migrations/008_items_target.sql +15 -0
  141. package/.framework/migrations/009_roles_slug_unique.sql +15 -0
  142. package/.framework/migrations/010_auth_user_trigger.sql +15 -0
  143. package/.framework/migrations/011_spine_system_account.sql +16 -0
  144. package/.framework/migrations/012_service_role_grants.sql +16 -0
  145. package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
  146. package/.framework/migrations/014_apps_required_roles.sql +16 -0
  147. package/.framework/migrations/015_types_kind_slug_unique.sql +15 -0
  148. package/.framework/migrations/016_cil_types.sql +281 -0
  149. package/.framework/migrations/017_cil_stable_ids.sql +37 -0
  150. package/.framework/migrations/018_runtime_tables.sql +129 -0
  151. package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
  152. package/.framework/migrations/020_schema_reconciliation.sql +67 -0
  153. package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
  154. package/.framework/migrations/032_cil_status_migration.sql +73 -0
  155. package/.framework/migrations/033_cil_versioning.sql +73 -0
  156. package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
  157. package/.framework/migrations/035_rate_limits.sql +55 -0
  158. package/.framework/migrations/036_demo_record_flags.sql +72 -0
  159. package/.framework/migrations/037_kb_types_canonical.sql +244 -0
  160. package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
  161. package/.framework/migrations/042_registration_hierarchy.sql +309 -0
  162. package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
  163. package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
  164. package/.framework/migrations/045_security_critical_rls.sql +139 -0
  165. package/.framework/migrations/046_security_missing_rls.sql +79 -0
  166. package/.framework/migrations/047_people_updated_by.sql +27 -0
  167. package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
  168. package/.framework/migrations/049_security_blocklist.sql +148 -0
  169. package/.framework/migrations/050_notifications.sql +49 -0
  170. package/.framework/migrations/051_message_agent_fields.sql +74 -0
  171. package/.framework/migrations/052_registration_security.sql +421 -0
  172. package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
  173. package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
  174. package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
  175. package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
  176. package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
  177. package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
  178. package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
  179. package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
  180. package/.framework/migrations/061_fk_dedup.sql +32 -0
  181. package/.framework/public/spine-logo.svg +10 -3
  182. package/.framework/scripts/app-install-cli.ts +190 -93
  183. package/.framework/scripts/assemble-frontend.sh +127 -44
  184. package/.framework/scripts/assemble-functions.sh +128 -30
  185. package/.framework/scripts/boundary-check.sh +6 -2
  186. package/.framework/scripts/build-manifest.sh +24 -68
  187. package/.framework/scripts/check-core-integrity.sh +15 -76
  188. package/.framework/scripts/checksum-manifest.mts +343 -0
  189. package/.framework/scripts/cil-migrate-markers.ts +403 -0
  190. package/.framework/scripts/fix-cil-markers.mjs +176 -0
  191. package/.framework/scripts/verify-integrity.sh +21 -57
  192. package/.framework/scripts/verify-manifest.mts +305 -0
  193. package/.framework/seeds/types/funnel_signal_use.json +74 -21
  194. package/.framework/seeds/types/spine_instance.json +73 -21
  195. package/.framework/src/App.tsx +118 -72
  196. package/.framework/src/apps/admin/index.tsx +855 -58
  197. package/.framework/src/components/AppWrapper.tsx +43 -45
  198. package/.framework/src/components/CustomAppLoader.tsx +160 -116
  199. package/.framework/src/components/admin/AdminListPage.tsx +46 -44
  200. package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
  201. package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
  202. package/.framework/src/components/admin/PageInstructions.tsx +98 -2
  203. package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
  204. package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
  205. package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
  206. package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
  207. package/.framework/src/components/app-sidebar.tsx +42 -45
  208. package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
  209. package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
  210. package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
  211. package/.framework/src/components/kb/KBArticleList.tsx +251 -10
  212. package/.framework/src/components/layout/AppShell.tsx +51 -45
  213. package/.framework/src/components/layout/Header.tsx +42 -43
  214. package/.framework/src/components/layout/Layout.tsx +46 -46
  215. package/.framework/src/components/layout/Sidebar.tsx +196 -96
  216. package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
  217. package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
  218. package/.framework/src/components/runtime/DataFilters.tsx +49 -74
  219. package/.framework/src/components/runtime/DataHeader.tsx +53 -32
  220. package/.framework/src/components/runtime/DataListPage.tsx +51 -155
  221. package/.framework/src/components/runtime/DataStats.tsx +66 -44
  222. package/.framework/src/components/runtime/DataTable.tsx +49 -149
  223. package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
  224. package/.framework/src/components/runtime/index.ts +119 -16
  225. package/.framework/src/components/search-form.tsx +46 -29
  226. package/.framework/src/components/shared/AgentView.tsx +65 -48
  227. package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
  228. package/.framework/src/components/shared/InviteManager.tsx +207 -97
  229. package/.framework/src/components/shared/MemberList.tsx +97 -0
  230. package/.framework/src/components/shared/SchemaFields.tsx +107 -86
  231. package/.framework/src/components/ui/DataTable.tsx +80 -68
  232. package/.framework/src/components/ui/Form.tsx +157 -146
  233. package/.framework/src/components/ui/ItemCard.tsx +74 -67
  234. package/.framework/src/components/ui/ItemListView.tsx +73 -68
  235. package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
  236. package/.framework/src/components/ui/Modal.tsx +78 -68
  237. package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
  238. package/.framework/src/components/ui/accordion.tsx +85 -86
  239. package/.framework/src/components/ui/alert-dialog.tsx +197 -184
  240. package/.framework/src/components/ui/alert.tsx +105 -94
  241. package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
  242. package/.framework/src/components/ui/avatar.tsx +122 -107
  243. package/.framework/src/components/ui/badge.tsx +60 -55
  244. package/.framework/src/components/ui/breadcrumb.tsx +127 -128
  245. package/.framework/src/components/ui/button-group.tsx +86 -72
  246. package/.framework/src/components/ui/button.tsx +71 -50
  247. package/.framework/src/components/ui/calendar.tsx +72 -57
  248. package/.framework/src/components/ui/card.tsx +136 -129
  249. package/.framework/src/components/ui/carousel.tsx +226 -107
  250. package/.framework/src/components/ui/chart.tsx +252 -147
  251. package/.framework/src/components/ui/checkbox.tsx +43 -44
  252. package/.framework/src/components/ui/collapsible.tsx +86 -71
  253. package/.framework/src/components/ui/combobox.tsx +282 -249
  254. package/.framework/src/components/ui/command.tsx +158 -146
  255. package/.framework/src/components/ui/context-menu.tsx +239 -240
  256. package/.framework/src/components/ui/dialog.tsx +174 -157
  257. package/.framework/src/components/ui/direction.tsx +72 -56
  258. package/.framework/src/components/ui/drawer.tsx +168 -169
  259. package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
  260. package/.framework/src/components/ui/empty.tsx +131 -120
  261. package/.framework/src/components/ui/field.tsx +205 -173
  262. package/.framework/src/components/ui/hover-card.tsx +71 -72
  263. package/.framework/src/components/ui/input-group.tsx +148 -133
  264. package/.framework/src/components/ui/input-otp.tsx +99 -86
  265. package/.framework/src/components/ui/input.tsx +43 -41
  266. package/.framework/src/components/ui/item.tsx +207 -185
  267. package/.framework/src/components/ui/kbd.tsx +57 -56
  268. package/.framework/src/components/ui/label.tsx +45 -41
  269. package/.framework/src/components/ui/menubar.tsx +268 -236
  270. package/.framework/src/components/ui/native-select.tsx +85 -86
  271. package/.framework/src/components/ui/navigation-menu.tsx +166 -156
  272. package/.framework/src/components/ui/pagination.tsx +131 -141
  273. package/.framework/src/components/ui/popover.tsx +125 -128
  274. package/.framework/src/components/ui/progress.tsx +47 -44
  275. package/.framework/src/components/ui/radio-group.tsx +60 -55
  276. package/.framework/src/components/ui/resizable.tsx +85 -72
  277. package/.framework/src/components/ui/scroll-area.tsx +57 -58
  278. package/.framework/src/components/ui/select.tsx +182 -169
  279. package/.framework/src/components/ui/separator.tsx +42 -43
  280. package/.framework/src/components/ui/sheet.tsx +170 -159
  281. package/.framework/src/components/ui/sidebar.tsx +395 -398
  282. package/.framework/src/components/ui/skeleton.tsx +42 -43
  283. package/.framework/src/components/ui/slider.tsx +61 -44
  284. package/.framework/src/components/ui/sonner.tsx +44 -44
  285. package/.framework/src/components/ui/spinner.tsx +47 -42
  286. package/.framework/src/components/ui/switch.tsx +56 -42
  287. package/.framework/src/components/ui/table-primitives.tsx +272 -132
  288. package/.framework/src/components/ui/table.tsx +140 -142
  289. package/.framework/src/components/ui/tabs.tsx +110 -93
  290. package/.framework/src/components/ui/textarea.tsx +43 -44
  291. package/.framework/src/components/ui/toggle-group.tsx +87 -71
  292. package/.framework/src/components/ui/toggle.tsx +56 -56
  293. package/.framework/src/components/ui/tooltip.tsx +99 -85
  294. package/.framework/src/contexts/AppContext.tsx +166 -114
  295. package/.framework/src/contexts/AuthContext.tsx +232 -137
  296. package/.framework/src/hooks/use-mobile.ts +43 -44
  297. package/.framework/src/hooks/useApi.ts +185 -172
  298. package/.framework/src/hooks/useAppPath.ts +31 -29
  299. package/.framework/src/hooks/useApps.ts +77 -42
  300. package/.framework/src/hooks/useEntityList.ts +66 -29
  301. package/.framework/src/hooks/useEntityRecord.ts +76 -32
  302. package/.framework/src/hooks/useForm.ts +62 -30
  303. package/.framework/src/hooks/useListSchema.ts +60 -43
  304. package/.framework/src/hooks/useSchemaRecord.ts +115 -95
  305. package/.framework/src/lib/api.ts +258 -134
  306. package/.framework/src/lib/registration.ts +181 -0
  307. package/.framework/src/lib/supabase.ts +118 -81
  308. package/.framework/src/lib/utils.ts +266 -266
  309. package/.framework/src/main.tsx +43 -44
  310. package/.framework/src/pages/DashboardPage.tsx +44 -43
  311. package/.framework/src/pages/NoAppPage.tsx +50 -0
  312. package/.framework/src/pages/NotFoundPage.tsx +32 -29
  313. package/.framework/src/pages/SetupPage.tsx +34 -33
  314. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
  315. package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
  316. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
  317. package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
  318. package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
  319. package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
  320. package/.framework/src/pages/admin/AppsPage.tsx +45 -42
  321. package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
  322. package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
  323. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
  324. package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
  325. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
  326. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
  327. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
  328. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
  329. package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
  330. package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
  331. package/.framework/src/pages/admin/LogsPage.tsx +87 -137
  332. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
  333. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
  334. package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
  335. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
  336. package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
  337. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
  338. package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
  339. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
  340. package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
  341. package/.framework/src/pages/admin/RolesPage.tsx +47 -164
  342. package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
  343. package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
  344. package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
  345. package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
  346. package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
  347. package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
  348. package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
  349. package/.framework/src/pages/admin/TimersPage.tsx +44 -42
  350. package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
  351. package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
  352. package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
  353. package/.framework/src/pages/admin/TypesPage.tsx +45 -42
  354. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
  355. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
  356. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
  357. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
  358. package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
  359. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
  360. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
  361. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
  362. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
  363. package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
  364. package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
  365. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
  366. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  367. package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
  368. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
  369. package/.framework/src/pages/auth/LoginPage.tsx +38 -32
  370. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
  371. package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
  372. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
  373. package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
  374. package/.framework/src/types/auth.ts +101 -93
  375. package/.framework/src/types/types.ts +283 -262
  376. package/.framework/templates/project.json +87 -0
  377. package/.framework/templates/spine.config.neutral.json +7 -0
  378. package/.framework/tests/api/api-surface.test.ts +381 -0
  379. package/.framework/tests/fixtures/seed.ts +427 -0
  380. package/.framework/tests/fixtures/teardown.ts +228 -0
  381. package/.framework/tests/reporter.ts +351 -0
  382. package/.framework/tests/setup.ts +135 -0
  383. package/.framework/tests/ui/ui-sweep.ts +278 -0
  384. package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
  385. package/.framework/tests/unit/agent-runner.test.ts +2389 -0
  386. package/.framework/tests/unit/ai-interactions.test.ts +81 -0
  387. package/.framework/tests/unit/app-manifest.test.ts +359 -0
  388. package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
  389. package/.framework/tests/unit/cil-determinism.test.ts +85 -0
  390. package/.framework/tests/unit/core-isolation.test.ts +153 -0
  391. package/.framework/tests/unit/funnel-signals.test.ts +135 -0
  392. package/.framework/tests/unit/install-app.test.ts +1759 -0
  393. package/.framework/tests/unit/invites-security.test.ts +572 -0
  394. package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
  395. package/.framework/tests/unit/kb-search.test.ts +119 -0
  396. package/.framework/tests/unit/migrate.test.ts +509 -0
  397. package/.framework/tests/unit/notify.test.ts +136 -0
  398. package/.framework/tests/unit/permissions.test.ts +269 -0
  399. package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
  400. package/.framework/tests/unit/principal-cache.test.ts +138 -0
  401. package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
  402. package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
  403. package/.framework/tests/unit/schema-utils.test.ts +225 -0
  404. package/.framework/tests/unit/trigger-engine.test.ts +513 -0
  405. package/.framework/tests/unit/validate-app.test.ts +527 -0
  406. package/README.md +34 -3
  407. package/bin/spine-framework.cjs +1 -0
  408. package/config/tailwind.config.cjs +7 -0
  409. package/config/tsconfig.functions.json +42 -0
  410. package/config/tsconfig.json +37 -9
  411. package/config/vite.config.ts +31 -2
  412. package/netlify.toml +31 -3
  413. package/package.json +46 -29
  414. package/scripts/assemble-frontend.sh +127 -44
  415. package/scripts/assemble-functions.sh +127 -29
  416. package/scripts/boundary-check.sh +6 -2
  417. package/scripts/build-manifest.sh +24 -68
  418. package/scripts/checksum-manifest.mts +345 -0
  419. package/scripts/dev-clean.sh +86 -0
  420. package/scripts/dev-netlify.sh +49 -0
  421. package/scripts/netlify-dev-wrapper.sh +2 -0
  422. package/scripts/verify-install.ts +358 -0
  423. package/scripts/verify-integrity.sh +21 -57
  424. package/scripts/verify-manifest.mts +305 -0
  425. package/templates/project/gitignore +45 -0
  426. package/{config → templates/project}/package-lock.json +22335 -9366
  427. package/vitest.config.ts +46 -0
  428. package/.framework/public/spine.config.json +0 -91
  429. package/config/deno.lock +0 -108
  430. package/config/tsconfig.node.tsbuildinfo +0 -1
  431. package/config/tsconfig.tsbuildinfo +0 -1
  432. package/config/vite.config.d.ts +0 -2
  433. package/custom/.devin/AGENT.md +0 -357
  434. package/custom/.devin/skills/install-app/SKILL.md +0 -39
  435. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
  436. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
  437. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
  438. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
  439. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
  440. package/custom/.devin/workflows/app-install.yaml +0 -83
  441. package/custom/README.md +0 -79
  442. package/docs/README.md +0 -15
  443. package/scripts/app-install-cli.ts +0 -286
  444. package/scripts/check-core-integrity.sh +0 -82
  445. package/scripts/ingest-chunks.cjs +0 -202
  446. package/scripts/kb-chunk-parser.cjs +0 -312
  447. package/scripts/kb-chunk-parser.ts +0 -330
  448. package/scripts/kb-ingest-docs.ts +0 -203
  449. package/scripts/load-test-app-install.ts +0 -484
  450. package/scripts/test-login.js +0 -33
  451. package/spine.config.json +0 -91
@@ -1,3 +1,27 @@
1
+ /**
2
+ * @module admin-data
3
+ * @audience internal
4
+ * @layer app-specific
5
+ * @stability stable
6
+ *
7
+ * This module handles administrative data operations within the system, providing essential functionalities for managing records and permissions. It serves as an API handler for various administrative actions, ensuring that only authorized users can perform updates and access sensitive data. INVARIANT: Only users with system admin privileges can execute these operations.
8
+ *
9
+ * @seeAlso middleware.ts (provides request handling logic).
10
+ * @seeAlso permissions.ts (manages access control and validation).
11
+ * @seeAlso db.ts (interfaces with the database for data operations).
12
+ * @seeAlso principal.ts (determines user roles and permissions).
13
+ *
14
+ * @cil-generated
15
+ */
16
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/admin-data.ts"]
17
+ // CIL[DOC-MACRO purpose="This module handles administrative data operations within the system, providing essential functionalities for managing records and permissions."]
18
+ // CIL[DOC-RESPONSIBILITY responsibility="This module handles administrative data operations within the system, providing essential functionalities for managing records and permissions. It serves as an API handler for various administrative actions, ensuring that only authorized users can perform updates and access sensitive data. INVARIANT: Only users with system admin privileges can execute these operations."]
19
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files="middleware.ts (provides request handling logic).,permissions.ts (manages access control and validation).,db.ts (interfaces with the database for data operations).,principal.ts (determines user roles and permissions)."]
20
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
21
+ // CIL[DOC-MICRO logic_summary="This module handles administrative data operations within the system, providing essential functionalities for managing records and permissions. It serves as an API handler for various administrative actions, ensuring that only authorized users can perform updates and access sensitive data. INVARIANT: Only users with system admin privileges can execute these operations." notable_decisions="none"]
22
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
23
+ // CIL[DOC-STABILITY stability="stable"]
24
+ // CIL[DOC-AUDIENCE audience="internal"]
1
25
 
2
26
 
3
27
 
@@ -7,21 +31,6 @@
7
31
 
8
32
 
9
33
 
10
- // CIL[BEGIN chunk_id="admin-data_module_header_1784019432" type="module_header" identity="imports" parent="none"]
11
- // CIL[DOC-MACRO purpose="Import dependencies for generic CRUD operations"]
12
- // CIL[DOC-RESPONSIBILITY responsibility="Provide middleware, permissions, database access, type resolution, and triggers"]
13
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/db.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
14
- // CIL[DOC-CONTRACT inputs="none" outputs="imported_modules,constants" errors="none" side_effects="none"]
15
- // CIL[DOC-MICRO logic_summary="Imports modules and defines entity validation constants" notable_decisions="[]"]
16
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
17
- // CIL[DOC-STABILITY stability="stable"]
18
- // CIL[DOC-AUDIENCE audience="developer"]
19
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/db.ts, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, \."]
20
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
21
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
22
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
23
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
24
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
25
34
  import { createHandler } from './_shared/middleware'
26
35
  import { sanitizeRecordData, resolveFirstSurfacePermissions, validateUpdatePermissions } from './_shared/permissions'
27
36
  import { adminDb } from './_shared/db'
@@ -29,16 +38,151 @@ import { isSystemAdmin } from './_shared/principal'
29
38
  import { resolveTypeId, resolveTypeIds, resolveTypeRecord } from './_shared/resolve-ids'
30
39
  import { fireCreateTriggers, fireUpdateTriggers, fireDeleteTriggers } from './_shared/trigger-engine'
31
40
  import { withAdminLogging } from './_shared/logging'
41
+ import { hasInternalAudience, projectMessageForCustomer } from './_shared/access'
42
+ import { checkTypeSlugRateLimit } from './_shared/security'
43
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:module_header:module_header"]
44
+ // CIL[DOC-VECTOR type="context" content="purpose='This module handles administrative data operations within the system, providing essential functionalities for managing records and permissions.'; No verified external callers" status="ready"]
45
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
46
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
47
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
48
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
49
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
32
50
 
51
+ // CIL[DOC-MACRO purpose="PERMISSIONS_ALL defines a comprehensive set of permissions for record management, including create, read, update, and delete actions."]
52
+ // CIL[DOC-RESPONSIBILITY responsibility="PERMISSIONS_ALL defines a comprehensive set of permissions for record management, including create, read, update, and delete actions. It serves as a centralized reference for managing access control in the application."]
53
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
54
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
55
+ // CIL[DOC-MICRO logic_summary="PERMISSIONS_ALL defines a comprehensive set of permissions for record management, including create, read, update, and delete actions. It serves as a centralized reference for managing access control in the application." notable_decisions="none"]
56
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
57
+ // CIL[DOC-STABILITY stability="stable"]
58
+ /**
59
+ * PERMISSIONS_ALL defines a comprehensive set of permissions for record management, including create, read, update, and delete actions. It serves as a centralized reference for managing access control in the application.
60
+ *
61
+ * @sideEffects none
62
+ * @stability stable
63
+ * @cil-generated
64
+ */
65
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:permissions_all:constant" type="constant" identity="PERMISSIONS_ALL" parent="~/.framework/functions/admin-data.ts"]
66
+ // CIL[DOC-MACRO purpose="PERMISSIONS_ALL constant"]
67
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the PERMISSIONS_ALL constant."]
68
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
69
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
70
+ // CIL[DOC-MICRO logic_summary="Implements the PERMISSIONS_ALL constant." notable_decisions="[]"]
71
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
72
+ // CIL[DOC-STABILITY stability="stable"]
33
73
  const PERMISSIONS_ALL = {
34
74
  record_permissions: { all: ['create', 'read', 'update', 'delete'] },
35
75
  fields: {}
36
76
  }
77
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:permissions_all:constant"]
78
+ // CIL[DOC-VECTOR type="context" content="purpose='PERMISSIONS_ALL defines a comprehensive set of permissions for record management, including create, read, update, and delete actions.'; No verified external callers" status="ready"]
79
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
80
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
81
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
82
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
83
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
37
84
 
85
+ // CIL[DOC-MACRO purpose="VALID_ENTITIES is a constant array that defines the valid entity types used throughout the admin data functions."]
86
+ // CIL[DOC-RESPONSIBILITY responsibility="VALID_ENTITIES is a constant array that defines the valid entity types used throughout the admin data functions. It ensures that only recognized entity types are processed in the module."]
87
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
88
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
89
+ // CIL[DOC-MICRO logic_summary="VALID_ENTITIES is a constant array that defines the valid entity types used throughout the admin data functions. It ensures that only recognized entity types are processed in the module." notable_decisions="none"]
90
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
91
+ // CIL[DOC-STABILITY stability="stable"]
92
+ /**
93
+ * VALID_ENTITIES is a constant array that defines the valid entity types used throughout the admin data functions. It ensures that only recognized entity types are processed in the module.
94
+ *
95
+ * @sideEffects none
96
+ * @stability stable
97
+ * @cil-generated
98
+ */
99
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:valid_entities:constant" type="constant" identity="VALID_ENTITIES" parent="~/.framework/functions/admin-data.ts"]
100
+ // CIL[DOC-MACRO purpose="VALID_ENTITIES constant"]
101
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the VALID_ENTITIES constant."]
102
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
103
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
104
+ // CIL[DOC-MICRO logic_summary="Implements the VALID_ENTITIES constant." notable_decisions="[]"]
105
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
106
+ // CIL[DOC-STABILITY stability="stable"]
38
107
  const VALID_ENTITIES = ['accounts', 'people', 'items', 'threads', 'messages', 'links', 'attachments', 'watchers', 'item_progress', 'logs', 'test_runs', 'observability', 'test_cases', 'types', 'link_types', 'ai_agents', 'prompt_configs']
108
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:valid_entities:constant"]
109
+ // CIL[DOC-MACRO purpose="VALID_ENTITIES constant"]
110
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the VALID_ENTITIES constant."]
111
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
112
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
113
+ // CIL[DOC-MICRO logic_summary="Implements the VALID_ENTITIES constant." notable_decisions="[]"]
114
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
115
+ // CIL[DOC-STABILITY stability="stable"]
116
+ // CIL[DOC-VECTOR type="context" content="purpose='VALID_ENTITIES is a constant array that defines the valid entity types used throughout the admin data functions.'; No verified external callers" status="ready"]
117
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
118
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
119
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
120
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
121
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
39
122
 
123
+ // CIL[DOC-MACRO purpose="RAW_ENTITIES is a constant array that defines a set of entity names used in the admin data functions."]
124
+ // CIL[DOC-RESPONSIBILITY responsibility="RAW_ENTITIES is a constant array that defines a set of entity names used in the admin data functions. It exists to provide a centralized reference for these entity types, ensuring consistency across the module."]
125
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
126
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
127
+ // CIL[DOC-MICRO logic_summary="RAW_ENTITIES is a constant array that defines a set of entity names used in the admin data functions. It exists to provide a centralized reference for these entity types, ensuring consistency across the module." notable_decisions="none"]
128
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
129
+ // CIL[DOC-STABILITY stability="stable"]
130
+ /**
131
+ * RAW_ENTITIES is a constant array that defines a set of entity names used in the admin data functions. It exists to provide a centralized reference for these entity types, ensuring consistency across the module.
132
+ *
133
+ * @sideEffects none
134
+ * @stability stable
135
+ * @cil-generated
136
+ */
137
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:raw_entities:constant" type="constant" identity="RAW_ENTITIES" parent="~/.framework/functions/admin-data.ts"]
138
+ // CIL[DOC-MACRO purpose="RAW_ENTITIES constant"]
139
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the RAW_ENTITIES constant."]
140
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
141
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
142
+ // CIL[DOC-MICRO logic_summary="Implements the RAW_ENTITIES constant." notable_decisions="[]"]
143
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
144
+ // CIL[DOC-STABILITY stability="stable"]
40
145
  const RAW_ENTITIES = ['logs', 'test_runs', 'observability', 'test_cases']
146
+ // Entities with no created_by/updated_by columns — audit stamps must be
147
+ // omitted or writes fail with schema-cache errors.
148
+ const UNAUDITED_ENTITIES = ['types', 'link_types']
149
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:raw_entities:constant"]
150
+ // CIL[DOC-MACRO purpose="RAW_ENTITIES constant"]
151
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the RAW_ENTITIES constant."]
152
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
153
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
154
+ // CIL[DOC-MICRO logic_summary="Implements the RAW_ENTITIES constant." notable_decisions="[]"]
155
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
156
+ // CIL[DOC-STABILITY stability="stable"]
157
+ // CIL[DOC-VECTOR type="context" content="purpose='RAW_ENTITIES is a constant array that defines a set of entity names used in the admin data functions.'; No verified external callers" status="ready"]
158
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
159
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
160
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
161
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
162
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
41
163
 
164
+ // CIL[DOC-MACRO purpose="ENTITY_TO_KIND is a mapping of entity names to their corresponding kind identifiers."]
165
+ // CIL[DOC-RESPONSIBILITY responsibility="ENTITY_TO_KIND is a mapping of entity names to their corresponding kind identifiers. It exists to provide a centralized reference for translating entity types within the application."]
166
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
167
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
168
+ // CIL[DOC-MICRO logic_summary="ENTITY_TO_KIND is a mapping of entity names to their corresponding kind identifiers. It exists to provide a centralized reference for translating entity types within the application." notable_decisions="none"]
169
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
170
+ // CIL[DOC-STABILITY stability="stable"]
171
+ /**
172
+ * ENTITY_TO_KIND is a mapping of entity names to their corresponding kind identifiers. It exists to provide a centralized reference for translating entity types within the application.
173
+ *
174
+ * @sideEffects none
175
+ * @stability stable
176
+ * @cil-generated
177
+ */
178
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:entity_to_kind:constant" type="constant" identity="ENTITY_TO_KIND" parent="~/.framework/functions/admin-data.ts"]
179
+ // CIL[DOC-MACRO purpose="ENTITY_TO_KIND constant"]
180
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the ENTITY_TO_KIND constant."]
181
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
182
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
183
+ // CIL[DOC-MICRO logic_summary="Implements the ENTITY_TO_KIND constant." notable_decisions="[]"]
184
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
185
+ // CIL[DOC-STABILITY stability="stable"]
42
186
  const ENTITY_TO_KIND: Record<string, string> = {
43
187
  accounts: 'account',
44
188
  people: 'person',
@@ -50,23 +194,39 @@ const ENTITY_TO_KIND: Record<string, string> = {
50
194
  watchers: 'watcher',
51
195
  item_progress: 'item_progress'
52
196
  }
53
- // CIL[END chunk_id="admin-data_module_header_1784019432"]
54
- // CIL[BEGIN chunk_id="admin-data_list_1784019432" type="function" identity="list" parent="none"]
55
- // CIL[DOC-MACRO purpose="List entity records with filtering and pagination"]
56
- // CIL[DOC-RESPONSIBILITY responsibility="Query, filter, paginate, and sanitize entity records"]
57
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
58
- // CIL[DOC-CONTRACT inputs="none" outputs="sanitized_records[] or {data,schema,view}" errors="entity_required,database_error" side_effects="database_queries,permission_filtering"]
59
- // CIL[DOC-MICRO logic_summary="Builds query with filters, applies pagination, sanitizes results, optionally resolves views" notable_decisions="[]"]
60
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="complex_dependencies"]
61
- // CIL[DOC-STABILITY stability="stable"]
62
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, \."]
63
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
64
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
65
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
197
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:entity_to_kind:constant"]
198
+ // CIL[DOC-VECTOR type="context" content="purpose='ENTITY_TO_KIND is a mapping of entity names to their corresponding kind identifiers.'; No verified external callers" status="ready"]
199
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
200
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
201
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
66
202
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
67
203
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
204
+ // CIL[DOC-MACRO purpose="The 'list' constant defines an asynchronous handler for listing entities based on various query parameters."]
205
+ // CIL[DOC-RESPONSIBILITY responsibility="The 'list' constant defines an asynchronous handler for listing entities based on various query parameters. It validates input parameters and constructs a database query to retrieve the requested data."]
206
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
207
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="Error — Valid entity parameter is required" side_effects="none dependencies="withAdminLogging, resolveTypeIds, getSearchField"]
208
+ // CIL[DOC-MICRO logic_summary="The 'list' constant defines an asynchronous handler for listing entities based on various query parameters. It validates input parameters and constructs a database query to retrieve the requested data." notable_decisions="none"]
209
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
210
+ // CIL[DOC-STABILITY stability="stable"]
211
+ /**
212
+ * The 'list' constant defines an asynchronous handler for listing entities based on various query parameters. It validates input parameters and constructs a database query to retrieve the requested data.
213
+ *
214
+ * @throws Error — Valid entity parameter is required
215
+ * @sideEffects none
216
+ * @stability stable
217
+ * @calls withAdminLogging, resolveTypeIds, getSearchField
218
+ * @cil-generated
219
+ */
220
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:list:constant" type="constant" identity="list" parent="~/.framework/functions/admin-data.ts"]
221
+ // CIL[DOC-MACRO purpose="list constant"]
222
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the list constant."]
223
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
224
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
225
+ // CIL[DOC-MICRO logic_summary="Implements the list constant." notable_decisions="[]"]
226
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
227
+ // CIL[DOC-STABILITY stability="stable"]
68
228
  export const list = createHandler(async (ctx, _body) => {
69
- const { entity, action, method, search, sort_field = 'created_at', sort_direction = 'desc', limit = 50, offset = 0, type_slug, type_slugs, view: viewSlug, ...filters } = ctx.query || {}
229
+ const { entity, action, method, search, sort_field = 'created_at', sort_direction = 'desc', limit = 50, offset = 0, type_slug, type_slugs, view: viewSlug, flag_only, exclude_flag, ...filters } = ctx.query || {}
70
230
 
71
231
  return await withAdminLogging(
72
232
  ctx,
@@ -85,6 +245,12 @@ export const list = createHandler(async (ctx, _body) => {
85
245
  const db = (ctx.principal?.isInternal || isSystemAdmin(ctx.principal)) ? adminDb : ctx.db
86
246
  let query = db.from(entity).select('*')
87
247
 
248
+ // Customer-scoped principals never receive internal threads.
249
+ const internalAudience = hasInternalAudience(ctx.principal)
250
+ if (entity === 'threads' && !internalAudience) {
251
+ query = query.neq('visibility', 'internal')
252
+ }
253
+
88
254
  const targetSlugs: string[] = []
89
255
  if (type_slug) targetSlugs.push(type_slug)
90
256
  if (type_slugs) {
@@ -126,6 +292,26 @@ export const list = createHandler(async (ctx, _body) => {
126
292
  }
127
293
  })
128
294
 
295
+ // Generic record-flag filters on the row's data jsonb. flag_only=<field>
296
+ // returns only rows where data->>field is 'true'; exclude_flag=<field>
297
+ // hides them (null counts as unset). Flag fields are stamped server-side
298
+ // — clients can only filter on them, never set them. Only entities whose
299
+ // rows carry flaggable data payloads are eligible (accounts/people are
300
+ // excluded). The field name is validated before it is interpolated into
301
+ // the PostgREST filter string.
302
+ const FLAGGABLE_ENTITIES = ['items', 'threads', 'messages', 'links', 'attachments', 'watchers']
303
+ const flagParam = flag_only ?? exclude_flag
304
+ if (flagParam !== undefined && !/^[a-z][a-z0-9_]{0,62}$/.test(String(flagParam))) {
305
+ const e: any = new Error('Invalid flag field name'); e.statusCode = 400; throw e
306
+ }
307
+ if (FLAGGABLE_ENTITIES.includes(entity)) {
308
+ if (flag_only) {
309
+ query = query.eq(`data->>${flag_only}`, 'true')
310
+ } else if (exclude_flag) {
311
+ query = query.or(`data->>${exclude_flag}.is.null,data->>${exclude_flag}.eq.false`)
312
+ }
313
+ }
314
+
129
315
  query = query.order(sort_field, { ascending: sort_direction === 'asc' })
130
316
 
131
317
  const { count, error: countError } = await db.from(entity)
@@ -145,12 +331,32 @@ export const list = createHandler(async (ctx, _body) => {
145
331
  throw new Error(err.message || 'Database error listing records')
146
332
  }
147
333
 
148
- const sanitizedData = []
149
- for (const record of data || []) {
150
- const sanitizedRecord = await sanitizeRecordData(ctx, record, entity)
151
- sanitizedData.push(sanitizedRecord)
334
+ // Customer-scoped message reads project internal rows into safe
335
+ // step summaries — only when the parent thread itself is external.
336
+ let threadIsInternal = true
337
+ if (entity === 'messages' && !internalAudience && filters.thread_id) {
338
+ const { data: parentThread } = await adminDb
339
+ .from('threads')
340
+ .select('visibility')
341
+ .eq('id', filters.thread_id)
342
+ .maybeSingle()
343
+ threadIsInternal = parentThread?.visibility !== 'external' && parentThread?.visibility !== 'public'
344
+ ? true
345
+ : false
152
346
  }
153
347
 
348
+ // Sanitize rows concurrently — the sequential loop turned every list
349
+ // request into an N+1 of permission lookups.
350
+ const sanitizedData = (
351
+ await Promise.all((data || []).map(async (record: any) => {
352
+ const sanitizedRecord = await sanitizeRecordData(ctx, record, entity)
353
+ if (entity === 'messages' && !internalAudience) {
354
+ return projectMessageForCustomer(sanitizedRecord, { threadIsInternal })
355
+ }
356
+ return sanitizedRecord
357
+ }))
358
+ ).filter(Boolean)
359
+
154
360
  if (viewSlug && type_slug) {
155
361
  const { data: typeRecord } = await adminDb
156
362
  .from('types')
@@ -170,36 +376,70 @@ export const list = createHandler(async (ctx, _body) => {
170
376
  }
171
377
  )
172
378
  })
173
- // CIL[END chunk_id="admin-data_list_1784019432"]
174
- // CIL[BEGIN chunk_id="admin-data_get_1784019432" type="function" identity="get" parent="none"]
175
- // CIL[DOC-MACRO purpose="Get single entity record by ID"]
176
- // CIL[DOC-RESPONSIBILITY responsibility="Retrieve and sanitize individual entity record"]
177
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"\\\"]"]
178
- // CIL[DOC-CONTRACT inputs="none" outputs="sanitized_record or {data,schema,view}" errors="entity_required,id_required,record_not_found" side_effects="database_query,permission_filtering"]
179
- // CIL[DOC-MICRO logic_summary="Queries single record by ID, applies permission sanitization, optionally resolves view" notable_decisions="[]"]
180
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
181
- // CIL[DOC-STABILITY stability="stable"]
182
- // 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/TypeDetailPage.tsx, .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/functions/custom_cil-embeddings.ts, \."]
183
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
184
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
185
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
379
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:list:constant"]
380
+ // CIL[DOC-VECTOR type="context" content="purpose='The 'list' constant defines an asynchronous handler for listing entities based on various query parameters.'; No verified external callers" status="ready"]
381
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
382
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
383
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
186
384
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
187
385
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
386
+ // CIL[DOC-MACRO purpose="Async function that resolves and attaches hierarchical lineage data to a record."]
387
+ // CIL[DOC-RESPONSIBILITY responsibility="The attachLineage function retrieves and attaches parent and child records to a given record based on the lineage configuration declared on the record's type (design_schema.functionality.lineage). It is designed to facilitate the understanding of relationships between different entities in the database."]
388
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
389
+ // CIL[DOC-CONTRACT inputs="- record: any (required) — the record to which lineage will be attached.\\n- ctx: any (required) — the context containing database access and other utilities." outputs="Promise<void>" errors="none" side_effects="Database reads from 'types', 'links' and 'items' tables. dependencies="ctx.db.from, ctx.db.select, ctx.db.eq, ctx.db.limit, ctx.db.single, sanitizeRecordData, resolveTypeIds, adminDb.from"]
390
+ // CIL[DOC-MICRO logic_summary="Reads functionality.lineage off the record's type; walks declared parent_fields/link_type for parents (max 5 hops, cycle-guarded) and resolves declared children via links plus per-type data-field lookups." notable_decisions="Lineage traversal is fully declared on the owning app's type design_schema — no app-specific maps in framework code; each leg is guarded by its own declaration so partial blocks still work; types without a lineage block attach empty parents/children with no link/data queries."]
391
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
392
+ // CIL[DOC-STABILITY stability="stable"]
393
+ /**
394
+ * The attachLineage function retrieves and attaches parent and child records to a given record based on its lineage in a hierarchical structure. It is designed to facilitate the understanding of relationships between different entities in the database.
395
+ *
396
+ * @macro Async function that resolves and attaches hierarchical lineage data to a record.
397
+ * @micro Reads the type-declared functionality.lineage config (parent_fields, link_type, children) and resolves parents via link + data-field walks and children via reverse links + per-type field lookups.
398
+ * @inputSpec
399
+ * - record: any (required) — the record to which lineage will be attached.
400
+ * - ctx: any (required) — the context containing database access and other utilities.
401
+ * @outputSpec Promise<void>
402
+ * @sideEffects Database reads from 'types', 'links' and 'items' tables.
403
+ * @stability stable
404
+ * @calls adminDb.from, ctx.db.from, ctx.db.select, ctx.db.eq, ctx.db.limit, ctx.db.single, sanitizeRecordData, resolveTypeIds
405
+ * @errorHandling returns null on error during data fetching.
406
+ * @cil-generated
407
+ */
408
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:attachlineage:function" type="function" identity="attachLineage" parent="~/.framework/functions/admin-data.ts"]
409
+ // CIL[DOC-MACRO purpose="attachLineage function"]
410
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the attachLineage function from type-declared lineage config."]
411
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
412
+ // CIL[DOC-CONTRACT inputs="record: any — item record with type_id, ctx: any — request context with db" outputs="mutates record (parents, children, type_slug)" errors="none" side_effects="reads types/links/items"]
413
+ // CIL[DOC-MICRO logic_summary="Reads functionality.lineage off the record's type design_schema; parents walk declared link_type then parent_fields (5-hop, visited-set cycle guard); children resolve via reverse link_type edges plus per-child-type data field lookups." notable_decisions="['link_type queries are guarded by the declared link_type, parent scan by declared parent_fields, child field lookups by declared children — a type with no lineage block attaches empty arrays with no link/data queries']"]
414
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
415
+ // CIL[DOC-STABILITY stability="stable"]
188
416
  async function attachLineage(record: any, ctx: any): Promise<void> {
189
- const parentFields = ['epic_id', 'sprint_id', 'initiative_id', 'discovery_id', 'idea_id']
190
- const childrenMap: Record<string, { field: string; childSlugs: string[] }> = {
191
- workbench_idea: { field: 'idea_id', childSlugs: ['workbench_discovery'] },
192
- workbench_discovery: { field: 'discovery_id', childSlugs: ['workbench_initiative'] },
193
- workbench_initiative: { field: 'initiative_id', childSlugs: ['workbench_epic', 'workbench_work_item'] },
194
- workbench_epic: { field: 'epic_id', childSlugs: ['workbench_work_item', 'workbench_sprint'] },
195
- workbench_sprint: { field: 'sprint_id', childSlugs: ['workbench_work_item'] },
196
- workbench_work_item: { field: '', childSlugs: [] },
197
- }
417
+ // Lineage is declared per item type in design_schema.functionality.lineage:
418
+ // { parent_fields: string[], link_type: string, children: { [childTypeSlug]: field } }
419
+ // Each leg is guarded by its own declaration — link queries run only when
420
+ // link_type is declared, the parent field-scan only iterates declared
421
+ // parent_fields, and data-field child lookups only run for declared children
422
+ // entries. A type with no lineage block gets empty parents/children and no
423
+ // link/data queries run at all.
424
+ const { data: typeRow } = await adminDb
425
+ .from('types')
426
+ .select('slug, design_schema')
427
+ .eq('id', record.type_id)
428
+ .single()
429
+ const lineage = typeRow?.design_schema?.functionality?.lineage
430
+ const linkType = typeof lineage?.link_type === 'string' && lineage.link_type ? lineage.link_type : null
431
+ const parentFields: string[] = Array.isArray(lineage?.parent_fields)
432
+ ? lineage.parent_fields.filter((f: any) => typeof f === 'string' && f)
433
+ : []
434
+ const childrenMap: Record<string, string> =
435
+ lineage?.children && typeof lineage.children === 'object' ? lineage.children : {}
198
436
 
199
437
  async function parentIdFor(current: any, visited: Set<string>): Promise<string | null> {
200
- const { data: links } = await ctx.db.from('links').select('target_id').eq('source_id', current.id).eq('link_type', 'workbench_originated_from').eq('source_type', 'items').limit(1)
201
- const linkTarget = links?.[0]?.target_id
202
- if (linkTarget && !visited.has(linkTarget)) return linkTarget
438
+ if (linkType) {
439
+ const { data: links } = await ctx.db.from('links').select('target_id').eq('source_id', current.id).eq('link_type', linkType).eq('source_type', 'items').limit(1)
440
+ const linkTarget = links?.[0]?.target_id
441
+ if (linkTarget && !visited.has(linkTarget)) return linkTarget
442
+ }
203
443
  const d = current.data || {}
204
444
  for (const key of parentFields) {
205
445
  const id = d[key]
@@ -209,6 +449,7 @@ async function attachLineage(record: any, ctx: any): Promise<void> {
209
449
  }
210
450
 
211
451
  async function getParents(record: any): Promise<any[]> {
452
+ if (!linkType && parentFields.length === 0) return []
212
453
  const parents: any[] = []
213
454
  const visited = new Set<string>([record.id])
214
455
  let current: any = record
@@ -227,19 +468,21 @@ async function attachLineage(record: any, ctx: any): Promise<void> {
227
468
 
228
469
  async function getChildren(record: any): Promise<any[]> {
229
470
  const childIds = new Set<string>()
230
- const { data: linkRows } = await ctx.db.from('links').select('source_id').eq('target_id', record.id).eq('link_type', 'workbench_originated_from').eq('target_type', 'items').limit(50)
231
- for (const row of linkRows || []) {
232
- if (row.source_id && row.source_id !== record.id) childIds.add(row.source_id)
471
+ if (linkType) {
472
+ const { data: linkRows } = await ctx.db.from('links').select('source_id').eq('target_id', record.id).eq('link_type', linkType).eq('target_type', 'items').limit(50)
473
+ for (const row of linkRows || []) {
474
+ if (row.source_id && row.source_id !== record.id) childIds.add(row.source_id)
475
+ }
233
476
  }
234
- const { data: typeRow } = await adminDb.from('types').select('slug').eq('id', record.type_id).single()
235
- const cfg = typeRow?.slug ? childrenMap[typeRow.slug] : null
236
- if (cfg?.childSlugs.length) {
477
+ const childEntries = Object.entries(childrenMap)
478
+ .filter(([slug, field]) => slug && typeof field === 'string' && field)
479
+ if (childEntries.length) {
237
480
  try {
238
- const pairs = cfg.childSlugs.map(slug => ({ kind: 'item', slug }))
239
- const resolved = await resolveTypeIds(pairs)
240
- const typeIds = Object.values(resolved)
241
- if (typeIds.length) {
242
- const { data: dataChildren } = await ctx.db.from('items').select('id').in('type_id', typeIds).eq(`data->>${cfg.field}`, record.id)
481
+ const resolved = await resolveTypeIds(childEntries.map(([slug]) => ({ kind: 'item', slug })))
482
+ for (const [slug, field] of childEntries) {
483
+ const childTypeId = resolved[`item/${slug}`]
484
+ if (!childTypeId) continue
485
+ const { data: dataChildren } = await ctx.db.from('items').select('id').eq('type_id', childTypeId).eq(`data->>${field}`, record.id)
243
486
  for (const child of dataChildren || []) {
244
487
  if (child.id && child.id !== record.id) childIds.add(child.id)
245
488
  }
@@ -273,7 +516,38 @@ async function attachLineage(record: any, ctx: any): Promise<void> {
273
516
  record.parents = parents
274
517
  record.children = children
275
518
  }
519
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:attachlineage:function"]
520
+ // CIL[DOC-VECTOR type="context" content="purpose='The attachLineage function retrieves and attaches parent and child records to a given record based on its lineage in a hierarchical structure.'; No verified external callers" status="ready"]
521
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
522
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
523
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
524
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
525
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
276
526
 
527
+ // CIL[DOC-MACRO purpose="The 'get' constant defines an asynchronous handler for retrieving records from a database based on entity type and ID."]
528
+ // CIL[DOC-RESPONSIBILITY responsibility="The 'get' constant defines an asynchronous handler for retrieving records from a database based on entity type and ID. It ensures proper logging and validation of input parameters before fetching and sanitizing the requested data."]
529
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
530
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="Error — Valid entity parameter is required, Error — ID parameter is required, Error — Record not found" side_effects="none dependencies="withAdminLogging, ctx.db.from, sanitizeRecordData, adminDb.from, attachLineage, projectMessageForCustomer"]
531
+ // CIL[DOC-MICRO logic_summary="The 'get' constant defines an asynchronous handler for retrieving records from a database based on entity type and ID. It ensures proper logging and validation of input parameters before fetching and sanitizing the requested data." notable_decisions="none"]
532
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
533
+ // CIL[DOC-STABILITY stability="stable"]
534
+ /**
535
+ * The 'get' constant defines an asynchronous handler for retrieving records from a database based on entity type and ID. It ensures proper logging and validation of input parameters before fetching and sanitizing the requested data.
536
+ *
537
+ * @throws Error — Valid entity parameter is required, Error — ID parameter is required, Error — Record not found
538
+ * @sideEffects none
539
+ * @stability stable
540
+ * @calls withAdminLogging, ctx.db.from, sanitizeRecordData, adminDb.from, attachLineage, projectMessageForCustomer
541
+ * @cil-generated
542
+ */
543
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:get:constant" type="constant" identity="get" parent="~/.framework/functions/admin-data.ts"]
544
+ // CIL[DOC-MACRO purpose="get constant"]
545
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the get constant."]
546
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
547
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
548
+ // CIL[DOC-MICRO logic_summary="Implements the get constant." notable_decisions="[]"]
549
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
550
+ // CIL[DOC-STABILITY stability="stable"]
277
551
  export const get = createHandler(async (ctx, _body) => {
278
552
  const { entity, id, view: viewSlug } = ctx.query || {}
279
553
  const method = ctx.query?.method || 'GET'
@@ -306,9 +580,29 @@ export const get = createHandler(async (ctx, _body) => {
306
580
  throw new Error('Record not found')
307
581
  }
308
582
 
309
- const sanitizedRecord = await sanitizeRecordData(ctx, data, entity)
583
+ let sanitizedRecord = await sanitizeRecordData(ctx, data, entity)
584
+
585
+ // Customer-scoped principals cannot fetch internal threads or
586
+ // unprojectable internal messages by id.
587
+ if (!hasInternalAudience(ctx.principal) && sanitizedRecord?.visibility === 'internal') {
588
+ if (entity === 'threads') {
589
+ throw new Error('Record not found')
590
+ }
591
+ if (entity === 'messages') {
592
+ const { data: parentThread } = await adminDb
593
+ .from('threads')
594
+ .select('visibility')
595
+ .eq('id', sanitizedRecord.thread_id)
596
+ .maybeSingle()
597
+ const threadIsInternal = parentThread?.visibility !== 'external' && parentThread?.visibility !== 'public'
598
+ sanitizedRecord = projectMessageForCustomer(sanitizedRecord, { threadIsInternal })
599
+ if (!sanitizedRecord) throw new Error('Record not found')
600
+ }
601
+ }
310
602
 
311
- if (entity === 'items') {
603
+ // Lineage traversal costs several sequential reads — polling callers
604
+ // that never render it pass lineage=0 to skip it.
605
+ if (entity === 'items' && (ctx as any).query?.lineage !== '0') {
312
606
  await attachLineage(sanitizedRecord, ctx)
313
607
  }
314
608
 
@@ -322,23 +616,37 @@ export const get = createHandler(async (ctx, _body) => {
322
616
  }
323
617
  )
324
618
  })
325
- // CIL[END chunk_id="admin-data_get_1784019432"]
326
- // CIL[BEGIN chunk_id="admin-data_create_1784019432" type="function" identity="create" parent="none"]
327
- // CIL[DOC-LEARNING topic="runtime-type:generic/stamping" content="Every runtime record is stamped with type.design_schema and type.validation_schema from the types table. resolveTypeRecord resolves kind+slug or type_id. admin-data create inherits scope from parent, applies PERMISSIONS_ALL default when record_permissions is missing, sets system fields on the row and non-system fields in record.data, then fires triggers. This applies to all kinds: account, person, item, thread, message, link, attachment, watcher."]
328
- // CIL[DOC-NOTE type="design_schema_caveat" content="If a type row lacks record_permissions, the created record receives PERMISSIONS_ALL but permissions.ts may still reduce it to id at read time if the stamped schema is later cleared. Missing scope defaults to account inheritance; ensure types define scope explicitly."]
329
- // CIL[DOC-MACRO purpose="Create new entity record with type resolution"]
330
- // CIL[DOC-RESPONSIBILITY responsibility="Validate, resolve type, create record with inheritance and triggers"]
331
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/db.ts\",\".framework/src/components/ui/dialog.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
332
- // CIL[DOC-CONTRACT inputs="none" outputs="created_record" errors="entity_required,type_resolution_failed,parent_not_found" side_effects="database_insert,trigger_fire,permission_inheritance"]
333
- // CIL[DOC-MICRO logic_summary="Resolves type, handles account inheritance, applies defaults, fires triggers" notable_decisions="[]"]
334
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="complex_dependencies"]
335
- // CIL[DOC-STABILITY stability="stable"]
336
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/db.ts, .framework/src/components/ui/dialog.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
337
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
338
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
339
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
619
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:get:constant"]
620
+ // CIL[DOC-VECTOR type="context" content="purpose='The 'get' constant defines an asynchronous handler for retrieving records from a database based on entity type and ID.'; No verified external callers" status="ready"]
621
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
622
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
623
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
340
624
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
341
625
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
626
+ // CIL[DOC-MACRO purpose="The 'create' constant defines an asynchronous handler for creating new entities in the admin data context."]
627
+ // CIL[DOC-RESPONSIBILITY responsibility="The 'create' constant defines an asynchronous handler for creating new entities in the admin data context. It validates input data and logs the creation action while handling various entity types."]
628
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
629
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="Error — Valid entity parameter is required; Error — level and message are required for logs; Error — suite is required for test_runs; Error — metric_name and metric_value are required for observability; Error — slug and name are required for test_cases." side_effects="Database writes for new entity records, logging actions, and triggering additional processes. dependencies="withAdminLogging, ctx.db.from, fireCreateTriggers, sanitizeRecordData"]
630
+ // CIL[DOC-MICRO logic_summary="The 'create' constant defines an asynchronous handler for creating new entities in the admin data context. It validates input data and logs the creation action while handling various entity types." notable_decisions="none"]
631
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
632
+ // CIL[DOC-STABILITY stability="stable"]
633
+ /**
634
+ * The 'create' constant defines an asynchronous handler for creating new entities in the admin data context. It validates input data and logs the creation action while handling various entity types.
635
+ *
636
+ * @throws Error — Valid entity parameter is required; Error — level and message are required for logs; Error — suite is required for test_runs; Error — metric_name and metric_value are required for observability; Error — slug and name are required for test_cases.
637
+ * @sideEffects Database writes for new entity records, logging actions, and triggering additional processes.
638
+ * @stability stable
639
+ * @calls withAdminLogging, ctx.db.from, fireCreateTriggers, sanitizeRecordData
640
+ * @cil-generated
641
+ */
642
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:create:constant" type="constant" identity="create" parent="~/.framework/functions/admin-data.ts"]
643
+ // CIL[DOC-MACRO purpose="create constant"]
644
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the create constant."]
645
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
646
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
647
+ // CIL[DOC-MICRO logic_summary="Implements the create constant." notable_decisions="[]"]
648
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
649
+ // CIL[DOC-STABILITY stability="stable"]
342
650
  export const create = createHandler(async (ctx, body) => {
343
651
  const entity = body?.entity || ctx.query?.entity
344
652
  const type_slug = body?.type_slug
@@ -407,6 +715,11 @@ export const create = createHandler(async (ctx, body) => {
407
715
 
408
716
  recordData.type_id = typeRecord.id
409
717
 
718
+ // Per-type create rate limit. Apps opt in by declaring
719
+ // config.rate_limits['<type_slug>_create'] in their manifest;
720
+ // with no policy the cached config read is the only cost.
721
+ await checkTypeSlugRateLimit(ctx, body?.type_slug)
722
+
410
723
  let designSchema = typeRecord.design_schema || {}
411
724
  if (!designSchema.record_permissions) {
412
725
  designSchema = { ...PERMISSIONS_ALL, ...designSchema }
@@ -456,7 +769,7 @@ export const create = createHandler(async (ctx, body) => {
456
769
  ...recordData,
457
770
  design_schema: designSchema,
458
771
  validation_schema: typeRecord.validation_schema || {},
459
- created_by: ctx.principal?.id,
772
+ ...(UNAUDITED_ENTITIES.includes(entity) ? {} : { created_by: ctx.principal?.type === 'human' ? ctx.principal.id : null }),
460
773
  created_at: new Date().toISOString(),
461
774
  updated_at: new Date().toISOString()
462
775
  }
@@ -477,7 +790,9 @@ export const create = createHandler(async (ctx, body) => {
477
790
  'create',
478
791
  designSchema
479
792
  )
480
- if (!perms.canCreate) {
793
+ const isMachineGlobal = ctx.principal?.type === 'machine' &&
794
+ (ctx.principal.scopes || []).includes('*:*')
795
+ if (!perms.canCreate && !isMachineGlobal) {
481
796
  const e: any = new Error('Insufficient permissions to create this record')
482
797
  e.statusCode = 403
483
798
  throw e
@@ -499,21 +814,37 @@ export const create = createHandler(async (ctx, body) => {
499
814
  }
500
815
  )
501
816
  })
502
- // CIL[END chunk_id="admin-data_create_1784019432"]
503
- // CIL[BEGIN chunk_id="admin-data_update_1784019432" type="function" identity="update" parent="none"]
504
- // CIL[DOC-MACRO purpose="Update existing entity record"]
505
- // CIL[DOC-RESPONSIBILITY responsibility="Patch allowed fields on entity record with triggers"]
506
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\"]"]
507
- // CIL[DOC-CONTRACT inputs="none" outputs="updated_record" errors="entity_required,id_required" side_effects="database_update,trigger_fire"]
508
- // CIL[DOC-MICRO logic_summary="Filters protected fields, adds audit fields, updates record, fires triggers" notable_decisions="[]"]
509
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
510
- // CIL[DOC-STABILITY stability="stable"]
511
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx."]
512
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
513
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
514
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
817
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:create:constant"]
818
+ // CIL[DOC-VECTOR type="context" content="purpose='The 'create' constant defines an asynchronous handler for creating new entities in the admin data context.'; No verified external callers" status="ready"]
819
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
820
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
821
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
515
822
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
516
823
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
824
+ // CIL[DOC-MACRO purpose="The update function handles updating records in the database while ensuring proper validation and permissions."]
825
+ // CIL[DOC-RESPONSIBILITY responsibility="The update function handles updating records in the database while ensuring proper validation and permissions. It logs the update action and sanitizes the data before performing the update."]
826
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
827
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="Error — Valid entity parameter is required; Error — ID is required for update; Error — Record not found or access denied; Error — Insufficient permissions to update this record." side_effects="Database update operation, logging actions, and triggering update events. dependencies="withAdminLogging, validateUpdatePermissions, ctx.db.from, fireUpdateTriggers, sanitizeRecordData"]
828
+ // CIL[DOC-MICRO logic_summary="The update function handles updating records in the database while ensuring proper validation and permissions. It logs the update action and sanitizes the data before performing the update." notable_decisions="none"]
829
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
830
+ // CIL[DOC-STABILITY stability="stable"]
831
+ /**
832
+ * The update function handles updating records in the database while ensuring proper validation and permissions. It logs the update action and sanitizes the data before performing the update.
833
+ *
834
+ * @throws Error — Valid entity parameter is required; Error — ID is required for update; Error — Record not found or access denied; Error — Insufficient permissions to update this record.
835
+ * @sideEffects Database update operation, logging actions, and triggering update events.
836
+ * @stability stable
837
+ * @calls withAdminLogging, validateUpdatePermissions, ctx.db.from, fireUpdateTriggers, sanitizeRecordData
838
+ * @cil-generated
839
+ */
840
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:update:constant" type="constant" identity="update" parent="~/.framework/functions/admin-data.ts"]
841
+ // CIL[DOC-MACRO purpose="update constant"]
842
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the update constant."]
843
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
844
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
845
+ // CIL[DOC-MICRO logic_summary="Implements the update constant." notable_decisions="[]"]
846
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
847
+ // CIL[DOC-STABILITY stability="stable"]
517
848
  export const update = createHandler(async (ctx, body) => {
518
849
  const { entity, id } = ctx.query || {}
519
850
  const method = ctx.query?.method || 'PATCH'
@@ -528,7 +859,7 @@ export const update = createHandler(async (ctx, body) => {
528
859
  typeSlug: type_slug
529
860
  },
530
861
  async () => {
531
- const { design_schema: _ds, validation_schema: _vs, type_id: _ti, type_slug: _ts, id: _id, account_id: requestedAccountId, ...recordData } = body || {}
862
+ const { design_schema: _ds, validation_schema: _vs, type_id: _ti, type_slug: _ts, id: _id, account_id: requestedAccountId, entity: _entity, ...recordData } = body || {}
532
863
 
533
864
  if (!entity || !VALID_ENTITIES.includes(entity)) {
534
865
  throw new Error('Valid entity parameter is required')
@@ -560,16 +891,20 @@ export const update = createHandler(async (ctx, body) => {
560
891
  typeSlugForPermissions
561
892
  )
562
893
 
563
- if (!validation.valid) {
894
+ if (!validation.valid && !isSystemAdmin(ctx.principal)) {
564
895
  const e: any = new Error(validation.error || 'Insufficient permissions to update this record')
565
896
  e.statusCode = 403
566
897
  throw e
567
898
  }
568
899
 
569
- const sanitizedUpdate = validation.sanitizedData || recordData
900
+ const sanitizedUpdate = (validation as any).sanitizedData || recordData
570
901
  const dataToUpdate = RAW_ENTITIES.includes(entity)
571
902
  ? { ...sanitizedUpdate }
572
- : { ...sanitizedUpdate, updated_by: ctx.principal?.id, updated_at: new Date().toISOString() }
903
+ : {
904
+ ...sanitizedUpdate,
905
+ ...(UNAUDITED_ENTITIES.includes(entity) ? {} : { updated_by: ctx.principal?.type === 'human' ? ctx.principal.id : null }),
906
+ updated_at: new Date().toISOString()
907
+ }
573
908
 
574
909
  const { data, error: err } = await ctx.db.from(entity)
575
910
  .update(dataToUpdate)
@@ -586,21 +921,37 @@ export const update = createHandler(async (ctx, body) => {
586
921
  }
587
922
  )
588
923
  })
589
- // CIL[END chunk_id="admin-data_update_1784019432"]
590
- // CIL[BEGIN chunk_id="admin-data_remove_1784019432" type="function" identity="remove" parent="none"]
591
- // CIL[DOC-MACRO purpose="Delete entity record with soft delete support"]
592
- // CIL[DOC-RESPONSIBILITY responsibility="Perform hard or soft delete with triggers"]
593
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[]"]
594
- // CIL[DOC-CONTRACT inputs="none" outputs="delete_confirmation" errors="entity_required,id_required" side_effects="database_delete,trigger_fire"]
595
- // CIL[DOC-MICRO logic_summary="Checks soft delete support, performs appropriate delete method, fires triggers" notable_decisions="[]"]
596
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
597
- // CIL[DOC-STABILITY stability="stable"]
598
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
599
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
600
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
601
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
924
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:update:constant"]
925
+ // CIL[DOC-VECTOR type="context" content="purpose='The update function handles updating records in the database while ensuring proper validation and permissions.'; No verified external callers" status="ready"]
926
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
927
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
928
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
602
929
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
603
930
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
931
+ // CIL[DOC-MACRO purpose="The 'remove' constant defines an asynchronous handler for removing records from a database, supporting both soft and hard deletes based on the provided parameters."]
932
+ // CIL[DOC-RESPONSIBILITY responsibility="The 'remove' constant defines an asynchronous handler for removing records from a database, supporting both soft and hard deletes based on the provided parameters. It ensures that the entity and ID are valid and checks for sufficient permissions before performing the delete operation."]
933
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
934
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="Error — Valid entity parameter is required, Error — ID is required for delete, Error — Record not found or access denied, Error — Insufficient permissions to delete this record." side_effects="Updates or deletes records in the database. dependencies="withAdminLogging, ctx.db.from, resolveFirstSurfacePermissions, entitySupportsSoftDelete, sanitizeRecordData"]
935
+ // CIL[DOC-MICRO logic_summary="The 'remove' constant defines an asynchronous handler for removing records from a database, supporting both soft and hard deletes based on the provided parameters. It ensures that the entity and ID are valid and checks for sufficient permissions before performing the delete operation." notable_decisions="none"]
936
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
937
+ // CIL[DOC-STABILITY stability="stable"]
938
+ /**
939
+ * The 'remove' constant defines an asynchronous handler for removing records from a database, supporting both soft and hard deletes based on the provided parameters. It ensures that the entity and ID are valid and checks for sufficient permissions before performing the delete operation.
940
+ *
941
+ * @throws Error — Valid entity parameter is required, Error — ID is required for delete, Error — Record not found or access denied, Error — Insufficient permissions to delete this record.
942
+ * @sideEffects Updates or deletes records in the database.
943
+ * @stability stable
944
+ * @calls withAdminLogging, ctx.db.from, resolveFirstSurfacePermissions, entitySupportsSoftDelete, sanitizeRecordData
945
+ * @cil-generated
946
+ */
947
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:remove:constant" type="constant" identity="remove" parent="~/.framework/functions/admin-data.ts"]
948
+ // CIL[DOC-MACRO purpose="remove constant"]
949
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the remove constant."]
950
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
951
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
952
+ // CIL[DOC-MICRO logic_summary="Implements the remove constant." notable_decisions="[]"]
953
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
954
+ // CIL[DOC-STABILITY stability="stable"]
604
955
  export const remove = createHandler(async (ctx, _body) => {
605
956
  const { entity, id, soft = 'true' } = ctx.query || {}
606
957
  const method = ctx.query?.method || 'DELETE'
@@ -640,7 +991,7 @@ export const remove = createHandler(async (ctx, _body) => {
640
991
  existing.design_schema
641
992
  )
642
993
 
643
- if (!perms.canDelete) {
994
+ if (!perms.canDelete && !isSystemAdmin(ctx.principal)) {
644
995
  const e: any = new Error('Insufficient permissions to delete this record')
645
996
  e.statusCode = 403
646
997
  throw e
@@ -652,7 +1003,7 @@ export const remove = createHandler(async (ctx, _body) => {
652
1003
  const { data, error: err } = await ctx.db.from(entity)
653
1004
  .update({
654
1005
  is_active: false,
655
- updated_by: ctx.principal?.id,
1006
+ updated_by: ctx.principal?.type === 'human' ? ctx.principal.id : null,
656
1007
  updated_at: new Date().toISOString()
657
1008
  })
658
1009
  .eq('id', id)
@@ -672,21 +1023,38 @@ export const remove = createHandler(async (ctx, _body) => {
672
1023
  }
673
1024
  )
674
1025
  })
675
- // CIL[END chunk_id="admin-data_remove_1784019432"]
676
- // CIL[BEGIN chunk_id="admin-data_getsearchfield_1784019432" type="function" identity="getSearchField" parent="none"]
677
- // CIL[DOC-MACRO purpose="Return search field mapping for entity"]
678
- // CIL[DOC-RESPONSIBILITY responsibility="Provide field name for search functionality"]
679
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[]"]
680
- // CIL[DOC-CONTRACT inputs="none" outputs="search_field:string" errors="none" side_effects="none"]
681
- // CIL[DOC-MICRO logic_summary="Maps entity types to their primary display fields for search" notable_decisions="[]"]
682
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
683
- // CIL[DOC-STABILITY stability="stable"]
684
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
685
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
686
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
687
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1026
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:remove:constant"]
1027
+ // CIL[DOC-VECTOR type="context" content="purpose='The 'remove' constant defines an asynchronous handler for removing records from a database, supporting both soft and hard deletes based on the provided parameters.'; No verified external callers" status="ready"]
1028
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
1029
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
1030
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
688
1031
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
689
1032
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1033
+ // CIL[DOC-MACRO purpose="Retrieves the appropriate search field name for a given entity type."]
1034
+ // CIL[DOC-RESPONSIBILITY responsibility="Retrieves the appropriate search field name for a given entity type. This function helps standardize search queries across different entity types in the application."]
1035
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
1036
+ // CIL[DOC-CONTRACT inputs="entity: string (required) — the name of the entity for which to retrieve the search field." outputs="string — the search field name associated with the entity or 'id' if not found." errors="none" side_effects="none"]
1037
+ // CIL[DOC-MICRO logic_summary="Retrieves the appropriate search field name for a given entity type. This function helps standardize search queries across different entity types in the application." notable_decisions="none"]
1038
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1039
+ // CIL[DOC-STABILITY stability="stable"]
1040
+ /**
1041
+ * Retrieves the appropriate search field name for a given entity type. This function helps standardize search queries across different entity types in the application.
1042
+ *
1043
+ * @inputSpec
1044
+ * entity: string (required) — the name of the entity for which to retrieve the search field.
1045
+ * @outputSpec string — the search field name associated with the entity or 'id' if not found.
1046
+ * @sideEffects none
1047
+ * @stability stable
1048
+ * @cil-generated
1049
+ */
1050
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:getsearchfield:function" type="function" identity="getSearchField" parent="~/.framework/functions/admin-data.ts"]
1051
+ // CIL[DOC-MACRO purpose="getSearchField function"]
1052
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the getSearchField function."]
1053
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
1054
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
1055
+ // CIL[DOC-MICRO logic_summary="Implements the getSearchField function." notable_decisions="[]"]
1056
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
1057
+ // CIL[DOC-STABILITY stability="stable"]
690
1058
  function getSearchField(entity: string): string {
691
1059
  const searchFields: Record<string, string> = {
692
1060
  accounts: 'display_name',
@@ -705,40 +1073,73 @@ function getSearchField(entity: string): string {
705
1073
  }
706
1074
  return searchFields[entity] || 'id'
707
1075
  }
708
- // CIL[END chunk_id="admin-data_getsearchfield_1784019432"]
709
- // CIL[BEGIN chunk_id="admin-data_entitysupportssoftdelete_1784019432" type="function" identity="entitySupportsSoftDelete" parent="none"]
710
- // CIL[DOC-MACRO purpose="Check if entity supports soft delete"]
711
- // CIL[DOC-RESPONSIBILITY responsibility="Determine soft delete capability for entity type"]
712
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[]"]
713
- // CIL[DOC-CONTRACT inputs="none" outputs="boolean:supports_soft_delete" errors="none" side_effects="none"]
714
- // CIL[DOC-MICRO logic_summary="Returns true if entity has is_active column for soft delete" notable_decisions="[]"]
715
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
716
- // CIL[DOC-STABILITY stability="stable"]
717
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
718
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
719
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
720
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1076
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:getsearchfield:function"]
1077
+ // CIL[DOC-VECTOR type="context" content="purpose='Retrieves the appropriate search field name for a given entity type.'; No verified external callers" status="ready"]
1078
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
1079
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
1080
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
721
1081
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
722
1082
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1083
+ // CIL[DOC-MACRO purpose="Determines if a given entity supports soft deletion by checking against a predefined list of entities."]
1084
+ // CIL[DOC-RESPONSIBILITY responsibility="Determines if a given entity supports soft deletion by checking against a predefined list of entities. This function exists to facilitate operations that depend on the soft delete capability of certain entities."]
1085
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
1086
+ // CIL[DOC-CONTRACT inputs="entity: string (required) — the name of the entity to check for soft delete support." outputs="boolean — returns true if the entity supports soft deletion, otherwise false." errors="none" side_effects="none"]
1087
+ // CIL[DOC-MICRO logic_summary="Determines if a given entity supports soft deletion by checking against a predefined list of entities. This function exists to facilitate operations that depend on the soft delete capability of certain entities." notable_decisions="none"]
1088
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1089
+ // CIL[DOC-STABILITY stability="stable"]
1090
+ /**
1091
+ * Determines if a given entity supports soft deletion by checking against a predefined list of entities. This function exists to facilitate operations that depend on the soft delete capability of certain entities.
1092
+ *
1093
+ * @inputSpec
1094
+ * entity: string (required) — the name of the entity to check for soft delete support.
1095
+ * @outputSpec boolean — returns true if the entity supports soft deletion, otherwise false.
1096
+ * @sideEffects none
1097
+ * @stability stable
1098
+ * @cil-generated
1099
+ */
1100
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:entitysupportssoftdelete:function" type="function" identity="entitySupportsSoftDelete" parent="~/.framework/functions/admin-data.ts"]
1101
+ // CIL[DOC-MACRO purpose="entitySupportsSoftDelete function"]
1102
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the entitySupportsSoftDelete function."]
1103
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
1104
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
1105
+ // CIL[DOC-MICRO logic_summary="Implements the entitySupportsSoftDelete function." notable_decisions="[]"]
1106
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
1107
+ // CIL[DOC-STABILITY stability="stable"]
723
1108
  function entitySupportsSoftDelete(entity: string): boolean {
724
1109
  const softDeleteEntities = ['accounts', 'people', 'items', 'threads', 'messages', 'watchers', 'item_progress', 'test_cases']
725
1110
  return softDeleteEntities.includes(entity)
726
1111
  }
727
- // CIL[END chunk_id="admin-data_entitysupportssoftdelete_1784019432"]
728
- // CIL[BEGIN chunk_id="admin-data_stats_1784019432" type="function" identity="stats" parent="none"]
729
- // CIL[DOC-MACRO purpose="Get record count for entity"]
730
- // CIL[DOC-RESPONSIBILITY responsibility="Return total record count with RLS filtering"]
731
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[]"]
732
- // CIL[DOC-CONTRACT inputs="none" outputs="{entity,count}" errors="entity_required,database_error" side_effects="database_count_query"]
733
- // CIL[DOC-MICRO logic_summary="Performs count query with RLS filtering applied" notable_decisions="[]"]
734
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
735
- // CIL[DOC-STABILITY stability="stable"]
736
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
737
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
738
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
739
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1112
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:entitysupportssoftdelete:function"]
1113
+ // CIL[DOC-VECTOR type="context" content="purpose='Determines if a given entity supports soft deletion by checking against a predefined list of entities.'; No verified external callers" status="ready"]
1114
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
1115
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
1116
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
740
1117
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
741
1118
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1119
+ // CIL[DOC-MACRO purpose="The 'stats' constant provides an asynchronous handler for retrieving the count of records for a specified entity in the database."]
1120
+ // CIL[DOC-RESPONSIBILITY responsibility="The 'stats' constant provides an asynchronous handler for retrieving the count of records for a specified entity in the database. It ensures that the entity is valid and logs the request for administrative purposes."]
1121
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
1122
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="Error — Valid entity parameter is required, Error — database query error." side_effects="none dependencies="withAdminLogging, ctx.db.from"]
1123
+ // CIL[DOC-MICRO logic_summary="The 'stats' constant provides an asynchronous handler for retrieving the count of records for a specified entity in the database. It ensures that the entity is valid and logs the request for administrative purposes." notable_decisions="none"]
1124
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1125
+ // CIL[DOC-STABILITY stability="stable"]
1126
+ /**
1127
+ * The 'stats' constant provides an asynchronous handler for retrieving the count of records for a specified entity in the database. It ensures that the entity is valid and logs the request for administrative purposes.
1128
+ *
1129
+ * @throws Error — Valid entity parameter is required, Error — database query error.
1130
+ * @sideEffects none
1131
+ * @stability stable
1132
+ * @calls withAdminLogging, ctx.db.from
1133
+ * @cil-generated
1134
+ */
1135
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:stats:constant" type="constant" identity="stats" parent="~/.framework/functions/admin-data.ts"]
1136
+ // CIL[DOC-MACRO purpose="stats constant"]
1137
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the stats constant."]
1138
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
1139
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
1140
+ // CIL[DOC-MICRO logic_summary="Implements the stats constant." notable_decisions="[]"]
1141
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
1142
+ // CIL[DOC-STABILITY stability="stable"]
742
1143
  export const stats = createHandler(async (ctx, _body) => {
743
1144
  const { entity } = ctx.query || {}
744
1145
  const method = ctx.query?.method || 'GET'
@@ -764,21 +1165,37 @@ export const stats = createHandler(async (ctx, _body) => {
764
1165
  }
765
1166
  )
766
1167
  })
767
- // CIL[END chunk_id="admin-data_stats_1784019432"]
768
- // CIL[BEGIN chunk_id="admin-data_handler_1784019432" type="function" identity="handler" parent="none"]
769
- // CIL[DOC-MACRO purpose="Route HTTP methods to appropriate CRUD handlers"]
770
- // CIL[DOC-RESPONSIBILITY responsibility="Dispatch requests based on method and action parameters"]
771
- // CIL[DOC-CONTEXT module="admin-data" layer="api-handler" related_files="[]"]
772
- // CIL[DOC-CONTRACT inputs="none" outputs="handler_response" errors="invalid_action_or_method" side_effects="delegates_to_crud_handlers"]
773
- // CIL[DOC-MICRO logic_summary="Routes GET/POST/PATCH/DELETE to list/get/create/update/remove/stats" notable_decisions="[]"]
774
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
775
- // CIL[DOC-STABILITY stability="stable"]
776
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
777
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
778
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
779
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
1168
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:stats:constant"]
1169
+ // CIL[DOC-VECTOR type="context" content="purpose='The 'stats' constant provides an asynchronous handler for retrieving the count of records for a specified entity in the database.'; No verified external callers" status="ready"]
1170
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
1171
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
1172
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
780
1173
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
781
1174
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
1175
+ // CIL[DOC-MACRO purpose="The handler processes incoming requests based on the specified action and HTTP method, routing them to the appropriate function."]
1176
+ // CIL[DOC-RESPONSIBILITY responsibility="The handler processes incoming requests based on the specified action and HTTP method, routing them to the appropriate function. It serves as a centralized entry point for managing various administrative data operations."]
1177
+ // CIL[DOC-CONTEXT module="admin-data" layer="app-specific" related_files=".framework/functions/_shared/middleware,.framework/functions/_shared/permissions,.framework/functions/_shared/db,.framework/functions/_shared/principal,.framework/functions/_shared/resolve-ids,.framework/functions/_shared/trigger-engine,.framework/functions/_shared/logging,.framework/functions/_shared/access"]
1178
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="Error — Invalid action or method" side_effects="none dependencies="list, get, stats, create, update, remove"]
1179
+ // CIL[DOC-MICRO logic_summary="The handler processes incoming requests based on the specified action and HTTP method, routing them to the appropriate function. It serves as a centralized entry point for managing various administrative data operations." notable_decisions="none"]
1180
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
1181
+ // CIL[DOC-STABILITY stability="stable"]
1182
+ /**
1183
+ * The handler processes incoming requests based on the specified action and HTTP method, routing them to the appropriate function. It serves as a centralized entry point for managing various administrative data operations.
1184
+ *
1185
+ * @throws Error — Invalid action or method
1186
+ * @sideEffects none
1187
+ * @stability stable
1188
+ * @calls list, get, stats, create, update, remove
1189
+ * @cil-generated
1190
+ */
1191
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-data.ts:handler:constant" type="constant" identity="handler" parent="~/.framework/functions/admin-data.ts"]
1192
+ // CIL[DOC-MACRO purpose="handler constant"]
1193
+ // CIL[DOC-RESPONSIBILITY responsibility="Implements the handler constant."]
1194
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-data.ts" layer="app-specific" related_files=""]
1195
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
1196
+ // CIL[DOC-MICRO logic_summary="Implements the handler constant." notable_decisions="[]"]
1197
+ // CIL[DOC-CONFIDENCE pass="first" score="0.8" flags="none"]
1198
+ // CIL[DOC-STABILITY stability="stable"]
782
1199
  export const handler = createHandler(async (ctx, body) => {
783
1200
  const { action } = ctx.query || {}
784
1201
  const method = ctx.query?.method || 'GET'
@@ -818,4 +1235,10 @@ export const handler = createHandler(async (ctx, body) => {
818
1235
 
819
1236
  throw new Error('Invalid action or method')
820
1237
  })
821
- // CIL[END chunk_id="admin-data_handler_1784019432"]
1238
+ // CIL[END stable_id="~/.framework/functions/admin-data.ts:handler:constant"]
1239
+ // CIL[DOC-VECTOR type="context" content="purpose='The handler processes incoming requests based on the specified action and HTTP method, routing them to the appropriate function.'; No verified external callers" status="ready"]
1240
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only" status="ready"]
1241
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
1242
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented" status="ready"]
1243
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
1244
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]