spine-framework 0.3.144 → 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 +20 -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,64 +1,62 @@
1
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-funnel.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/admin-funnel.ts"]
2
+ // CIL[DOC-MACRO purpose="Module-level imports for the admin funnel metrics handler"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Import shared middleware and database client used by the handler"]
4
+ // CIL[DOC-CONTEXT module="admin-funnel" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Dependency wiring for the admin funnel function" notable_decisions="Uses createHandler and adminDb from _shared"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stable]
9
+ // CIL[DOC-AUDIENCE audience="internal"]
1
10
 
2
- // CIL[BEGIN chunk_id="admin-funnel_module_header_1784019432" type="module_header" identity="imports" parent="none"]
3
- // CIL[DOC-MACRO purpose="Import dependencies for funnel metrics"]
4
- // CIL[DOC-RESPONSIBILITY responsibility="Provide middleware and admin database access"]
5
- // CIL[DOC-CONTEXT module="admin-funnel" layer="api-handler" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"\\\"]"]
6
- // CIL[DOC-CONTRACT inputs="none" outputs="imported_modules" errors="none" side_effects="none"]
7
- // CIL[DOC-MICRO logic_summary="Imports required modules for funnel analytics" notable_decisions="[]"]
8
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
9
- // CIL[DOC-STABILITY stability="stable"]
10
- // CIL[DOC-AUDIENCE audience="developer"]
11
- // 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/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, \."]
12
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
13
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
14
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
15
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
16
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
17
11
  import { createHandler } from './_shared/middleware'
18
12
  import { adminDb } from './_shared/db'
