spine-framework 0.3.125 → 0.3.127

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/.framework/cli/commands/agents.ts +35 -37
  2. package/.framework/cli/commands/auth.ts +35 -34
  3. package/.framework/cli/commands/create-app.ts +104 -40
  4. package/.framework/cli/commands/dev.ts +104 -69
  5. package/.framework/cli/commands/doctor.ts +169 -97
  6. package/.framework/cli/commands/generate.ts +82 -161
  7. package/.framework/cli/commands/init.ts +72 -34
  8. package/.framework/cli/commands/install-app.ts +260 -125
  9. package/.framework/cli/commands/items.ts +33 -44
  10. package/.framework/cli/commands/migrate.ts +122 -40
  11. package/.framework/cli/commands/migrations.ts +33 -40
  12. package/.framework/cli/commands/pipelines.ts +31 -39
  13. package/.framework/cli/commands/status.ts +47 -23
  14. package/.framework/cli/commands/system.ts +47 -37
  15. package/.framework/cli/commands/test.ts +112 -68
  16. package/.framework/cli/commands/validate-app.ts +215 -121
  17. package/.framework/cli/context.ts +112 -130
  18. package/.framework/cli/env-loader.ts +47 -18
  19. package/.framework/cli/index.ts +81 -42
  20. package/.framework/docs/runtime-types.md +1024 -0
  21. package/.framework/functions/_shared/agent-runner.ts +1296 -961
  22. package/.framework/functions/_shared/app-manifest.ts +82 -68
  23. package/.framework/functions/_shared/audit.ts +135 -83
  24. package/.framework/functions/_shared/{cil-state.ts → cil.ts} +147 -54
  25. package/.framework/functions/_shared/db.ts +80 -126
  26. package/.framework/functions/_shared/hash-api-key.ts +63 -0
  27. package/.framework/functions/_shared/index.ts +222 -347
  28. package/.framework/functions/_shared/kb.ts +319 -0
  29. package/.framework/functions/_shared/llm.ts +92 -0
  30. package/.framework/functions/_shared/logging.ts +288 -0
  31. package/.framework/functions/_shared/middleware.ts +329 -365
  32. package/.framework/functions/_shared/outcomes.ts +36 -0
  33. package/.framework/functions/_shared/permissions.ts +359 -643
  34. package/.framework/functions/_shared/pipeline-runner.ts +243 -316
  35. package/.framework/functions/_shared/principal.ts +376 -468
  36. package/.framework/functions/_shared/resolve-credentials.ts +102 -0
  37. package/.framework/functions/_shared/resolve-ids.ts +162 -14
  38. package/.framework/functions/_shared/retry-deliveries.ts +104 -0
  39. package/.framework/functions/_shared/schema-utils.ts +611 -373
  40. package/.framework/functions/_shared/testing.ts +207 -137
  41. package/.framework/functions/_shared/tracing.ts +276 -0
  42. package/.framework/functions/_shared/trigger-engine.ts +159 -211
  43. package/.framework/functions/_shared/webhook-registration.ts +95 -81
  44. package/.framework/functions/_shared/webhook-registry.ts +153 -75
  45. package/.framework/functions/account-nodes.ts +31 -53
  46. package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
  47. package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
  48. package/.framework/functions/adapters/openai-outbound.ts +40 -0
  49. package/.framework/functions/admin-data.ts +687 -533
  50. package/.framework/functions/admin-funnel.ts +31 -20
  51. package/.framework/functions/admin-install-funnel.ts +47 -28
  52. package/.framework/functions/admin-signals.ts +47 -29
  53. package/.framework/functions/ai-agents.ts +122 -147
  54. package/.framework/functions/ai-interactions.ts +180 -90
  55. package/.framework/functions/api-keys.ts +250 -192
  56. package/.framework/functions/apps.ts +203 -197
  57. package/.framework/functions/auth.ts +98 -91
  58. package/.framework/functions/cil-agent-ingest.ts +773 -0
  59. package/.framework/functions/cil-agent.ts +592 -0
  60. package/.framework/functions/cil-callmap.ts +1227 -0
  61. package/.framework/functions/cil-config.ts +583 -0
  62. package/.framework/functions/cil-context.ts +445 -0
  63. package/.framework/functions/cil-doc.ts +1752 -0
  64. package/.framework/functions/cil-embeddings.ts +1202 -0
  65. package/.framework/functions/cil-graph.ts +585 -0
  66. package/.framework/functions/cil-ingest.ts +2416 -0
  67. package/.framework/functions/cil-pipeline.ts +318 -0
  68. package/.framework/functions/cil-project.ts +499 -0
  69. package/.framework/functions/cil-validate.ts +469 -0
  70. package/.framework/functions/debug-auth.ts +73 -53
  71. package/.framework/functions/deliveries.ts +117 -0
  72. package/.framework/functions/embeddings.ts +528 -516
  73. package/.framework/functions/eval-harness.ts +158 -106
  74. package/.framework/functions/integration-outbound.ts +311 -0
  75. package/.framework/functions/integration-routes.ts +240 -466
  76. package/.framework/functions/integrations.ts +132 -140
  77. package/.framework/functions/invites.ts +401 -201
  78. package/.framework/functions/item-progress.ts +113 -53
  79. package/.framework/functions/kb.ts +28 -0
  80. package/.framework/functions/logs.ts +239 -222
  81. package/.framework/functions/observability.ts +308 -259
  82. package/.framework/functions/pipeline-executions.ts +179 -235
  83. package/.framework/functions/pipelines.ts +163 -205
  84. package/.framework/functions/prompt-configs.ts +109 -156
  85. package/.framework/functions/roles.ts +97 -147
  86. package/.framework/functions/system-cron.ts +132 -218
  87. package/.framework/functions/system.ts +112 -52
  88. package/.framework/functions/tests.ts +32 -28
  89. package/.framework/functions/timers.ts +162 -210
  90. package/.framework/functions/triggers.ts +282 -346
  91. package/.framework/functions/types.ts +283 -400
  92. package/.framework/migrations/001_core_schema.sql +630 -0
  93. package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
  94. package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
  95. package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
  96. package/.framework/migrations/005_core_observability.sql +598 -0
  97. package/.framework/migrations/006_security_hardening_rls.sql +97 -0
  98. package/.framework/migrations/007_kb_article_list.sql +237 -0
  99. package/.framework/migrations/008_items_target.sql +8 -0
  100. package/.framework/migrations/009_roles_slug_unique.sql +11 -0
  101. package/.framework/public/spine.config.json +91 -0
  102. package/.framework/scripts/app-install-cli.ts +112 -98
  103. package/.framework/src/App.tsx +67 -20
  104. package/.framework/src/apps/admin/index.tsx +97 -27
  105. package/.framework/src/components/AppWrapper.tsx +50 -11
  106. package/.framework/src/components/CustomAppLoader.tsx +131 -22
  107. package/.framework/src/components/admin/AdminListPage.tsx +75 -8
  108. package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
  109. package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
  110. package/.framework/src/components/admin/PageInstructions.tsx +49 -0
  111. package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
  112. package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
  113. package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
  114. package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
  115. package/.framework/src/components/app-sidebar.tsx +50 -3
  116. package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
  117. package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
  118. package/.framework/src/components/kb/KBArticleList.tsx +557 -0
  119. package/.framework/src/components/layout/AppShell.tsx +54 -16
  120. package/.framework/src/components/layout/Header.tsx +50 -38
  121. package/.framework/src/components/layout/Layout.tsx +48 -32
  122. package/.framework/src/components/layout/Sidebar.tsx +167 -16
  123. package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
  124. package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
  125. package/.framework/src/components/runtime/DataFilters.tsx +78 -1
  126. package/.framework/src/components/runtime/DataHeader.tsx +32 -29
  127. package/.framework/src/components/runtime/DataListPage.tsx +161 -2
  128. package/.framework/src/components/runtime/DataStats.tsx +48 -1
  129. package/.framework/src/components/runtime/DataTable.tsx +153 -1
  130. package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
  131. package/.framework/src/components/runtime/index.ts +16 -9
  132. package/.framework/src/components/search-form.tsx +33 -1
  133. package/.framework/src/components/shared/AgentView.tsx +48 -51
  134. package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
  135. package/.framework/src/components/shared/InviteManager.tsx +113 -52
  136. package/.framework/src/components/shared/MemberList.tsx +182 -0
  137. package/.framework/src/components/shared/SchemaFields.tsx +96 -78
  138. package/.framework/src/components/ui/DataTable.tsx +86 -56
  139. package/.framework/src/components/ui/Form.tsx +188 -109
  140. package/.framework/src/components/ui/ItemCard.tsx +86 -58
  141. package/.framework/src/components/ui/ItemListView.tsx +88 -61
  142. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
  143. package/.framework/src/components/ui/Modal.tsx +81 -4
  144. package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
  145. package/.framework/src/components/ui/accordion.tsx +97 -5
  146. package/.framework/src/components/ui/alert-dialog.tsx +225 -13
  147. package/.framework/src/components/ui/alert.tsx +113 -6
  148. package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
  149. package/.framework/src/components/ui/avatar.tsx +129 -7
  150. package/.framework/src/components/ui/badge.tsx +65 -3
  151. package/.framework/src/components/ui/breadcrumb.tsx +145 -8
  152. package/.framework/src/components/ui/button-group.tsx +81 -4
  153. package/.framework/src/components/ui/button.tsx +49 -2
  154. package/.framework/src/components/ui/calendar.tsx +65 -3
  155. package/.framework/src/components/ui/card.tsx +145 -8
  156. package/.framework/src/components/ui/carousel.tsx +129 -7
  157. package/.framework/src/components/ui/chart.tsx +161 -10
  158. package/.framework/src/components/ui/checkbox.tsx +49 -2
  159. package/.framework/src/components/ui/collapsible.tsx +81 -5
  160. package/.framework/src/components/ui/combobox.tsx +305 -20
  161. package/.framework/src/components/ui/command.tsx +177 -11
  162. package/.framework/src/components/ui/context-menu.tsx +273 -17
  163. package/.framework/src/components/ui/dialog.tsx +209 -27
  164. package/.framework/src/components/ui/direction.tsx +64 -4
  165. package/.framework/src/components/ui/drawer.tsx +193 -12
  166. package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
  167. package/.framework/src/components/ui/empty.tsx +145 -9
  168. package/.framework/src/components/ui/field.tsx +209 -14
  169. package/.framework/src/components/ui/hover-card.tsx +81 -4
  170. package/.framework/src/components/ui/input-group.tsx +162 -10
  171. package/.framework/src/components/ui/input-otp.tsx +98 -5
  172. package/.framework/src/components/ui/input.tsx +49 -2
  173. package/.framework/src/components/ui/item.tsx +225 -13
  174. package/.framework/src/components/ui/kbd.tsx +65 -3
  175. package/.framework/src/components/ui/label.tsx +49 -2
  176. package/.framework/src/components/ui/menubar.tsx +289 -17
  177. package/.framework/src/components/ui/native-select.tsx +97 -5
  178. package/.framework/src/components/ui/navigation-menu.tsx +177 -10
  179. package/.framework/src/components/ui/pagination.tsx +161 -9
  180. package/.framework/src/components/ui/popover.tsx +145 -8
  181. package/.framework/src/components/ui/progress.tsx +49 -2
  182. package/.framework/src/components/ui/radio-group.tsx +65 -3
  183. package/.framework/src/components/ui/resizable.tsx +82 -4
  184. package/.framework/src/components/ui/scroll-area.tsx +65 -3
  185. package/.framework/src/components/ui/select.tsx +193 -11
  186. package/.framework/src/components/ui/separator.tsx +49 -2
  187. package/.framework/src/components/ui/sheet.tsx +193 -11
  188. package/.framework/src/components/ui/sidebar.tsx +481 -38
  189. package/.framework/src/components/ui/skeleton.tsx +49 -2
  190. package/.framework/src/components/ui/slider.tsx +49 -2
  191. package/.framework/src/components/ui/sonner.tsx +49 -2
  192. package/.framework/src/components/ui/spinner.tsx +49 -2
  193. package/.framework/src/components/ui/switch.tsx +49 -2
  194. package/.framework/src/components/ui/table-primitives.tsx +160 -33
  195. package/.framework/src/components/ui/table.tsx +161 -9
  196. package/.framework/src/components/ui/tabs.tsx +113 -6
  197. package/.framework/src/components/ui/textarea.tsx +49 -2
  198. package/.framework/src/components/ui/toggle-group.tsx +81 -4
  199. package/.framework/src/components/ui/toggle.tsx +65 -3
  200. package/.framework/src/components/ui/tooltip.tsx +97 -5
  201. package/.framework/src/contexts/AppContext.tsx +129 -45
  202. package/.framework/src/contexts/AuthContext.tsx +173 -145
  203. package/.framework/src/hooks/use-mobile.ts +48 -2
  204. package/.framework/src/hooks/useApi.ts +208 -159
  205. package/.framework/src/hooks/useAppPath.ts +32 -23
  206. package/.framework/src/hooks/useApps.ts +51 -20
  207. package/.framework/src/hooks/useEntityList.ts +32 -78
  208. package/.framework/src/hooks/useEntityRecord.ts +35 -96
  209. package/.framework/src/hooks/useForm.ts +32 -92
  210. package/.framework/src/hooks/useListSchema.ts +49 -78
  211. package/.framework/src/hooks/useSchemaRecord.ts +114 -105
  212. package/.framework/src/lib/api.ts +192 -115
  213. package/.framework/src/lib/supabase.ts +98 -64
  214. package/.framework/src/lib/utils.ts +287 -151
  215. package/.framework/src/main.tsx +49 -3
  216. package/.framework/src/pages/DashboardPage.tsx +52 -29
  217. package/.framework/src/pages/NotFoundPage.tsx +32 -10
  218. package/.framework/src/pages/SetupPage.tsx +32 -12
  219. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
  220. package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
  221. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
  222. package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
  223. package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
  224. package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
  225. package/.framework/src/pages/admin/AppsPage.tsx +49 -2
  226. package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
  227. package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
  228. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
  229. package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
  230. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
  231. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
  232. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
  233. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
  234. package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
  235. package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
  236. package/.framework/src/pages/admin/LogsPage.tsx +422 -75
  237. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
  238. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
  239. package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
  240. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
  241. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
  242. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
  243. package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
  244. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
  245. package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
  246. package/.framework/src/pages/admin/RolesPage.tsx +171 -18
  247. package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
  248. package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
  249. package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
  250. package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
  251. package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
  252. package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
  253. package/.framework/src/pages/admin/TimersPage.tsx +48 -20
  254. package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
  255. package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
  256. package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
  257. package/.framework/src/pages/admin/TypesPage.tsx +48 -20
  258. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
  259. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
  260. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
  261. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
  262. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
  263. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
  264. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
  265. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
  266. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
  267. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  268. package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
  269. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
  270. package/.framework/src/pages/auth/LoginPage.tsx +50 -23
  271. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
  272. package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
  273. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
  274. package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
  275. package/.framework/src/types/auth.ts +128 -71
  276. package/.framework/src/types/types.ts +373 -157
  277. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
  278. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
  279. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
  280. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
  281. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
  282. package/docs/README.md +9 -130
  283. package/netlify.toml +3 -3
  284. package/package.json +13 -25
  285. package/scripts/kb-ingest-docs.ts +203 -0
  286. package/spine.config.json +65 -4
  287. package/.framework/migrations/001_schema.sql +0 -425
  288. package/.framework/migrations/002_rls_and_functions.sql +0 -763
  289. package/.framework/migrations/004_enhancements.sql +0 -43
  290. package/.framework/migrations/005_auth_user_trigger.sql +0 -105
  291. package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
  292. package/.framework/migrations/016_invites.sql +0 -27
  293. package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
  294. package/.framework/migrations/018_apps_required_roles.sql +0 -17
  295. package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
  296. package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
  297. package/.framework/migrations/021_app_domains.sql +0 -112
  298. package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
  299. package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
  300. package/.framework/migrations/024_messages_account_id.sql +0 -9
  301. package/.framework/migrations/025_retype_threads_messages.sql +0 -240
  302. package/.framework/migrations/026_fix_rls_policies.sql +0 -47
  303. package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
  304. package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
  305. package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
  306. package/.framework/migrations/030_messages_updated_by.sql +0 -6
  307. package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
  308. package/docs/APPS.md +0 -232
  309. package/docs/ARCHITECTURE.md +0 -246
  310. package/docs/INSTALL.md +0 -155
  311. package/docs/design-schema-spec.md +0 -1837
  312. package/docs/dev-guides/01-create-an-app.md +0 -183
  313. package/docs/dev-guides/02-create-a-function.md +0 -178
  314. package/docs/dev-guides/03-create-a-component.md +0 -178
  315. package/docs/dev-guides/04-webhook-handlers.md +0 -129
  316. package/docs/dev-guides/05-testing.md +0 -168
  317. package/docs/dev-guides/README.md +0 -40
  318. package/docs/npm-packages-plan.md +0 -288
  319. package/docs/spine-core--api-reference.md +0 -822
@@ -1,63 +1,45 @@
1
- /**
2
- * @module logs
3
- * @audience core-contributor
4
- * @layer api-handler
5
- * @stability stable
6
- *
7
- * Read API for the `v2.logs` table plus a write endpoint for external log
8
- * ingestion. The `logs` table schema uses internal column names
9
- * (`level`, `source`, `source_type`, `source_id`, `context`) that differ from
10
- * the stable frontend contract. All reads are mapped through `mapLogRow`.
11
- *
12
- * **Routed by:** `GET/POST /.netlify/functions/logs`
13
- *
14
- * **Actions:**
15
- * | method | ?action | handler |
16
- * |--------|---------|------------------|
17
- * | GET | account | listAccount |
18
- * | GET | target | listTarget |
19
- * | GET | person | listPerson |
20
- * | GET | stats | getStats |
21
- * | GET | search | search |
22
- * | POST | cleanup | cleanup |
23
- * | POST | (default)| log |
24
- *
25
- * **Authorization:** All operations use `ctx.db` (RLS-scoped, always filtered
26
- * to `account_id`). No inserts are made by this module — `emitLog` from
27
- * `_shared/audit.ts` is the canonical write path.
28
- *
29
- * **Column mapping (DB → API):**
30
- * | DB column | API field |
31
- * |--------------|-------------|
32
- * | level | event_type |
33
- * | person_id | actor_id |
34
- * | source_type | target_type |
35
- * | source_id | target_id |
36
- * | source | action |
37
- * | context | details |
38
- *
39
- * @seeAlso audit.ts (emitLog — canonical write path for all system events)
40
- * @seeAlso observability.ts (aggregated metrics over logs)
41
- */
42
1
 