19
- // CIL[END chunk_id="admin-funnel_module_header_1784019432"]
20
- // CIL[BEGIN chunk_id="admin-funnel_metrics_1784019432" type="function" identity="metrics" parent="none"]
21
- // CIL[DOC-MACRO purpose="Calculate funnel metrics and conversion rates"]
22
- // CIL[DOC-RESPONSIBILITY responsibility="Aggregate funnel data across visitor journey stages"]
23
- // CIL[DOC-CONTEXT module="admin-funnel" layer="api-handler" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
24
- // CIL[DOC-CONTRACT inputs="none" outputs="funnel_metrics_object" errors="types_not_found" side_effects="database_queries,aggregation_calculations"]
25
- // CIL[DOC-MICRO logic_summary="Queries signals, sessions, instances; calculates conversion rates and stage distribution" notable_decisions="[]"]
26
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="external_symbols_unknown"]
27
- // CIL[DOC-STABILITY stability="stable"]
28
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/functions/_shared/principal.ts, \."]
29
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
30
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
31
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
13
+ // CIL[DOC-VECTOR type="context" content="purpose='Module-level imports for the admin funnel metrics handler'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
14
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
15
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
16
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
32
17
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
33
18
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
19
+ // CIL[END stable_id="~/.framework/functions/admin-funnel.ts:module_header:module_header"]
20
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-funnel.ts:metrics:constant" type="constant" identity="metrics" parent="~/.framework/functions/admin-funnel.ts"]
21
+ // CIL[DOC-MACRO purpose="Compute admin funnel metrics for the last 30 days"]
22
+ // CIL[DOC-RESPONSIBILITY responsibility="Query item type registry and items table to calculate visitor, user, install, and stage distribution metrics"]
23
+ // CIL[DOC-CONTEXT module="admin-funnel" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-funnel.ts"]
24
+ // CIL[DOC-CONTRACT inputs="ctx: RequestContext, body: request payload" outputs="anonymous_visitors, identified_users, installed_instances, conversion_rates, stage_distribution" errors="none — missing signal types degrade to zeroed metrics" side_effects="Reads from adminDb; no writes"]
25
+ // CIL[DOC-MICRO logic_summary="Resolve funnel_signal, anonymous_session, and spine_instance type IDs from types (kind='item'); count signals, anonymous sessions, identified accounts, and installed instances; return conversion rates and stage distribution" notable_decisions="Signal types are app-seeded, so absent types produce zeroed sections rather than errors; ignores signal items without account_id for stage counts; uses 30-day window; guards division with zero checks"]
26
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
27
+ // CIL[DOC-STABILITY stable]
34
28
  export const metrics = createHandler(async (ctx, body) => {
35
- const { data: signalType } = await adminDb
36
- .from('item_type_registry')
37
- .select('id')
38
- .eq('slug', 'funnel_signal')
39
- .single()
40
-
41
- const { data: sessionType } = await adminDb
42
- .from('item_type_registry')
43
- .select('id')
44
- .eq('slug', 'anonymous_session')
45
- .single()
46
-
47
- const { data: instanceType } = await adminDb
48
- .from('item_type_registry')
49
- .select('id')
50
- .eq('slug', 'spine_instance')
51
- .single()
29
+ const { data: typeRows } = await adminDb
30
+ .from('types')
31
+ .select('id, slug')
32
+ .eq('kind', 'item')
33
+ .in('slug', ['funnel_signal', 'anonymous_session', 'spine_instance'])
52
34
 
53
- if (!signalType || !sessionType || !instanceType) {
54
- throw new Error('Required types not found')
35
+ const typeIdFor = (slug: string) => typeRows?.find((t: any) => t.slug === slug)?.id || null
36
+ const signalTypeId = typeIdFor('funnel_signal')
37
+ const sessionTypeId = typeIdFor('anonymous_session')
38
+ const instanceTypeId = typeIdFor('spine_instance')
39
+
40
+ // Signal types are seeded by installed apps — a clean framework install
41
+ // legitimately has none, so degrade to zeroed metrics instead of 500s.
42
+ if (!signalTypeId && !sessionTypeId && !instanceTypeId) {
43
+ return {
44
+ anonymous_visitors: 0,
45
+ identified_users: 0,
46
+ installed_instances: 0,
47
+ conversion_rates: {
48
+ anonymous_to_identified: 0,
49
+ identified_to_installed: 0
50
+ },
51
+ stage_distribution: []
52
+ }
55
53
  }
56
54
 
57
- const { data: stageData } = await adminDb
55
+ const { data: stageData } = signalTypeId ? await adminDb
58
56
  .from('items')
59
57
  .select('data->>stage, account_id')
60
- .eq('type_id', signalType.id)
61
- .gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString())
58
+ .eq('type_id', signalTypeId)
59
+ .gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString()) : { data: [] }
62
60
 
63
61
  const stageCounts = stageData?.reduce((acc, item) => {
64
62
  const stage = item.data?.stage || 'unknown'
@@ -70,27 +68,27 @@ export const metrics = createHandler(async (ctx, body) => {
70
68
 
71
69
  const totalStageSignals = Object.values(stageCounts).reduce((sum, count) => sum + count, 0)
72
70
 
73
- const { count: anonymousSessions } = await adminDb
71
+ const { count: anonymousSessions } = sessionTypeId ? await adminDb
74
72
  .from('items')
75
73
  .select('*', { count: 'exact', head: true })
76
- .eq('type_id', sessionType.id)
74
+ .eq('type_id', sessionTypeId)
77
75
  .is('data->lifecycle->>stitched_to_account_id', null)
78
- .gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString())
76
+ .gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString()) : { count: 0 }
79
77
 
80
- const { data: accountData } = await adminDb
78
+ const { data: accountData } = signalTypeId ? await adminDb
81
79
  .from('items')
82
80
  .select('account_id')
83
- .eq('type_id', signalType.id)
81
+ .eq('type_id', signalTypeId)
84
82
  .gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString())
85
- .not('account_id', 'is', null)
83
+ .not('account_id', 'is', null) : { data: [] }
86
84
 
87
85
  const uniqueAccounts = new Set(accountData?.map(item => item.account_id)).size
88
86
 
89
- const { count: installedInstances } = await adminDb
87
+ const { count: installedInstances } = instanceTypeId ? await adminDb
90
88
  .from('items')
91
89
  .select('*', { count: 'exact', head: true })
92
- .eq('type_id', instanceType.id)
93
- .not('data->>claimed_by_person_id', 'is', null)
90
+ .eq('type_id', instanceTypeId)
91
+ .not('data->>claimed_by_person_id', 'is', null) : { count: 0 }
94
92
 
95
93
  const stageDistribution = Object.entries(stageCounts).map(([stage, count]) => ({
96
94
  stage,
@@ -112,4 +110,10 @@ export const metrics = createHandler(async (ctx, body) => {
112
110
  stage_distribution: stageDistribution
113
111
  }
114
112
  })
115
- // CIL[END chunk_id="admin-funnel_metrics_1784019432"]
113
+ // CIL[DOC-VECTOR type="context" content="purpose='Compute admin funnel metrics for the last 30 days'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
114
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
115
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
116
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
117
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
118
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
119
+ // CIL[END stable_id="~/.framework/functions/admin-funnel.ts:metrics:constant"]
@@ -1,59 +1,66 @@
1
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-install-funnel.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/admin-install-funnel.ts"]
2
+ // CIL[DOC-MACRO purpose="Netlify function entrypoint for install funnel admin metrics and export handlers"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Define admin metrics and exportData handler exports for the install-funnel function"]
4
+ // CIL[DOC-CONTEXT module="admin" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Imports shared middleware and database client for the install funnel admin endpoints" notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="admin-api consumer"]
1
10
 
2
11
 
3
- // CIL[BEGIN chunk_id="admin-install-funnel_module_header_1784019432" type="module_header" identity="imports" parent="none"]
4
- // CIL[DOC-MACRO purpose="Import dependencies for install funnel analytics"]
5
- // CIL[DOC-RESPONSIBILITY responsibility="Provide middleware and admin database access"]
6
- // CIL[DOC-CONTEXT module="admin-install-funnel" layer="api-handler" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/components/layout/Sidebar.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
7
- // CIL[DOC-CONTRACT inputs="none" outputs="imported_modules" errors="none" side_effects="none"]
8
- // CIL[DOC-MICRO logic_summary="Imports required modules for install funnel processing" notable_decisions="[]"]
9
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
10
- // CIL[DOC-STABILITY stability="stable"]
11
- // CIL[DOC-AUDIENCE audience="developer"]
12
- // 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/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/components/layout/Sidebar.tsx, .framework/functions/_shared/schema-utils.ts, \."]
13
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
14
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
15
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
16
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
17
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
18
12
  import { createHandler } from './_shared/middleware'
19
13
  import { adminDb } from './_shared/db'
20
- // CIL[END chunk_id="admin-install-funnel_module_header_1784019432"]
21
- // CIL[BEGIN chunk_id="admin-install-funnel_metrics_1784019432" type="function" identity="metrics" parent="none"]
22
- // CIL[DOC-MACRO purpose="Calculate install funnel metrics and trends"]
23
- // CIL[DOC-RESPONSIBILITY responsibility="Aggregate install data with conversion rates and version analytics"]
24
- // CIL[DOC-CONTEXT module="admin-install-funnel" layer="api-handler" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
25
- // CIL[DOC-CONTRACT inputs="none" outputs="install_metrics_object" errors="funnel_signal_type_not_found" side_effects="database_queries,aggregation_calculations,trend_analysis"]
26
- // CIL[DOC-MICRO logic_summary="Counts downloads/installs, calculates conversion rates, analyzes versions, tracks trends" notable_decisions="[]"]
27
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="external_symbols_unknown"]
28
- // CIL[DOC-STABILITY stability="stable"]
29
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/src/components/ui/dialog.tsx, \."]
30
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
31
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
32
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
14
+ // CIL[DOC-VECTOR type="context" content="purpose='Netlify function entrypoint for install funnel admin metrics and export handlers'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
15
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
16
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
17
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
33
18
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
34
19
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
20
+ // CIL[END stable_id="~/.framework/functions/admin-install-funnel.ts:module_header:module_header"]
21
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-install-funnel.ts:metrics:constant" type="constant" identity="metrics" parent="~/.framework/functions/admin-install-funnel.ts"]
22
+ // CIL[DOC-MACRO purpose="Serve install funnel metrics including downloads, installs, first use, claimed, trends and version breakdown"]
23
+ // CIL[DOC-RESPONSIBILITY responsibility="Compute and return install funnel analytics from the item registry"]
24
+ // CIL[DOC-CONTEXT module="admin" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-install-funnel.ts"]
25
+ // CIL[DOC-CONTRACT inputs="admin request context and body" outputs="JSON metrics object with funnel counts, trends, recent installs and top versions" errors="none — missing signal types degrade to zeroed metrics" side_effects="none"]
26
+ // CIL[DOC-MICRO logic_summary="Resolves the funnel_signal and spine_instance types, aggregates counts, formats recent installs and computes 30-day daily trends" notable_decisions="Signal types are app-seeded, so absent types produce zeroed sections rather than errors"]
27
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
28
+ // CIL[DOC-STABILITY stability="stable"]
35
29
  export const metrics = createHandler(async (ctx, body) => {
36
- const { data: signalType } = await adminDb
37
- .from('item_type_registry')
38
- .select('id')
39
- .eq('slug', 'funnel_signal')
40
- .single()
41
-
42
- if (!signalType) {
43
- throw new Error('funnel_signal type not found')
30
+ const { data: typeRows } = await adminDb
31
+ .from('types')
32
+ .select('id, slug')
33
+ .eq('kind', 'item')
34
+ .in('slug', ['funnel_signal', 'spine_instance'])
35
+
36
+ const signalTypeId = typeRows?.find((t: any) => t.slug === 'funnel_signal')?.id || null
37
+ const instanceTypeId = typeRows?.find((t: any) => t.slug === 'spine_instance')?.id || null
38
+
39
+ // Signal types are seeded by installed apps — a clean framework install
40
+ // legitimately has none, so degrade to zeroed metrics instead of 500s.
41
+ if (!signalTypeId) {
42
+ return {
43
+ total_downloads: 0,
44
+ unique_installers: 0,
45
+ active_instances: 0,
46
+ conversion_funnel: { downloads: 0, installations: 0, first_use: 0, claimed: 0 },
47
+ install_trends: [],
48
+ recent_installs: [],
49
+ top_versions: []
50
+ }
44
51
  }
45
52
 
46
53
  const { count: totalDownloads } = await adminDb
47
54
  .from('items')
48
55
  .select('*', { count: 'exact', head: true })
49
- .eq('type_id', signalType.id)
56
+ .eq('type_id', signalTypeId)
50
57
  .eq('data->>source', 'inst')
51
58
  .eq('data->>action_type', 'download')
52
59
 
53
60
  const { data: installerData } = await adminDb
54
61
  .from('items')
55
62
  .select('data->>serial')
56
- .eq('type_id', signalType.id)
63
+ .eq('type_id', signalTypeId)
57
64
  .eq('data->>source', 'inst')
58
65
  .not('data->>serial', 'is', null)
59
66
 
@@ -63,7 +70,7 @@ export const metrics = createHandler(async (ctx, body) => {
63
70
  const { count: activeInstances } = await adminDb
64
71
  .from('items')
65
72
  .select('*', { count: 'exact', head: true })
66
- .eq('type_id', signalType.id)
73
+ .eq('type_id', signalTypeId)
67
74
  .eq('data->>source', 'inst')
68
75
  .not('data->>serial', 'is', null)
69
76
  .gte('created_at', sevenDaysAgo)
@@ -71,21 +78,21 @@ export const metrics = createHandler(async (ctx, body) => {
71
78
  const { count: installations } = await adminDb
72
79
  .from('items')
73
80
  .select('*', { count: 'exact', head: true })
74
- .eq('type_id', signalType.id)
81
+ .eq('type_id', signalTypeId)
75
82
  .eq('data->>source', 'inst')
76
83
  .eq('data->>action_type', 'install')
77
84
 
78
85
  const { count: firstUse } = await adminDb
79
86
  .from('items')
80
87
  .select('*', { count: 'exact', head: true })
81
- .eq('type_id', signalType.id)
88
+ .eq('type_id', signalTypeId)
82
89
  .eq('data->>source', 'inst')
83
90
  .eq('data->>action_type', 'first_command')
84
91
 
85
92
  const { count: claimed } = await adminDb
86
93
  .from('items')
87
94
  .select('*', { count: 'exact', head: true })
88
- .eq('type_id', signalType.id)
95
+ .eq('type_id', signalTypeId)
89
96
  .eq('data->>source', 'inst')
90
97
  .not('data->>claimed_by_person_id', 'is', null)
91
98
 
@@ -101,10 +108,10 @@ export const metrics = createHandler(async (ctx, body) => {
101
108
  data->>claimed_by_person_id,
102
109
  data->>claimed_at,
103
110
  account_id,
104
- people(email),
111
+ people!fk_items_created_by(email),
105
112
  accounts(name)
106
113
  `)
107
- .eq('type_id', signalType.id)
114
+ .eq('type_id', signalTypeId)
108
115
  .eq('data->>source', 'inst')
109
116
  .not('data->>serial', 'is', null)
110
117
  .order('created_at', { ascending: false })
@@ -123,10 +130,10 @@ export const metrics = createHandler(async (ctx, body) => {
123
130
  person_email: instance.people?.email
124
131
  }))
125
132
 
126
- const { data: versionData } = await adminDb
133
+ const { data: versionData } = instanceTypeId ? await adminDb
127
134
  .from('items')
128
135
  .select('data->>version')
129
- .eq('type_id', instanceType.id)
136
+ .eq('type_id', instanceTypeId) : { data: [] }
130
137
 
131
138
  const versionCounts = versionData?.reduce((acc, item) => {
132
139
  const version = item.data?.version || 'unknown'
@@ -156,7 +163,7 @@ export const metrics = createHandler(async (ctx, body) => {
156
163
  const { count: dailyDownloads } = await adminDb
157
164
  .from('items')
158
165
  .select('*', { count: 'exact', head: true })
159
- .eq('type_id', signalType.id)
166
+ .eq('type_id', signalTypeId)
160
167
  .eq('data->>source', 'inst')
161
168
  .eq('data->>action_type', 'download')
162
169
  .gte('created_at', dateStr)
@@ -165,7 +172,7 @@ export const metrics = createHandler(async (ctx, body) => {
165
172
  const { count: dailyInstalls } = await adminDb
166
173
  .from('items')
167
174
  .select('*', { count: 'exact', head: true })
168
- .eq('type_id', signalType.id)
175
+ .eq('type_id', signalTypeId)
169
176
  .eq('data->>source', 'inst')
170
177
  .eq('data->>action_type', 'install')
171
178
  .gte('created_at', dateStr)
@@ -193,30 +200,35 @@ export const metrics = createHandler(async (ctx, body) => {
193
200
  top_versions: topVersions
194
201
  }
195
202
  })
196
- // CIL[END chunk_id="admin-install-funnel_metrics_1784019432"]
197
- // CIL[BEGIN chunk_id="admin-install-funnel_exportdata_1784019432" type="function" identity="exportData" parent="none"]
198
- // CIL[DOC-MACRO purpose="Export all install instances with full details"]
199
- // CIL[DOC-RESPONSIBILITY responsibility="Provide complete install data for analysis and reporting"]
200
- // CIL[DOC-CONTEXT module="admin-install-funnel" layer="api-handler" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/components/layout/Sidebar.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
201
- // CIL[DOC-CONTRACT inputs="none" outputs="export_data_object" errors="funnel_signal_type_not_found" side_effects="database_query,data_export"]
202
- // CIL[DOC-MICRO logic_summary="Queries all install instances with full details and metadata" notable_decisions="[]"]
203
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
204
- // CIL[DOC-STABILITY stability="stable"]
205
- // 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/components/layout/Sidebar.tsx, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
206
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
207
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
208
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
203
+ // CIL[DOC-VECTOR type="context" content="purpose='Serve install funnel metrics including downloads, installs, first use, claimed, trends and version breakdown'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
204
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
205
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
206
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
209
207
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
210
208
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
209
+ // CIL[END stable_id="~/.framework/functions/admin-install-funnel.ts:metrics:constant"]
210
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-install-funnel.ts:exportData:constant" type="constant" identity="exportData" parent="~/.framework/functions/admin-install-funnel.ts"]
211
+ // CIL[DOC-MACRO purpose="Export raw install funnel instance records with contact and account details"]
212
+ // CIL[DOC-RESPONSIBILITY responsibility="Return all funnel_signal instances with source 'inst' and a non-null serial"]
213
+ // CIL[DOC-CONTEXT module="admin" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-install-funnel.ts"]
214
+ // CIL[DOC-CONTRACT inputs="admin request context and body" outputs="JSON object with instances array, exported_at and total_count" errors="none" side_effects="none"]
215
+ // CIL[DOC-MICRO logic_summary="Selects instances with joined people and accounts, ordered by created_at descending" notable_decisions="[]"]
216
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
217
+ // CIL[DOC-STABILITY stability="stable"]
211
218
  export const exportData = createHandler(async (ctx, body) => {
212
219
  const { data: signalType } = await adminDb
213
- .from('item_type_registry')
220
+ .from('types')
214
221
  .select('id')
222
+ .eq('kind', 'item')
215
223
  .eq('slug', 'funnel_signal')
216
- .single()
224
+ .maybeSingle()
217
225
 
218
226
  if (!signalType) {
219
- throw new Error('funnel_signal type not found')
227
+ return {
228
+ instances: [],
229
+ exported_at: new Date().toISOString(),
230
+ total_count: 0
231
+ }
220
232
  }
221
233
 
222
234
  const { data: instances } = await adminDb
@@ -227,7 +239,7 @@ export const exportData = createHandler(async (ctx, body) => {
227
239
  updated_at,
228
240
  data,
229
241
  account_id,
230
- people(email),
242
+ people!fk_items_created_by(email),
231
243
  accounts(name)
232
244
  `)
233
245
  .eq('type_id', signalType.id)
@@ -241,4 +253,10 @@ export const exportData = createHandler(async (ctx, body) => {
241
253
  total_count: instances?.length || 0
242
254
  }
243
255
  })
244
- // CIL[END chunk_id="admin-install-funnel_exportdata_1784019432"]
256
+ // CIL[DOC-VECTOR type="context" content="purpose='Export raw install funnel instance records with contact and account details'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
257
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
258
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
259
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
260
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
261
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
262
+ // CIL[END stable_id="~/.framework/functions/admin-install-funnel.ts:exportData:constant"]
@@ -1,50 +1,54 @@
1
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-signals.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/admin-signals.ts"]
2
+ // CIL[DOC-MACRO purpose="Declares the admin-signals function module and its imports"]
3
+ // CIL[DOC-RESPONSIBILITY responsibility="Set up module context and shared dependencies"]
4
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-signals.ts" layer="functions" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts"]
5
+ // CIL[DOC-CONTRACT inputs="none" outputs="module scope" errors="none" side_effects="none"]
6
+ // CIL[DOC-MICRO logic_summary="Module header that imports shared middleware and database client for admin signal handlers." notable_decisions="[]"]
7
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
8
+ // CIL[DOC-STABILITY stability="stable"]
9
+ // CIL[DOC-AUDIENCE audience="system-admin, developer"]
1
10
 
2
11
 
3
- // CIL[BEGIN chunk_id="admin-signals_module_header_1784019432" type="module_header" identity="imports" parent="none"]
4
- // CIL[DOC-MACRO purpose="Import dependencies for signal analytics"]
5
- // CIL[DOC-RESPONSIBILITY responsibility="Provide middleware and admin database access"]
6
- // CIL[DOC-CONTEXT module="admin-signals" layer="api-handler" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"\\\"]"]
7
- // CIL[DOC-CONTRACT inputs="none" outputs="imported_modules" errors="none" side_effects="none"]
8
- // CIL[DOC-MICRO logic_summary="Imports required modules for signal processing" notable_decisions="[]"]
9
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
10
- // CIL[DOC-STABILITY stability="stable"]
11
- // CIL[DOC-AUDIENCE audience="developer"]
12
- // 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/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, \."]
13
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
14
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
15
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
16
- // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
17
- // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
18
12
  import { createHandler } from './_shared/middleware'
19
13
  import { adminDb } from './_shared/db'
20
- // CIL[END chunk_id="admin-signals_module_header_1784019432"]
21
- // CIL[BEGIN chunk_id="admin-signals_metrics_1784019432" type="function" identity="metrics" parent="none"]
22
- // CIL[DOC-MACRO purpose="Calculate signal metrics and analytics"]
23
- // CIL[DOC-RESPONSIBILITY responsibility="Aggregate signal data with conversion rates and trends"]
24
- // CIL[DOC-CONTEXT module="admin-signals" layer="api-handler" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
25
- // CIL[DOC-CONTRACT inputs="none" outputs="signal_metrics_object" errors="funnel_signal_type_not_found" side_effects="database_queries,aggregation_calculations"]
26
- // CIL[DOC-MICRO logic_summary="Counts signals by time periods, calculates sources, formats recent signals, computes conversion rates" notable_decisions="[]"]
27
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="external_symbols_unknown"]
28
- // CIL[DOC-STABILITY stability="stable"]
29
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/functions/_shared/principal.ts, \."]
30
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
31
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
32
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
14
+ // CIL[DOC-VECTOR type="context" content="purpose='Declares the admin-signals function module and its imports'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
15
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
16
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
17
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
33
18
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
34
19
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
20
+ // CIL[END stable_id="~/.framework/functions/admin-signals.ts:module_header:module_header"]
21
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-signals.ts:metrics:constant" type="constant" identity="metrics" parent="~/.framework/functions/admin-signals.ts"]
22
+ // CIL[DOC-MACRO purpose="Aggregate funnel signal metrics for the admin dashboard"]
23
+ // CIL[DOC-RESPONSIBILITY responsibility="Compute and return totals, daily and weekly counts, conversion rate, top sources, and recent signals"]
24
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-signals.ts" layer="functions" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-signals.ts"]
25
+ // CIL[DOC-CONTRACT inputs="ctx, body" outputs="JSON metrics object" errors="none — missing signal types degrade to zeroed metrics" side_effects="Queries adminDb"]
26
+ // CIL[DOC-MICRO logic_summary="Resolves funnel_signal item type, runs count and select queries over items, aggregates source distribution over the past week, computes conversion rate, and formats the most recent signals." notable_decisions="[]"]
27
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
28
+ // CIL[DOC-STABILITY stability="stable"]
35
29
  export const metrics = createHandler(async (ctx, body) => {
36
30
  const now = new Date()
37
31
  const today = now.toISOString().split('T')[0]
38
32
  const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000).toISOString()
39
33
 
40
34
  const { data: signalType } = await adminDb
41
- .from('item_type_registry')
35
+ .from('types')
42
36
  .select('id')
37
+ .eq('kind', 'item')
43
38
  .eq('slug', 'funnel_signal')
44
- .single()
45
-
39
+ .maybeSingle()
40
+
41
+ // Signal types are seeded by installed apps — a clean framework install
42
+ // legitimately has none, so degrade to zeroed metrics instead of 500s.
46
43
  if (!signalType) {
47
- throw new Error('funnel_signal type not found')
44
+ return {
45
+ total_signals: 0,
46
+ signals_today: 0,
47
+ signals_this_week: 0,
48
+ conversion_rate: 0,
49
+ top_sources: [],
50
+ recent_signals: []
51
+ }
48
52
  }
49
53
 
50
54
  const { count: totalSignals } = await adminDb
@@ -125,21 +129,21 @@ export const metrics = createHandler(async (ctx, body) => {
125
129
  recent_signals: formattedSignals || []
126
130
  }
127
131
  })
128
- // CIL[END chunk_id="admin-signals_metrics_1784019432"]
129
- // CIL[BEGIN chunk_id="admin-signals_audit_1784019432" type="function" identity="audit" parent="none"]
130
- // CIL[DOC-MACRO purpose="Audit and export signal data with filtering"]
131
- // CIL[DOC-RESPONSIBILITY responsibility="Provide searchable, filterable signal audit trail"]
132
- // CIL[DOC-CONTEXT module="admin-signals" layer="api-handler" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/functions/_shared/db.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
133
- // CIL[DOC-CONTRACT inputs="none" outputs="paginated_signals_or_export_data" errors="funnel_signal_type_not_found" side_effects="database_queries,data_formatting"]
134
- // CIL[DOC-MICRO logic_summary="Builds filtered query, applies pagination, formats signal data for audit/export" notable_decisions="[]"]
135
- // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="external_symbols_unknown"]
136
- // CIL[DOC-STABILITY stability="stable"]
137
- // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/functions/_shared/db.ts, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/schema-utils.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
138
- // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
139
- // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
140
- // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
132
+ // CIL[DOC-VECTOR type="context" content="purpose='Aggregate funnel signal metrics for the admin dashboard'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
133
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
134
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
135
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
141
136
  // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
142
137
  // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
138
+ // CIL[END stable_id="~/.framework/functions/admin-signals.ts:metrics:constant"]
139
+ // CIL[BEGIN stable_id="~/.framework/functions/admin-signals.ts:audit:constant" type="constant" identity="audit" parent="~/.framework/functions/admin-signals.ts"]
140
+ // CIL[DOC-MACRO purpose="List and optionally export funnel signal audit records"]
141
+ // CIL[DOC-RESPONSIBILITY responsibility="Fetch paginated signal records, apply query filters, and support CSV-like export"]
142
+ // CIL[DOC-CONTEXT module=".framework/functions/admin-signals.ts" layer="functions" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-signals.ts"]
143
+ // CIL[DOC-CONTRACT inputs="ctx, body and ctx.query filter parameters" outputs="Object with signals array, total, page, limit or formatted array for export" errors="query failure throws; missing signal type degrades to an empty page" side_effects="Queries adminDb"]
144
+ // CIL[DOC-MICRO logic_summary="Resolves funnel_signal item type, builds a filtered query over items including related accounts and people, optionally paginates, returns full data for export, and formats each row." notable_decisions="[]"]
145
+ // CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
146
+ // CIL[DOC-STABILITY stability="stable"]
143
147
  export const audit = createHandler(async (ctx, body) => {
144
148
  const {
145
149
  page = '1',
@@ -156,13 +160,21 @@ export const audit = createHandler(async (ctx, body) => {
156
160
  } = ctx.query || {}
157
161
 
158
162
  const { data: signalType } = await adminDb
159
- .from('item_type_registry')
163
+ .from('types')
160
164
  .select('id')
165
+ .eq('kind', 'item')
161
166
  .eq('slug', 'funnel_signal')
162
- .single()
163
-
167
+ .maybeSingle()
168
+
169
+ // Signal types are seeded by installed apps — degrade to an empty page.
164
170
  if (!signalType) {
165
- throw new Error('funnel_signal type not found')
171
+ if (exportData) return []
172
+ return {
173
+ signals: [],
174
+ total: 0,
175
+ page: parseInt(page),
176
+ limit: parseInt(limit)
177
+ }
166
178
  }
167
179
 
168
180
  let query = adminDb
@@ -183,7 +195,7 @@ export const audit = createHandler(async (ctx, body) => {
183
195
  data->attribution->>utm_medium,
184
196
  data->attribution->>utm_campaign,
185
197
  account_id,
186
- people(email),
198
+ people!fk_items_created_by(email),
187
199
  accounts(name)
188
200
  `, { count: 'exact' })
189
201
  .eq('type_id', signalType.id)
@@ -256,4 +268,10 @@ export const audit = createHandler(async (ctx, body) => {
256
268
  limit: parseInt(limit)
257
269
  }
258
270
  })
259
- // CIL[END chunk_id="admin-signals_audit_1784019432"]
271
+ // CIL[DOC-VECTOR type="context" content="purpose='List and optionally export funnel signal audit records'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
272
+ // CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
273
+ // CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
274
+ // CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
275
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
276
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
277
+ // CIL[END stable_id="~/.framework/functions/admin-signals.ts:audit:constant"]