43
- import { createHandler, json, error, parseBody } from './_shared/middleware'
44
2
 
45
- // ─── HELPERS ─────────────────────────────────────────────────────────────────
46
-
47
- // ─── CHUNK_START: LOGS_MAP_ROW ──────────────────────────────────────────────
48
- /**
49
- * @chunk-id LOGS_MAP_ROW_1_0_0
50
- * @version 1.0.0
51
- * @hash 52289a18616b71c05c908c27f2fd5d09837e7b861d30b9307bb6bdf265dd4845
52
- * @macro Log Row Mapper
53
- * @micro Maps raw DB log rows to stable frontend API contract
54
- * @inputs row: any — Raw database log row from v2.logs table
55
- * @outputs object — Mapped log row with API field names
56
- * @depends-on [none]
57
- * @depended-by [listAccount, listTarget, listPerson, search]
58
- * @side-effects [none]
59
- * @tags logs, mapping, helper, api-contract
60
- */
3
+
4
+
5
+
6
+
7
+
8
+
9
+
10
+ // CIL[BEGIN chunk_id="logs_moduleheader_1783968140" type="module_header" identity="imports" parent="none"]
11
+ // CIL[DOC-MACRO purpose="Import middleware dependencies for log API handlers"]
12
+ // CIL[DOC-RESPONSIBILITY responsibility="Import shared handler utilities"]
13
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[\".framework/src/components/ui/dialog.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/migrations/015_simplify_apps_table.sql\",\"\\\"]"]
14
+ // CIL[DOC-CONTRACT inputs="none" outputs="Imported middleware functions" errors="Import failures" side_effects="none"]
15
+ // CIL[DOC-MICRO logic_summary="Imports createHandler, json, error, parseBody from shared middleware" 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: .framework/src/components/ui/dialog.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/migrations/015_simplify_apps_table.sql, \."]
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
+ import { createHandler, json, error, parseBody } from './_shared/middleware'
26
+ import { adminDb } from './_shared/db'
27
+ import { isSystemAdmin } from './_shared/principal'
28
+ // CIL[END chunk_id="logs_moduleheader_1783968140"]
29
+ // CIL[BEGIN chunk_id="logs_maplogrow_1783968140" type="function" identity="mapLogRow" parent="none"]
30
+ // CIL[DOC-MACRO purpose="Transform raw DB log row to stable frontend API contract"]
31
+ // CIL[DOC-RESPONSIBILITY responsibility="Map internal log fields to public API fields"]
32
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/components/ui/dialog.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"\\\"]"]
33
+ // CIL[DOC-CONTRACT inputs="none" outputs="Mapped log row with API field names" errors="Invalid row structure" side_effects="none"]
34
+ // CIL[DOC-MICRO logic_summary="Maps DB columns (level, person_id, source_type, etc.) to API fields (event_type, actor_id, target_type, etc.)" notable_decisions="[]"]
35
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
36
+ // CIL[DOC-STABILITY stability="stable"]
37
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/components/ui/dialog.tsx, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/migrations/015_simplify_apps_table.sql, \."]
38
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
39
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
40
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
41
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
42
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
61
43
  function mapLogRow(row: any) {
62
44
  return {
63
45
  id: row.id,
@@ -66,75 +48,120 @@ function mapLogRow(row: any) {
66
48
  target_type: row.source_type,
67
49
  target_id: row.source_id,
68
50
  action: row.source,
51
+ span_name: row.span_name,
52
+ trace_id: row.trace_id,
53
+ span_id: row.span_id,
54
+ parent_span_id: row.parent_span_id,
55
+ duration_ms: row.duration_ms,
56
+ outcome: row.outcome,
57
+ event_category: row.event_category,
58
+ kind: row.kind,
69
59
  message: row.message,
70
60
  details: row.context,
71
61
  metadata: row.metadata,
72
62
  created_at: row.created_at,
73
63
  }
74
64
  }
75
- // ─── CHUNK_END: LOGS_MAP_ROW ────────────────────────────────────────────────
76
-
77
- // ─── HANDLERS ─────────────────────────────────────────────────────────────────
78
-
79
- // ─── CHUNK_START: LOGS_LIST_ACCOUNT ──────────────────────────────────────────────
80
- /**
81
- * @chunk-id LOGS_LIST_ACCOUNT_1_0_0
82
- * @version 1.0.0
83
- * @hash d512e35890e479c88f4e6130567b16b1143a164705fca4e887aee643cc76a1e5
84
- * @macro Account Logs List Handler
85
- * @micro Lists all account log entries with filtering and mapping
86
- * @inputs ctx: CoreContext — Request context with principal and database
87
- * @inputs body: any — Request body (unused for GET)
88
- * @outputs Array of mapped log rows with API field names
89
- * @depends-on [createHandler, mapLogRow]
90
- * @depended-by [Netlify function routing]
91
- * @side-effects [DB queries, row mapping]
92
- * @tags logs, list, account, pagination
93
- */
65
+ // CIL[END chunk_id="logs_maplogrow_1783968140"]
66
+ // CIL[BEGIN chunk_id="logs_listaccount_1783968140" type="function" identity="listAccount" parent="none"]
67
+ // CIL[DOC-MACRO purpose="List all account log entries with filtering and pagination"]
68
+ // CIL[DOC-RESPONSIBILITY responsibility="Query and return paginated account logs"]
69
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[\".framework/src/components/ui/dialog.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/migrations/015_simplify_apps_table.sql\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
70
+ // CIL[DOC-CONTRACT inputs="none" outputs="Array of mapped log rows" errors="Account context required, DB errors" side_effects="DB read operations"]
71
+ // CIL[DOC-MICRO logic_summary="Builds filtered query on logs table, applies date/type filters, returns mapped results" notable_decisions="[]"]
72
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
73
+ // CIL[DOC-STABILITY stability="stable"]
74
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: .framework/src/components/ui/dialog.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/migrations/015_simplify_apps_table.sql, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/src/pages/admin/RolesPage.tsx, \."]
75
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
76
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
77
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
78
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
79
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
94
80
  export const listAccount = createHandler(async (ctx, body) => {
95
- const { event_type, target_type, date_from, date_to, limit = 100, offset = 0 } = ctx.query || {}
81
+ const { event, event_type, target_type, source, source_id, actor_id, query: searchQuery, date_from, date_to, trace_id, limit = 100, offset = 0 } = ctx.query || {}
82
+ const db = isSystemAdmin(ctx.principal) ? adminDb : ctx.db
96
83
 
97
- if (!ctx.accountId) {
84
+ if (!isSystemAdmin(ctx.principal) && !ctx.accountId) {
98
85
  throw new Error('Account context required')
99
86
  }
100
87
 
101
- let query = ctx.db
88
+ if (event === 'threshold.breached') {
89
+ let q = db
90
+ .from('logs')
91
+ .select('id, span_name, metadata, created_at', { count: 'exact' })
92
+ .eq('span_name', 'threshold.breached')
93
+ .order('created_at', { ascending: false })
94
+
95
+ if (!isSystemAdmin(ctx.principal) && ctx.accountId) {
96
+ q = q.eq('account_id', ctx.accountId)
97
+ }
98
+ if (date_from) q = q.gte('created_at', date_from)
99
+ if (date_to) q = q.lte('created_at', date_to)
100
+
101
+ const { data, error: err, count } = await q.range(
102
+ parseInt(offset.toString()),
103
+ parseInt(offset.toString()) + parseInt(limit.toString()) - 1
104
+ )
105
+
106
+ if (err) throw err
107
+
108
+ const alerts = (data || []).map((row: any) => ({
109
+ id: row.id,
110
+ metric: row.metadata?.metric || row.span_name,
111
+ threshold_value: row.metadata?.threshold_value ?? 0,
112
+ actual_value: row.metadata?.actual_value ?? 0,
113
+ created_at: row.created_at,
114
+ }))
115
+
116
+ return { data: alerts, total: count || alerts.length }
117
+ }
118
+
119
+ let query = db
102
120
  .from('logs')
103
- .select('*')
104
- .eq('account_id', ctx.accountId)
121
+ .select('*', { count: 'exact' })
105
122
  .order('created_at', { ascending: false })
106
123
 
124
+ if (!isSystemAdmin(ctx.principal) && ctx.accountId) {
125
+ query = query.eq('account_id', ctx.accountId)
126
+ }
107
127
  if (event_type) query = query.eq('level', event_type)
128
+ if (event) query = query.eq('span_name', event)
108
129
  if (target_type) query = query.eq('source_type', target_type)
130
+ if (source) query = query.eq('source', source)
131
+ if (source_id) query = query.eq('source_id', source_id)
132
+ if (actor_id) query = query.eq('created_by', actor_id)
133
+ if (searchQuery) query = query.ilike('message', `%${searchQuery}%`)
109
134
  if (date_from) query = query.gte('created_at', date_from)
110
135
  if (date_to) query = query.lte('created_at', date_to)
136
+ if (trace_id) query = query.eq('trace_id', trace_id)
111
137
 
112
- const { data, error: err } = await query.range(
138
+ const { data, error: err, count } = await query.range(
113
139
  parseInt(offset.toString()),
114
140
  parseInt(offset.toString()) + parseInt(limit.toString()) - 1
115
141
  )
116
142
 
117
143
  if (err) throw err
118
144
 
119
- return (data || []).map(mapLogRow)
145
+ return {
146
+ data: (data || []).map(mapLogRow),
147
+ total: count || 0
148
+ }
120
149
  })
121
- // ─── CHUNK_END: LOGS_LIST_ACCOUNT ────────────────────────────────────────────────
122
-
123
- // ─── CHUNK_START: LOGS_LIST_TARGET ──────────────────────────────────────────────
124
- /**
125
- * @chunk-id LOGS_LIST_TARGET_1_0_0
126
- * @version 1.0.0
127
- * @hash 7ea27876f183b59057284ca9007aed6e0e65050b196f00756b8ad5715073e745
128
- * @macro Target Logs List Handler
129
- * @micro Lists log entries for specific target entity with filtering
130
- * @inputs ctx: CoreContext — Request context with principal and database
131
- * @inputs body: any — Request body (unused for GET)
132
- * @outputs Array of mapped log rows for target entity
133
- * @depends-on [createHandler, mapLogRow]
134
- * @depended-by [Netlify function routing]
135
- * @side-effects [DB queries, row mapping]
136
- * @tags logs, list, target, entity-specific
137
- */
150
+ // CIL[END chunk_id="logs_listaccount_1783968140"]
151
+ // CIL[BEGIN chunk_id="logs_listtarget_1783968140" type="function" identity="listTarget" parent="none"]
152
+ // CIL[DOC-MACRO purpose="List log entries for specific target entity with filtering"]
153
+ // CIL[DOC-RESPONSIBILITY responsibility="Query logs by target type and ID with pagination"]
154
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[\".framework/src/components/ui/dialog.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
155
+ // CIL[DOC-CONTRACT inputs="none" outputs="Array of mapped log rows for target" errors="Missing target params, DB errors" side_effects="DB read operations"]
156
+ // CIL[DOC-MICRO logic_summary="Filters logs by source_type and source_id, applies optional event_type filter" notable_decisions="[]"]
157
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
158
+ // CIL[DOC-STABILITY stability="stable"]
159
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: .framework/src/components/ui/dialog.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/schema-utils.ts, \."]
160
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
161
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
162
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
163
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
164
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
138
165
  export const listTarget = createHandler(async (ctx, body) => {
139
166
  const { target_type, target_id, event_type, limit = 100, offset = 0 } = ctx.query || {}
140
167
 
@@ -165,23 +192,21 @@ export const listTarget = createHandler(async (ctx, body) => {
165
192
 
166
193
  return (data || []).map(mapLogRow)
167
194
  })
168
- // ─── CHUNK_END: LOGS_LIST_TARGET ────────────────────────────────────────────────
169
-
170
- // ─── CHUNK_START: LOGS_LIST_PERSON ──────────────────────────────────────────────
171
- /**
172
- * @chunk-id LOGS_LIST_PERSON_1_0_0
173
- * @version 1.0.0
174
- * @hash 1c502ddeac8766153f1cc9ff6ffc8a7804dd83519d3c2e8b11dcf610fc6d6dfe
175
- * @macro Person Activity Feed Handler
176
- * @micro Returns activity feed for person with system event filtering
177
- * @inputs ctx: CoreContext — Request context with principal and database
178
- * @inputs body: any — Request body (unused for GET)
179
- * @outputs Array of mapped log rows for person activity
180
- * @depends-on [createHandler, mapLogRow]
181
- * @depended-by [Netlify function routing]
182
- * @side-effects [DB queries, row mapping]
183
- * @tags logs, list, person, activity-feed
184
- */
195
+ // CIL[END chunk_id="logs_listtarget_1783968140"]
196
+ // CIL[BEGIN chunk_id="logs_listperson_1783968140" type="function" identity="listPerson" parent="none"]
197
+ // CIL[DOC-MACRO purpose="Returns activity feed for person with system event filtering"]
198
+ // CIL[DOC-RESPONSIBILITY responsibility="Query person's activity logs with optional system filtering"]
199
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
200
+ // CIL[DOC-CONTRACT inputs="none" outputs="Array of mapped log rows for person" errors="Person ID required, DB errors" side_effects="DB read operations"]
201
+ // CIL[DOC-MICRO logic_summary="Filters by person_id, optionally excludes system events, returns mapped results" notable_decisions="[]"]
202
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
203
+ // CIL[DOC-STABILITY stability="stable"]
204
+ // 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/principal.ts, .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
205
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
206
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
207
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
208
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
209
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
185
210
  export const listPerson = createHandler(async (ctx, body) => {
186
211
  const { person_id, include_system, limit = 50, offset = 0 } = ctx.query || {}
187
212
 
@@ -215,67 +240,67 @@ export const listPerson = createHandler(async (ctx, body) => {
215
240
 
216
241
  return (data || []).map(mapLogRow)
217
242
  })
218
- // ─── CHUNK_END: LOGS_LIST_PERSON ────────────────────────────────────────────────
219
-
220
- // ─── CHUNK_START: LOGS_GET_STATS ──────────────────────────────────────────────
221
- /**
222
- * @chunk-id LOGS_GET_STATS_1_0_0
223
- * @version 1.0.0
224
- * @hash a25e065d770b9658aa1a7d1db325e044febbac498c06cad735e18167442a2674
225
- * @macro Logs Statistics Handler
226
- * @micro Returns log counts by event type with date range filtering
227
- * @inputs ctx: CoreContext — Request context with principal and database
228
- * @inputs body: any — Request body (unused for GET)
229
- * @outputs {total: number, by_type: Record<string, number>} — Log statistics
230
- * @depends-on [createHandler]
231
- * @depended-by [Netlify function routing]
232
- * @side-effects [DB count query, aggregation]
233
- * @tags logs, stats, analytics, monitoring
234
- */
243
+ // CIL[END chunk_id="logs_listperson_1783968140"]
244
+ // CIL[BEGIN chunk_id="logs_getstats_1783968140" type="function" identity="getStats" parent="none"]
245
+ // CIL[DOC-MACRO purpose="Returns log counts by event type with date range filtering"]
246
+ // CIL[DOC-RESPONSIBILITY responsibility="Aggregate log statistics by event type"]
247
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[]"]
248
+ // CIL[DOC-CONTRACT inputs="none" outputs="{total: number, by_type: Record<string, number>}" errors="Account context required, DB errors" side_effects="DB read operations"]
249
+ // CIL[DOC-MICRO logic_summary="Counts logs by level field, aggregates into by_type object" notable_decisions="[]"]
250
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
251
+ // CIL[DOC-STABILITY stability="stable"]
252
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
253
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
254
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
255
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
256
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
257
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
235
258
  export const getStats = createHandler(async (ctx, body) => {
236
- const { date_from, date_to } = ctx.query || {}
259
+ const { event_type, target_type, source, source_id, actor_id, query: searchQuery, date_from, date_to } = ctx.query || {}
237
260
 
238
261
  if (!ctx.accountId) {
239
262
  throw new Error('Account context required')
240
263
  }
241
264
 
242
- let query = ctx.db
243
- .from('logs')
244
- .select('id, level')
245
- .eq('account_id', ctx.accountId)
246
-
247
- if (date_from) query = query.gte('created_at', date_from)
248
- if (date_to) query = query.lte('created_at', date_to)
249
-
250
- const { data, error: err } = await query
265
+ const { data, error: err } = await ctx.db.rpc('get_log_stats', {
266
+ p_account_id: ctx.accountId,
267
+ p_level: event_type || null,
268
+ p_source: source || null,
269
+ p_source_type: target_type || null,
270
+ p_source_id: source_id || null,
271
+ p_person_id: actor_id || null,
272
+ p_query: searchQuery || null,
273
+ p_date_from: date_from || null,
274
+ p_date_to: date_to || null,
275
+ })
251
276
 
252
277
  if (err) throw err
253
278
 
254
- const rows = data || []
255
- const by_type: Record<string, number> = {}
256
- for (const row of rows) {
257
- by_type[row.level] = (by_type[row.level] || 0) + 1
279
+ return data?.[0] || {
280
+ total: 0,
281
+ error_count: 0,
282
+ user_action_count: 0,
283
+ event_type_count: 0,
284
+ levels: [],
285
+ sources: [],
286
+ source_types: []
258
287
  }
259
-
260
- return { total: rows.length, by_type }
261
288
  })
262
- // ─── CHUNK_END: LOGS_GET_STATS ────────────────────────────────────────────────
263
-
264
- // ─── CHUNK_START: LOGS_SEARCH ──────────────────────────────────────────────
265
- /**
266
- * @chunk-id LOGS_SEARCH_1_0_0
267
- * @version 1.0.0
268
- * @hash 25f4552cc8b604e280e77c9180dea6435c99f864f8d1578af44ea68793c4c67d
269
- * @macro Logs Text Search Handler
270
- * @micro Performs full-text search on log messages with filtering
271
- * @inputs ctx: CoreContext — Request context with principal and database
272
- * @inputs body: any — Request body (unused for GET)
273
- * @outputs Array of mapped log rows matching search query
274
- * @depends-on [createHandler, mapLogRow]
275
- * @depended-by [Netlify function routing]
276
- * @side-effects [DB ILIKE search, row mapping]
277
- * @tags logs, search, text-search, ilike
278
- */
289
+ // CIL[END chunk_id="logs_getstats_1783968140"]
290
+ // CIL[BEGIN chunk_id="logs_search_1783968140" type="function" identity="search" parent="none"]
291
+ // CIL[DOC-MACRO purpose="Performs full-text search on log messages with filtering"]
292
+ // CIL[DOC-RESPONSIBILITY responsibility="Search log messages and return filtered results"]
293
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[]"]
294
+ // CIL[DOC-CONTRACT inputs="none" outputs="Array of mapped log rows matching search" errors="Search query required, DB errors" side_effects="DB read operations"]
295
+ // CIL[DOC-MICRO logic_summary="Uses ILIKE to search message field, applies event_type and target_type filters" notable_decisions="[]"]
296
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
297
+ // CIL[DOC-STABILITY stability="stable"]
298
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
299
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
300
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
301
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
302
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
303
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
279
304
  export const search = createHandler(async (ctx, body) => {
280
305
  const { query: searchQuery, event_type, target_type, limit = 50, offset = 0 } = ctx.query || {}
281
306
 
@@ -306,23 +331,21 @@ export const search = createHandler(async (ctx, body) => {
306
331
 
307
332
  return (data || []).map(mapLogRow)
308
333
  })
309
- // ─── CHUNK_END: LOGS_SEARCH ────────────────────────────────────────────────
310
-
311
- // ─── CHUNK_START: LOGS_LOG ──────────────────────────────────────────────
312
- /**
313
- * @chunk-id LOGS_LOG_1_0_0
314
- * @version 1.0.0
315
- * @hash 521255a8c1a7e4110e2873050c8b58c8819fa6540bb039d30117946ef741633f
316
- * @macro Log Entry Writer
317
- * @micro Writes external log entry with field mapping and validation
318
- * @inputs ctx: CoreContext — Request context with principal and database
319
- * @inputs body: object — Log data including event_type and optional fields
320
- * @outputs {log_id: string} — ID of created log entry
321
- * @depends-on [createHandler]
322
- * @depended-by [Netlify function routing]
323
- * @side-effects [DB insert with field mapping]
324
- * @tags logs, create, external, instrumentation
325
- */
334
+ // CIL[END chunk_id="logs_search_1783968140"]
335
+ // CIL[BEGIN chunk_id="logs_log_1783968140" type="function" identity="log" parent="none"]
336
+ // CIL[DOC-MACRO purpose="Writes external log entry with field mapping and validation"]
337
+ // CIL[DOC-RESPONSIBILITY responsibility="Insert new log entry into database"]
338
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[]"]
339
+ // CIL[DOC-CONTRACT inputs="none" outputs="{log_id: string}" errors="event_type required, DB errors" side_effects="DB insert operation"]
340
+ // CIL[DOC-MICRO logic_summary="Maps API fields to DB columns, inserts into logs table, returns ID" notable_decisions="[]"]
341
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
342
+ // CIL[DOC-STABILITY stability="stable"]
343
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
344
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
345
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
346
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
347
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
348
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
326
349
  export const log = createHandler(async (ctx, body) => {
327
350
  const { event_type, target_type, target_id, action, message, details, metadata } = body
328
351
 
@@ -354,23 +377,21 @@ export const log = createHandler(async (ctx, body) => {
354
377
 
355
378
  return { log_id: data?.id }
356
379
  })
357
- // ─── CHUNK_END: LOGS_LOG ────────────────────────────────────────────────
358
-
359
- // ─── CHUNK_START: LOGS_CLEANUP ──────────────────────────────────────────────
360
- /**
361
- * @chunk-id LOGS_CLEANUP_1_0_0
362
- * @version 1.0.0
363
- * @hash 3790847ac4c98e79285483511dcc23c303dc339b4988ac5715c1f165a1bb29c9
364
- * @macro Logs Cleanup Handler
365
- * @micro Deletes old log entries beyond retention period
366
- * @inputs ctx: CoreContext — Request context with principal and database
367
- * @inputs body: object — days_to_keep (default 90)
368
- * @outputs {deleted_count: number} — Number of deleted log entries
369
- * @depends-on [createHandler]
370
- * @depended-by [Netlify function routing, system-cron.ts]
371
- * @side-effects [DB delete by date]
372
- * @tags logs, cleanup, retention, maintenance
373
- */
380
+ // CIL[END chunk_id="logs_log_1783968140"]
381
+ // CIL[BEGIN chunk_id="logs_cleanup_1783968140" type="function" identity="cleanup" parent="none"]
382
+ // CIL[DOC-MACRO purpose="Deletes old log entries beyond retention period"]
383
+ // CIL[DOC-RESPONSIBILITY responsibility="Remove expired log entries from database"]
384
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[]"]
385
+ // CIL[DOC-CONTRACT inputs="none" outputs="{deleted_count: number}" errors="DB errors" side_effects="DB delete operation"]
386
+ // CIL[DOC-MICRO logic_summary="Calculates cutoff date from days_to_keep, deletes older logs" notable_decisions="[]"]
387
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
388
+ // CIL[DOC-STABILITY stability="stable"]
389
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
390
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
391
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
392
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
393
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
394
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
374
395
  export const cleanup = createHandler(async (ctx, body) => {
375
396
  const { days_to_keep = 90 } = body
376
397
 
@@ -387,25 +408,21 @@ export const cleanup = createHandler(async (ctx, body) => {
387
408
 
388
409
  return { deleted_count: (data || []).length }
389
410
  })
390
- // ─── CHUNK_END: LOGS_CLEANUP ────────────────────────────────────────────────
391
-
392
- // ─── MAIN HANDLER ────────────────────────────────────────────────────────────
393
-
394
- // ─── CHUNK_START: LOGS_HANDLER ──────────────────────────────────────────────
395
- /**
396
- * @chunk-id LOGS_HANDLER_1_0_0
397
- * @version 1.0.0
398
- * @hash 62e729c4e43a30a85394c5ed66a1c2a12898135b133b8b712f481670d2351b22
399
- * @macro Logs Router
400
- * @micro Routes HTTP methods and actions to appropriate log handlers
401
- * @inputs ctx: CoreContext — Request context with principal and database
402
- * @inputs body: any — Request body for POST operations
403
- * @outputs Varies — Depends on routed handler (listAccount/listTarget/listPerson/getStats/search/cleanup/log)
404
- * @depends-on [createHandler, listAccount, listTarget, listPerson, getStats, search, cleanup, log]
405
- * @depended-by [Netlify function routing]
406
- * @side-effects [Delegates to appropriate handler]
407
- * @tags logs, router, crud, netlify-function
408
- */
411
+ // CIL[END chunk_id="logs_cleanup_1783968140"]
412
+ // CIL[BEGIN chunk_id="logs_handler_1783968140" type="function" identity="handler" parent="none"]
413
+ // CIL[DOC-MACRO purpose="Routes HTTP methods and actions to appropriate log handlers"]
414
+ // CIL[DOC-RESPONSIBILITY responsibility="Dispatch requests to correct log handler functions"]
415
+ // CIL[DOC-CONTEXT module="logs" layer="api-handler" related_files="[]"]
416
+ // CIL[DOC-CONTRACT inputs="none" outputs="Varies by handler" errors="Invalid action or method" side_effects="Delegates to handlers"]
417
+ // CIL[DOC-MICRO logic_summary="Switch statement routes action+method combinations to appropriate handler" notable_decisions="[]"]
418
+ // CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
419
+ // CIL[DOC-STABILITY stability="stable"]
420
+ // CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: none."]
421
+ // CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
422
+ // CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
423
+ // CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
424
+ // CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
425
+ // CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
409
426
  export const handler = createHandler(async (ctx, body) => {
410
427
  const { action } = ctx.query || {}
411
428
  const method = ctx.query?.method || 'GET'
@@ -435,4 +452,4 @@ export const handler = createHandler(async (ctx, body) => {
435
452
 
436
453
  throw new Error('Invalid action or method')
437
454
  })
438
- // ─── CHUNK_END: LOGS_HANDLER ────────────────────────────────────────────────
455
+ // CIL[END chunk_id="logs_handler_1783968140"]