spine-framework 0.1.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 (385) hide show
  1. package/.framework/README.md +129 -0
  2. package/.framework/cli/bin.cjs +14 -0
  3. package/.framework/cli/commands/agents.ts +153 -0
  4. package/.framework/cli/commands/auth.ts +94 -0
  5. package/.framework/cli/commands/create-app.ts +185 -0
  6. package/.framework/cli/commands/dev.ts +295 -0
  7. package/.framework/cli/commands/doctor.ts +442 -0
  8. package/.framework/cli/commands/generate.ts +332 -0
  9. package/.framework/cli/commands/init.ts +272 -0
  10. package/.framework/cli/commands/install-app.ts +391 -0
  11. package/.framework/cli/commands/items.ts +253 -0
  12. package/.framework/cli/commands/migrations.ts +141 -0
  13. package/.framework/cli/commands/pipelines.ts +166 -0
  14. package/.framework/cli/commands/status.ts +197 -0
  15. package/.framework/cli/commands/system.ts +184 -0
  16. package/.framework/cli/commands/test.ts +227 -0
  17. package/.framework/cli/commands/uninstall-app.ts +166 -0
  18. package/.framework/cli/context.ts +268 -0
  19. package/.framework/cli/env-loader.ts +36 -0
  20. package/.framework/cli/index.ts +106 -0
  21. package/.framework/cli/welcome.cjs +45 -0
  22. package/.framework/docs/API.md +384 -0
  23. package/.framework/docs/STABILITY.md +52 -0
  24. package/.framework/docs/admin-routes.md +76 -0
  25. package/.framework/docs/api-docs-progress.md +38 -0
  26. package/.framework/docs/api-governance.md +146 -0
  27. package/.framework/docs/api-testing-results.md +212 -0
  28. package/.framework/docs/apis/admin-configs.md +567 -0
  29. package/.framework/docs/apis/admin-data.md +272 -0
  30. package/.framework/docs/apis/index.md +231 -0
  31. package/.framework/docs/apis/internal.md +295 -0
  32. package/.framework/docs/apis/runtime.md +537 -0
  33. package/.framework/docs/assembly-launch-guide.md +138 -0
  34. package/.framework/docs/audit-results.md +590 -0
  35. package/.framework/docs/authorization-model.md +170 -0
  36. package/.framework/docs/db-api-inventory.md +95 -0
  37. package/.framework/docs/examples/custom-app/README.md +77 -0
  38. package/.framework/docs/examples/custom-function/README.md +27 -0
  39. package/.framework/docs/examples/custom-function/handler.ts +48 -0
  40. package/.framework/docs/examples/custom-webhook/README.md +68 -0
  41. package/.framework/docs/gap-remediation-backlog.md +103 -0
  42. package/.framework/docs/guides/cli-guide.md +224 -0
  43. package/.framework/docs/guides/getting-started.md +103 -0
  44. package/.framework/docs/guides/import-guide.md +193 -0
  45. package/.framework/docs/guides/testing-guide.md +229 -0
  46. package/.framework/docs/permission-examples.md +326 -0
  47. package/.framework/docs/ui-adoption-verification.md +111 -0
  48. package/.framework/docs/ui-api-coverage.md +84 -0
  49. package/.framework/docs/v2-compatibility-audit.md +228 -0
  50. package/.framework/functions/.gitkeep +1 -0
  51. package/.framework/functions/_shared/agent-runner.ts +1097 -0
  52. package/.framework/functions/_shared/app-manifest.ts +184 -0
  53. package/.framework/functions/_shared/audit.ts +150 -0
  54. package/.framework/functions/_shared/db.ts +174 -0
  55. package/.framework/functions/_shared/index.ts +382 -0
  56. package/.framework/functions/_shared/middleware.ts +490 -0
  57. package/.framework/functions/_shared/permissions.ts +1325 -0
  58. package/.framework/functions/_shared/pipeline-runner.ts +731 -0
  59. package/.framework/functions/_shared/principal.ts +760 -0
  60. package/.framework/functions/_shared/schema-utils.ts +967 -0
  61. package/.framework/functions/_shared/testing.ts +258 -0
  62. package/.framework/functions/_shared/trigger-engine.ts +425 -0
  63. package/.framework/functions/_shared/webhook-registration.ts +168 -0
  64. package/.framework/functions/_shared/webhook-registry.ts +129 -0
  65. package/.framework/functions/account-nodes.ts +111 -0
  66. package/.framework/functions/admin-data.ts +606 -0
  67. package/.framework/functions/ai-agents.ts +323 -0
  68. package/.framework/functions/api-keys.ts +376 -0
  69. package/.framework/functions/apps.ts +483 -0
  70. package/.framework/functions/auth.ts +196 -0
  71. package/.framework/functions/debug-auth.ts +107 -0
  72. package/.framework/functions/embeddings.ts +556 -0
  73. package/.framework/functions/integration-routes.ts +523 -0
  74. package/.framework/functions/integrations.ts +319 -0
  75. package/.framework/functions/item-progress.ts +272 -0
  76. package/.framework/functions/logs.ts +438 -0
  77. package/.framework/functions/observability.ts +275 -0
  78. package/.framework/functions/pipeline-executions.ts +494 -0
  79. package/.framework/functions/pipelines.ts +485 -0
  80. package/.framework/functions/prompt-configs.ts +339 -0
  81. package/.framework/functions/roles.ts +387 -0
  82. package/.framework/functions/system-cron.ts +742 -0
  83. package/.framework/functions/system.ts +323 -0
  84. package/.framework/functions/tests.ts +119 -0
  85. package/.framework/functions/timers.ts +357 -0
  86. package/.framework/functions/triggers.ts +563 -0
  87. package/.framework/functions/types.ts +604 -0
  88. package/.framework/migrations/000_foundation.sql +1256 -0
  89. package/.framework/migrations/001_seed.sql +92 -0
  90. package/.framework/migrations/002_seed_constraints.sql +13 -0
  91. package/.framework/migrations/003_auth_user_trigger.sql +59 -0
  92. package/.framework/src/App.tsx +126 -0
  93. package/.framework/src/apps/admin/index.tsx +173 -0
  94. package/.framework/src/components/AppWrapper.tsx +56 -0
  95. package/.framework/src/components/CustomAppLoader.tsx +116 -0
  96. package/.framework/src/components/admin/AdminListPage.tsx +151 -0
  97. package/.framework/src/components/admin/AdminSidebar.tsx +166 -0
  98. package/.framework/src/components/admin/AdminStatsCard.tsx +62 -0
  99. package/.framework/src/components/admin/SortableTableHeader.tsx +42 -0
  100. package/.framework/src/components/app-shell/GenericAppShell.tsx +181 -0
  101. package/.framework/src/components/app-shell/GenericDetailPage.tsx +200 -0
  102. package/.framework/src/components/app-shell/GenericListPage.tsx +116 -0
  103. package/.framework/src/components/app-sidebar.tsx +228 -0
  104. package/.framework/src/components/auth/ProtectedRoute.tsx +88 -0
  105. package/.framework/src/components/layout/AppShell.tsx +91 -0
  106. package/.framework/src/components/layout/Header.tsx +88 -0
  107. package/.framework/src/components/layout/Layout.tsx +95 -0
  108. package/.framework/src/components/layout/Sidebar.tsx +329 -0
  109. package/.framework/src/components/runtime/DataDetailHeader.tsx +77 -0
  110. package/.framework/src/components/runtime/DataDetailPage.tsx +171 -0
  111. package/.framework/src/components/runtime/DataFilters.tsx +91 -0
  112. package/.framework/src/components/runtime/DataHeader.tsx +68 -0
  113. package/.framework/src/components/runtime/DataListPage.tsx +124 -0
  114. package/.framework/src/components/runtime/DataStats.tsx +70 -0
  115. package/.framework/src/components/runtime/DataTable.tsx +174 -0
  116. package/.framework/src/components/runtime/SchemaDetailForm.tsx +134 -0
  117. package/.framework/src/components/runtime/index.ts +18 -0
  118. package/.framework/src/components/search-form.tsx +29 -0
  119. package/.framework/src/components/shared/AgentView.tsx +213 -0
  120. package/.framework/src/components/shared/FieldRenderer.tsx +478 -0
  121. package/.framework/src/components/shared/SchemaFields.tsx +226 -0
  122. package/.framework/src/components/ui/DataTable.tsx +343 -0
  123. package/.framework/src/components/ui/Form.tsx +281 -0
  124. package/.framework/src/components/ui/ItemCard.tsx +296 -0
  125. package/.framework/src/components/ui/ItemListView.tsx +308 -0
  126. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -0
  127. package/.framework/src/components/ui/Modal.tsx +61 -0
  128. package/.framework/src/components/ui/RichTextEditor.tsx +210 -0
  129. package/.framework/src/components/ui/accordion.tsx +82 -0
  130. package/.framework/src/components/ui/alert-dialog.tsx +197 -0
  131. package/.framework/src/components/ui/alert.tsx +76 -0
  132. package/.framework/src/components/ui/aspect-ratio.tsx +11 -0
  133. package/.framework/src/components/ui/avatar.tsx +110 -0
  134. package/.framework/src/components/ui/badge.tsx +49 -0
  135. package/.framework/src/components/ui/breadcrumb.tsx +122 -0
  136. package/.framework/src/components/ui/button-group.tsx +83 -0
  137. package/.framework/src/components/ui/button.tsx +65 -0
  138. package/.framework/src/components/ui/calendar.tsx +222 -0
  139. package/.framework/src/components/ui/card.tsx +100 -0
  140. package/.framework/src/components/ui/carousel.tsx +240 -0
  141. package/.framework/src/components/ui/chart.tsx +373 -0
  142. package/.framework/src/components/ui/checkbox.tsx +31 -0
  143. package/.framework/src/components/ui/collapsible.tsx +33 -0
  144. package/.framework/src/components/ui/combobox.tsx +299 -0
  145. package/.framework/src/components/ui/command.tsx +193 -0
  146. package/.framework/src/components/ui/context-menu.tsx +261 -0
  147. package/.framework/src/components/ui/dialog.tsx +165 -0
  148. package/.framework/src/components/ui/direction.tsx +22 -0
  149. package/.framework/src/components/ui/drawer.tsx +132 -0
  150. package/.framework/src/components/ui/dropdown-menu.tsx +269 -0
  151. package/.framework/src/components/ui/empty.tsx +104 -0
  152. package/.framework/src/components/ui/field.tsx +238 -0
  153. package/.framework/src/components/ui/hover-card.tsx +42 -0
  154. package/.framework/src/components/ui/input-group.tsx +153 -0
  155. package/.framework/src/components/ui/input-otp.tsx +87 -0
  156. package/.framework/src/components/ui/input.tsx +19 -0
  157. package/.framework/src/components/ui/item.tsx +196 -0
  158. package/.framework/src/components/ui/kbd.tsx +26 -0
  159. package/.framework/src/components/ui/label.tsx +22 -0
  160. package/.framework/src/components/ui/menubar.tsx +277 -0
  161. package/.framework/src/components/ui/native-select.tsx +61 -0
  162. package/.framework/src/components/ui/navigation-menu.tsx +164 -0
  163. package/.framework/src/components/ui/pagination.tsx +129 -0
  164. package/.framework/src/components/ui/popover.tsx +87 -0
  165. package/.framework/src/components/ui/progress.tsx +31 -0
  166. package/.framework/src/components/ui/radio-group.tsx +42 -0
  167. package/.framework/src/components/ui/resizable.tsx +50 -0
  168. package/.framework/src/components/ui/scroll-area.tsx +53 -0
  169. package/.framework/src/components/ui/select.tsx +195 -0
  170. package/.framework/src/components/ui/separator.tsx +26 -0
  171. package/.framework/src/components/ui/sheet.tsx +145 -0
  172. package/.framework/src/components/ui/sidebar.tsx +706 -0
  173. package/.framework/src/components/ui/skeleton.tsx +13 -0
  174. package/.framework/src/components/ui/slider.tsx +59 -0
  175. package/.framework/src/components/ui/sonner.tsx +47 -0
  176. package/.framework/src/components/ui/spinner.tsx +10 -0
  177. package/.framework/src/components/ui/switch.tsx +33 -0
  178. package/.framework/src/components/ui/table-primitives.tsx +141 -0
  179. package/.framework/src/components/ui/table.tsx +114 -0
  180. package/.framework/src/components/ui/tabs.tsx +90 -0
  181. package/.framework/src/components/ui/textarea.tsx +18 -0
  182. package/.framework/src/components/ui/toggle-group.tsx +89 -0
  183. package/.framework/src/components/ui/toggle.tsx +45 -0
  184. package/.framework/src/components/ui/tooltip.tsx +57 -0
  185. package/.framework/src/contexts/AppContext.tsx +133 -0
  186. package/.framework/src/contexts/AuthContext.tsx +371 -0
  187. package/.framework/src/hooks/use-mobile.ts +19 -0
  188. package/.framework/src/hooks/useApi.ts +526 -0
  189. package/.framework/src/hooks/useApps.ts +114 -0
  190. package/.framework/src/hooks/useEntityList.ts +190 -0
  191. package/.framework/src/hooks/useEntityRecord.ts +308 -0
  192. package/.framework/src/hooks/useForm.ts +307 -0
  193. package/.framework/src/hooks/useListSchema.ts +264 -0
  194. package/.framework/src/hooks/useSchemaRecord.ts +223 -0
  195. package/.framework/src/index.css +128 -0
  196. package/.framework/src/lib/api.ts +156 -0
  197. package/.framework/src/lib/supabase.ts +94 -0
  198. package/.framework/src/lib/utils.ts +317 -0
  199. package/.framework/src/main.tsx +27 -0
  200. package/.framework/src/pages/DashboardPage.tsx +181 -0
  201. package/.framework/src/pages/NotFoundPage.tsx +39 -0
  202. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +161 -0
  203. package/.framework/src/pages/admin/AIAgentsPage.tsx +318 -0
  204. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +199 -0
  205. package/.framework/src/pages/admin/APIKeysPage.tsx +303 -0
  206. package/.framework/src/pages/admin/AlertsConfigPage.tsx +523 -0
  207. package/.framework/src/pages/admin/AppDetailPage.tsx +493 -0
  208. package/.framework/src/pages/admin/AppsPage.tsx +355 -0
  209. package/.framework/src/pages/admin/DesignedPage.tsx +491 -0
  210. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +534 -0
  211. package/.framework/src/pages/admin/EmbeddingsPage.tsx +424 -0
  212. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +176 -0
  213. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +109 -0
  214. package/.framework/src/pages/admin/IntegratedDashboard.tsx +402 -0
  215. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +187 -0
  216. package/.framework/src/pages/admin/IntegrationsPage.tsx +301 -0
  217. package/.framework/src/pages/admin/LogsPage.tsx +283 -0
  218. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +85 -0
  219. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +470 -0
  220. package/.framework/src/pages/admin/PipelineDetailPage.tsx +183 -0
  221. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +279 -0
  222. package/.framework/src/pages/admin/PipelinesPage.tsx +390 -0
  223. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +299 -0
  224. package/.framework/src/pages/admin/PromptConfigsPage.tsx +292 -0
  225. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +434 -0
  226. package/.framework/src/pages/admin/RoleDetailPage.tsx +273 -0
  227. package/.framework/src/pages/admin/RolesPage.tsx +292 -0
  228. package/.framework/src/pages/admin/SelectTestPage.tsx +61 -0
  229. package/.framework/src/pages/admin/ShadcnTestPage.tsx +588 -0
  230. package/.framework/src/pages/admin/SimpleDashboard.tsx +387 -0
  231. package/.framework/src/pages/admin/TestRunDetailPage.tsx +172 -0
  232. package/.framework/src/pages/admin/TestingDashboard.tsx +257 -0
  233. package/.framework/src/pages/admin/TimerDetailPage.tsx +151 -0
  234. package/.framework/src/pages/admin/TimersPage.tsx +376 -0
  235. package/.framework/src/pages/admin/TriggerDetailPage.tsx +149 -0
  236. package/.framework/src/pages/admin/TriggersPage.tsx +381 -0
  237. package/.framework/src/pages/admin/TypeDetailPage.tsx +694 -0
  238. package/.framework/src/pages/admin/TypesPage.tsx +295 -0
  239. package/.framework/src/pages/auth/LoginPage.tsx +188 -0
  240. package/.framework/src/pages/auth/RegisterPage.tsx +163 -0
  241. package/.framework/src/pages/spine-framework/APIPage.tsx +17 -0
  242. package/.framework/src/pages/spine-framework/CLIPage.tsx +25 -0
  243. package/.framework/src/types/auth.ts +125 -0
  244. package/.framework/src/types/types.ts +407 -0
  245. package/STRUCTURE.md +150 -0
  246. package/config/components.json +25 -0
  247. package/config/deno.lock +108 -0
  248. package/config/package-lock.json +17183 -0
  249. package/config/postcss.config.cjs +10 -0
  250. package/config/tailwind.config.cjs +78 -0
  251. package/config/tsconfig.build.json +32 -0
  252. package/config/tsconfig.cli.json +18 -0
  253. package/config/tsconfig.json +41 -0
  254. package/config/tsconfig.node.json +17 -0
  255. package/config/tsconfig.node.tsbuildinfo +1 -0
  256. package/config/tsconfig.tsbuildinfo +1 -0
  257. package/config/typedoc.json +16 -0
  258. package/config/vite.config.d.ts +2 -0
  259. package/config/vite.config.ts +72 -0
  260. package/dist/cli/commands/agents.d.ts +39 -0
  261. package/dist/cli/commands/agents.d.ts.map +1 -0
  262. package/dist/cli/commands/auth.d.ts +36 -0
  263. package/dist/cli/commands/auth.d.ts.map +1 -0
  264. package/dist/cli/commands/create-app.d.ts +23 -0
  265. package/dist/cli/commands/create-app.d.ts.map +1 -0
  266. package/dist/cli/commands/dev.d.ts +39 -0
  267. package/dist/cli/commands/dev.d.ts.map +1 -0
  268. package/dist/cli/commands/doctor.d.ts +42 -0
  269. package/dist/cli/commands/doctor.d.ts.map +1 -0
  270. package/dist/cli/commands/generate.d.ts +36 -0
  271. package/dist/cli/commands/generate.d.ts.map +1 -0
  272. package/dist/cli/commands/init.d.ts +30 -0
  273. package/dist/cli/commands/init.d.ts.map +1 -0
  274. package/dist/cli/commands/install-app.d.ts +30 -0
  275. package/dist/cli/commands/install-app.d.ts.map +1 -0
  276. package/dist/cli/commands/items.d.ts +45 -0
  277. package/dist/cli/commands/items.d.ts.map +1 -0
  278. package/dist/cli/commands/migrations.d.ts +41 -0
  279. package/dist/cli/commands/migrations.d.ts.map +1 -0
  280. package/dist/cli/commands/pipelines.d.ts +40 -0
  281. package/dist/cli/commands/pipelines.d.ts.map +1 -0
  282. package/dist/cli/commands/status.d.ts +23 -0
  283. package/dist/cli/commands/status.d.ts.map +1 -0
  284. package/dist/cli/commands/system.d.ts +29 -0
  285. package/dist/cli/commands/system.d.ts.map +1 -0
  286. package/dist/cli/commands/test.d.ts +46 -0
  287. package/dist/cli/commands/test.d.ts.map +1 -0
  288. package/dist/cli/commands/uninstall-app.d.ts +23 -0
  289. package/dist/cli/commands/uninstall-app.d.ts.map +1 -0
  290. package/dist/cli/context.d.ts +88 -0
  291. package/dist/cli/context.d.ts.map +1 -0
  292. package/dist/cli/env-loader.d.ts +14 -0
  293. package/dist/cli/env-loader.d.ts.map +1 -0
  294. package/dist/cli/index.d.ts +41 -0
  295. package/dist/cli/index.d.ts.map +1 -0
  296. package/dist/functions/_shared/agent-runner.d.ts +156 -0
  297. package/dist/functions/_shared/agent-runner.d.ts.map +1 -0
  298. package/dist/functions/_shared/app-manifest.d.ts +68 -0
  299. package/dist/functions/_shared/app-manifest.d.ts.map +1 -0
  300. package/dist/functions/_shared/audit.d.ts +91 -0
  301. package/dist/functions/_shared/audit.d.ts.map +1 -0
  302. package/dist/functions/_shared/db.d.ts +125 -0
  303. package/dist/functions/_shared/db.d.ts.map +1 -0
  304. package/dist/functions/_shared/index.d.ts +298 -0
  305. package/dist/functions/_shared/index.d.ts.map +1 -0
  306. package/dist/functions/_shared/middleware.d.ts +315 -0
  307. package/dist/functions/_shared/middleware.d.ts.map +1 -0
  308. package/dist/functions/_shared/permissions.d.ts +626 -0
  309. package/dist/functions/_shared/permissions.d.ts.map +1 -0
  310. package/dist/functions/_shared/pipeline-runner.d.ts +124 -0
  311. package/dist/functions/_shared/pipeline-runner.d.ts.map +1 -0
  312. package/dist/functions/_shared/principal.d.ts +284 -0
  313. package/dist/functions/_shared/principal.d.ts.map +1 -0
  314. package/dist/functions/_shared/schema-utils.d.ts +181 -0
  315. package/dist/functions/_shared/schema-utils.d.ts.map +1 -0
  316. package/dist/functions/_shared/testing.d.ts +172 -0
  317. package/dist/functions/_shared/testing.d.ts.map +1 -0
  318. package/dist/functions/_shared/trigger-engine.d.ts +140 -0
  319. package/dist/functions/_shared/trigger-engine.d.ts.map +1 -0
  320. package/dist/functions/_shared/webhook-registration.d.ts +81 -0
  321. package/dist/functions/_shared/webhook-registration.d.ts.map +1 -0
  322. package/dist/functions/_shared/webhook-registry.d.ts +57 -0
  323. package/dist/functions/_shared/webhook-registry.d.ts.map +1 -0
  324. package/dist/functions/account-nodes.d.ts +48 -0
  325. package/dist/functions/account-nodes.d.ts.map +1 -0
  326. package/dist/functions/admin-data.d.ts +178 -0
  327. package/dist/functions/admin-data.d.ts.map +1 -0
  328. package/dist/functions/ai-agents.d.ts +125 -0
  329. package/dist/functions/ai-agents.d.ts.map +1 -0
  330. package/dist/functions/api-keys.d.ts +140 -0
  331. package/dist/functions/api-keys.d.ts.map +1 -0
  332. package/dist/functions/apps.d.ts +163 -0
  333. package/dist/functions/apps.d.ts.map +1 -0
  334. package/dist/functions/auth.d.ts +74 -0
  335. package/dist/functions/auth.d.ts.map +1 -0
  336. package/dist/functions/debug-auth.d.ts +33 -0
  337. package/dist/functions/debug-auth.d.ts.map +1 -0
  338. package/dist/functions/embeddings.d.ts +205 -0
  339. package/dist/functions/embeddings.d.ts.map +1 -0
  340. package/dist/functions/integration-routes.d.ts +45 -0
  341. package/dist/functions/integration-routes.d.ts.map +1 -0
  342. package/dist/functions/integrations.d.ts +124 -0
  343. package/dist/functions/integrations.d.ts.map +1 -0
  344. package/dist/functions/item-progress.d.ts +41 -0
  345. package/dist/functions/item-progress.d.ts.map +1 -0
  346. package/dist/functions/logs.d.ts +162 -0
  347. package/dist/functions/logs.d.ts.map +1 -0
  348. package/dist/functions/observability.d.ts +123 -0
  349. package/dist/functions/observability.d.ts.map +1 -0
  350. package/dist/functions/pipeline-executions.d.ts +190 -0
  351. package/dist/functions/pipeline-executions.d.ts.map +1 -0
  352. package/dist/functions/pipelines.d.ts +171 -0
  353. package/dist/functions/pipelines.d.ts.map +1 -0
  354. package/dist/functions/prompt-configs.d.ts +125 -0
  355. package/dist/functions/prompt-configs.d.ts.map +1 -0
  356. package/dist/functions/roles.d.ts +118 -0
  357. package/dist/functions/roles.d.ts.map +1 -0
  358. package/dist/functions/system-cron.d.ts +65 -0
  359. package/dist/functions/system-cron.d.ts.map +1 -0
  360. package/dist/functions/system.d.ts +29 -0
  361. package/dist/functions/system.d.ts.map +1 -0
  362. package/dist/functions/tests.d.ts +28 -0
  363. package/dist/functions/tests.d.ts.map +1 -0
  364. package/dist/functions/timers.d.ts +139 -0
  365. package/dist/functions/timers.d.ts.map +1 -0
  366. package/dist/functions/triggers.d.ts +203 -0
  367. package/dist/functions/triggers.d.ts.map +1 -0
  368. package/dist/functions/types.d.ts +151 -0
  369. package/dist/functions/types.d.ts.map +1 -0
  370. package/dist/src/types/types.d.ts +364 -0
  371. package/dist/src/types/types.d.ts.map +1 -0
  372. package/package.json +192 -0
  373. package/scripts/app-install-cli.ts +286 -0
  374. package/scripts/assemble-frontend.sh +79 -0
  375. package/scripts/assemble-functions.sh +62 -0
  376. package/scripts/assemble.sh +35 -0
  377. package/scripts/boundary-check.sh +106 -0
  378. package/scripts/build-manifest.sh +80 -0
  379. package/scripts/check-core-integrity.sh +82 -0
  380. package/scripts/ingest-chunks.cjs +202 -0
  381. package/scripts/kb-chunk-parser.cjs +312 -0
  382. package/scripts/kb-chunk-parser.ts +330 -0
  383. package/scripts/load-test-app-install.ts +484 -0
  384. package/scripts/netlify-dev-wrapper.sh +22 -0
  385. package/scripts/verify-integrity.sh +69 -0
@@ -0,0 +1,323 @@
1
+ /**
2
+ * @module ai-agents
3
+ * @audience core-contributor
4
+ * @layer api-handler
5
+ * @stability stable
6
+ *
7
+ * CRUD API for the `ai_agents` table. AI agent records define the configuration
8
+ * for agentic inference workloads: model settings, system prompts, available
9
+ * tools, capabilities, and constraints. The runtime execution is handled by
10
+ * `_shared/agent-runner.ts`.
11
+ *
12
+ * **Routed by:** `GET/POST/PATCH/DELETE /.netlify/functions/ai-agents`
13
+ *
14
+ * **Actions (standard CRUD only):**
15
+ * | method | condition | handler |
16
+ * |--------|-----------|---------|
17
+ * | GET | ?id | get |
18
+ * | GET | (default) | list |
19
+ * | POST | — | create |
20
+ * | PATCH | — | update |
21
+ * | DELETE | — | remove |
22
+ *
23
+ * **Authorization:** All operations use `ctx.db` (RLS-scoped). Authenticated
24
+ * principal required for writes.
25
+ *
26
+ * INVARIANT: `remove` is a hard delete.
27
+ * INVARIANT: `update` only patches allowed fields: name, description,
28
+ * model_config, system_prompt, tools, capabilities, constraints, metadata,
29
+ * is_active.
30
+ *
31
+ * @seeAlso agent-runner.ts (runAgent — runtime execution using these configs)
32
+ * @seeAlso prompt-configs.ts (prompt_configs referenced by agent configs)
33
+ * @seeAlso audit.ts (emitLog for ai_agent.* events)
34
+ */
35
+
36
+ import { createHandler } from './_shared/middleware'
37
+ import { joins } from './_shared/db'
38
+ import { emitLog } from './_shared/audit'
39
+ import { PermissionEngine, sanitizeRecordData } from './_shared/permissions'
40
+
41
+ const permissions = PermissionEngine as any
42
+
43
+ // ─── HANDLERS ─────────────────────────────────────────────────────────────────
44
+
45
+ // ─── CHUNK_START: AI_AGENTS_LIST ──────────────────────────────────────────────
46
+ /**
47
+ * @chunk-id AI_AGENTS_LIST_1_0_0
48
+ * @version 1.0.0
49
+ * @hash 237972d65e86f5d432f55b602ac5e6f2dcfaefa83c662c10b7d3437ac906ff0d
50
+ * @macro AI Agents List Handler
51
+ * @micro Lists AI agents with filtering and pagination
52
+ * @inputs ctx: CoreContext — Request context with principal and database
53
+ * @inputs _body: any — Request body (unused for GET)
54
+ * @outputs Array of sanitized AI agent records
55
+ * @depends-on [createHandler, joins, sanitizeRecordData]
56
+ * @depended-by [Netlify function routing]
57
+ * @side-effects [DB queries, permission sanitization]
58
+ * @tags ai-agents, list, crud, pagination
59
+ */
60
+ export const list = createHandler(async (ctx, _body) => {
61
+ const { agent_type, is_active, limit = 100, offset = 0 } = ctx.query || {}
62
+
63
+ if (!ctx.accountId) {
64
+ throw new Error('Account context required')
65
+ }
66
+
67
+ // RLS automatically filters to accessible accounts
68
+ let query = ctx.db
69
+ .from('ai_agents')
70
+ .select(`*, ${joins.app}, ${joins.createdBy}`)
71
+ .order('name')
72
+
73
+ if (agent_type) {
74
+ query = query.eq('agent_type', agent_type)
75
+ }
76
+ if (is_active !== undefined) {
77
+ query = query.eq('is_active', is_active === 'true')
78
+ }
79
+
80
+ const { data, error: err } = await query.range(
81
+ parseInt(offset.toString()),
82
+ parseInt(offset.toString()) + parseInt(limit.toString()) - 1
83
+ )
84
+
85
+ if (err) throw err
86
+
87
+ const sanitized = []
88
+ for (const agent of data || []) {
89
+ sanitized.push(await sanitizeRecordData(ctx, agent, 'ai_agent'))
90
+ }
91
+
92
+ return sanitized
93
+ })
94
+ // ─── CHUNK_END: AI_AGENTS_LIST ────────────────────────────────────────────────
95
+
96
+ // ─── CHUNK_START: AI_AGENTS_GET ──────────────────────────────────────────────
97
+ /**
98
+ * @chunk-id AI_AGENTS_GET_1_0_0
99
+ * @version 1.0.0
100
+ * @hash 62f283668d9a90ff81e2cbf8c437298206b355d2dd96fb559b2848fc4ffbc5cd
101
+ * @macro AI Agent Get Handler
102
+ * @micro Returns a single AI agent by UUID with joins
103
+ * @inputs ctx: CoreContext — Request context with principal and database
104
+ * @inputs _body: any — Request body (unused for GET)
105
+ * @outputs Sanitized AI agent record with app and createdBy joins
106
+ * @depends-on [createHandler, joins, sanitizeRecordData]
107
+ * @depended-by [Netlify function routing]
108
+ * @side-effects [DB single row query, permission sanitization]
109
+ * @tags ai-agents, get, crud, single-record
110
+ */
111
+ export const get = createHandler(async (ctx, _body) => {
112
+ const { id } = ctx.query || {}
113
+
114
+ if (!id) {
115
+ throw new Error('Agent ID is required')
116
+ }
117
+
118
+ const { data, error: err } = await ctx.db
119
+ .from('ai_agents')
120
+ .select(`*, ${joins.app}, ${joins.createdBy}`)
121
+ .eq('id', id)
122
+ .single()
123
+
124
+ if (err) throw err
125
+
126
+ return await sanitizeRecordData(ctx, data, 'ai_agent')
127
+ })
128
+ // ─── CHUNK_END: AI_AGENTS_GET ────────────────────────────────────────────────
129
+
130
+ // ─── CHUNK_START: AI_AGENTS_CREATE ──────────────────────────────────────────────
131
+ /**
132
+ * @chunk-id AI_AGENTS_CREATE_1_0_0
133
+ * @version 1.0.0
134
+ * @hash 355c8ceb1f33e033616480827141a2f33cde8e18fa4e9f9d94f4866af6fe66f6
135
+ * @macro AI Agent Create Handler
136
+ * @micro Creates new AI agent configuration with validation and audit logging
137
+ * @inputs ctx: CoreContext — Request context with principal and database
138
+ * @inputs body: object — Agent configuration data
139
+ * @outputs Inserted AI agent record
140
+ * @depends-on [createHandler, emitLog]
141
+ * @depended-by [Netlify function routing]
142
+ * @side-effects [DB insert, audit logging]
143
+ * @tags ai-agents, create, crud, audit
144
+ */
145
+ export const create = createHandler(async (ctx, body) => {
146
+ const { app_id, name, description, agent_type, model_config, system_prompt, tools, capabilities, constraints, metadata } = body
147
+
148
+ if (!name || !agent_type) {
149
+ throw new Error('name and agent_type are required')
150
+ }
151
+
152
+ if (!ctx.principal || ctx.principal.id === 'anonymous' || !ctx.accountId) {
153
+ throw new Error('User context (person and account) required')
154
+ }
155
+
156
+ const { data, error: err } = await ctx.db
157
+ .from('ai_agents')
158
+ .insert({
159
+ app_id: app_id || null,
160
+ account_id: ctx.accountId,
161
+ name,
162
+ description: description || null,
163
+ agent_type,
164
+ model_config: model_config || {},
165
+ system_prompt: system_prompt || null,
166
+ tools: tools || [],
167
+ capabilities: capabilities || [],
168
+ constraints: constraints || {},
169
+ metadata: metadata || {},
170
+ created_by: ctx.principal.id
171
+ })
172
+ .select()
173
+ .single()
174
+
175
+ if (err) throw err
176
+
177
+ await emitLog(ctx, 'ai_agent.created',
178
+ { type: 'ai_agent', id: data.id },
179
+ { after: { name, agent_type } }
180
+ )
181
+
182
+ return data
183
+ })
184
+ // ─── CHUNK_END: AI_AGENTS_CREATE ────────────────────────────────────────────────
185
+
186
+ // ─── CHUNK_START: AI_AGENTS_UPDATE ──────────────────────────────────────────────
187
+ /**
188
+ * @chunk-id AI_AGENTS_UPDATE_1_0_0
189
+ * @version 1.0.0
190
+ * @hash 07e173626958a0ef032cc4c80719c49df5990756e08ecdb70a4168ab73544f10
191
+ * @macro AI Agent Update Handler
192
+ * @micro Updates AI agent with field validation and audit logging
193
+ * @inputs ctx: CoreContext — Request context with principal and database
194
+ * @inputs body: object — Agent updates including id
195
+ * @outputs Updated AI agent record
196
+ * @depends-on [createHandler, emitLog]
197
+ * @depended-by [Netlify function routing]
198
+ * @side-effects [DB update, audit logging]
199
+ * @tags ai-agents, update, crud, audit
200
+ */
201
+ export const update = createHandler(async (ctx, body) => {
202
+ const id = body?.id || ctx.query?.id
203
+ const { id: _bodyId, ...updates } = body || {}
204
+
205
+ if (!id) {
206
+ throw new Error('Agent ID is required')
207
+ }
208
+
209
+ if (!ctx.principal || ctx.principal.id === 'anonymous' || !ctx.accountId) {
210
+ throw new Error('User context (person and account) required')
211
+ }
212
+
213
+ const allowed = ['name', 'description', 'model_config', 'system_prompt', 'tools', 'capabilities', 'constraints', 'metadata', 'is_active']
214
+ const updateData: Record<string, any> = { updated_at: new Date().toISOString() }
215
+ for (const key of allowed) {
216
+ if (updates[key] !== undefined) updateData[key] = updates[key]
217
+ }
218
+
219
+ const { data, error: err } = await ctx.db
220
+ .from('ai_agents')
221
+ .update(updateData)
222
+ .eq('id', id)
223
+ .select()
224
+ .single()
225
+
226
+ if (err) throw err
227
+
228
+ await emitLog(ctx, 'ai_agent.updated',
229
+ { type: 'ai_agent', id },
230
+ { after: updateData }
231
+ )
232
+
233
+ return data
234
+ })
235
+ // ─── CHUNK_END: AI_AGENTS_UPDATE ────────────────────────────────────────────────
236
+
237
+ // ─── CHUNK_START: AI_AGENTS_REMOVE ──────────────────────────────────────────────
238
+ /**
239
+ * @chunk-id AI_AGENTS_REMOVE_1_0_0
240
+ * @version 1.0.0
241
+ * @hash 7d990350b55b85945cc2148908618d6cd1dad27d1fc8343eab6966bedd9d84fa
242
+ * @macro AI Agent Remove Handler
243
+ * @micro Hard-deletes AI agent with validation and audit logging
244
+ * @inputs ctx: CoreContext — Request context with principal and database
245
+ * @inputs _body: any — Request body (unused for DELETE)
246
+ * @outputs {success: true} — Success confirmation
247
+ * @depends-on [createHandler, emitLog]
248
+ * @depended-by [Netlify function routing]
249
+ * @side-effects [DB delete, audit logging]
250
+ * @tags ai-agents, remove, crud, audit
251
+ */
252
+ export const remove = createHandler(async (ctx, _body) => {
253
+ const id = ctx.query?.id
254
+
255
+ if (!id) {
256
+ throw new Error('Agent ID is required')
257
+ }
258
+
259
+ const { data: current } = await ctx.db
260
+ .from('ai_agents')
261
+ .select('id, name')
262
+ .eq('id', id)
263
+ .single()
264
+
265
+ if (!current) throw new Error('Agent not found')
266
+
267
+ const { error: err } = await ctx.db
268
+ .from('ai_agents')
269
+ .delete()
270
+ .eq('id', id)
271
+
272
+ if (err) throw err
273
+
274
+ await emitLog(ctx, 'ai_agent.deleted',
275
+ { type: 'ai_agent', id },
276
+ { before: current }
277
+ )
278
+
279
+ return { success: true }
280
+ })
281
+ // ─── CHUNK_END: AI_AGENTS_REMOVE ────────────────────────────────────────────────
282
+
283
+ // ─── MAIN HANDLER ────────────────────────────────────────────────────────────
284
+
285
+ // ─── CHUNK_START: AI_AGENTS_HANDLER ──────────────────────────────────────────────
286
+ /**
287
+ * @chunk-id AI_AGENTS_HANDLER_1_0_0
288
+ * @version 1.0.0
289
+ * @hash a49f4917dd07295e0ba9815bf929cccc5cffcbe4dcf6852aa4bd84d6cba1b690
290
+ * @macro AI Agents Router
291
+ * @micro Routes HTTP methods to appropriate CRUD handlers
292
+ * @inputs ctx: CoreContext — Request context with principal and database
293
+ * @inputs body: any — Request body for POST/PATCH operations
294
+ * @outputs Varies — Depends on routed handler (list/get/create/update/remove)
295
+ * @depends-on [createHandler, list, get, create, update, remove]
296
+ * @depended-by [Netlify function routing]
297
+ * @side-effects [Delegates to appropriate handler]
298
+ * @tags ai-agents, router, crud, netlify-function
299
+ */
300
+ export const handler = createHandler(async (ctx, body) => {
301
+ const { action } = ctx.query || {}
302
+ const method = ctx.query?.method || 'GET'
303
+
304
+ switch (action) {
305
+ default:
306
+ if (method === 'GET') {
307
+ if (ctx.query?.id) {
308
+ return await get(ctx, body)
309
+ } else {
310
+ return await list(ctx, body)
311
+ }
312
+ } else if (method === 'POST') {
313
+ return await create(ctx, body)
314
+ } else if (method === 'PATCH') {
315
+ return await update(ctx, body)
316
+ } else if (method === 'DELETE') {
317
+ return await remove(ctx, body)
318
+ }
319
+ }
320
+
321
+ throw new Error('Invalid action or method')
322
+ })
323
+ // ─── CHUNK_END: AI_AGENTS_HANDLER ────────────────────────────────────────────────
@@ -0,0 +1,376 @@
1
+ /**
2
+ * @module api-keys
3
+ * @audience core-contributor
4
+ * @layer api-handler
5
+ * @stability stable
6
+ *
7
+ * Management and validation API for the `api_keys` table. API keys are
8
+ * issued per-integration and optionally scoped to specific permissions.
9
+ * Key material is generated and stored by the `create_api_key` Postgres
10
+ * RPC, which handles hashing internally. Validation also delegates to the
11
+ * `validate_api_key` RPC.
12
+ *
13
+ * **Routed by:** `GET/POST /.netlify/functions/api-keys`
14
+ *
15
+ * **Actions:**
16
+ * | method | ?action | handler |
17
+ * |--------|------------|---------------|
18
+ * | POST | validate | validate |
19
+ * | POST | revoke | revoke |
20
+ * | GET | usage-logs | listUsageLogs |
21
+ * | GET | ?id | get |
22
+ * | GET | (default) | list |
23
+ * | POST | — | create |
24
+ *
25
+ * **Authorization:** All operations use `ctx.db` (RLS-scoped). Account context
26
+ * required for creates. No PATCH/DELETE — use `revoke` for deactivation.
27
+ *
28
+ * INVARIANT: Raw key material is never stored. Only the hash is persisted.
29
+ * `create` returns the plaintext key once via RPC response.
30
+ * INVARIANT: `revoke` soft-deactivates by setting `is_active = false`.
31
+ *
32
+ * @seeAlso integrations.ts (integration_id FK on api_keys)
33
+ * @seeAlso audit.ts (emitLog for api_key.* events)
34
+ */
35
+
36
+ import { createHandler } from './_shared/middleware'
37
+ import { emitLog } from './_shared/audit'
38
+ import { sanitizeRecordData } from './_shared/permissions'
39
+
40
+ // ─── HANDLERS ─────────────────────────────────────────────────────────────────
41
+
42
+ // ─── CHUNK_START: API_KEYS_LIST ──────────────────────────────────────────────
43
+ /**
44
+ * @chunk-id API_KEYS_LIST_1_0_0
45
+ * @version 1.0.0
46
+ * @hash f825d8f4bbabe21071b61fe41e5e4e1b87482d501bf4078fab70906b7a5f5e78
47
+ * @macro API Keys List Handler
48
+ * @micro Lists API keys with filtering, pagination, and joins
49
+ * @inputs ctx: CoreContext — Request context with principal and database
50
+ * @inputs _body: any — Request body (unused for GET)
51
+ * @outputs Array of sanitized API key records with integration joins
52
+ * @depends-on [createHandler, sanitizeRecordData]
53
+ * @depended-by [Netlify function routing]
54
+ * @side-effects [DB queries, permission sanitization]
55
+ * @tags api-keys, list, crud, pagination
56
+ */
57
+ export const list = createHandler(async (ctx, _body) => {
58
+ const { integration_id, key_type, is_active, expires_before, expires_after, limit = 100, offset = 0 } = ctx.query || {}
59
+
60
+ if (!ctx.accountId) {
61
+ throw new Error('Account context required')
62
+ }
63
+
64
+ let query = ctx.db
65
+ .from('api_keys')
66
+ .select(`
67
+ *,
68
+ integration:integrations(id, name, provider, integration_type),
69
+ created_by_person:people(id, full_name, email)
70
+ `)
71
+ .order('created_at', { ascending: false })
72
+
73
+ if (integration_id) {
74
+ query = query.eq('integration_id', integration_id)
75
+ }
76
+ if (key_type) {
77
+ query = query.eq('key_type', key_type)
78
+ }
79
+ if (is_active !== undefined) {
80
+ query = query.eq('is_active', is_active === 'true')
81
+ }
82
+ if (expires_before) {
83
+ query = query.lte('expires_at', expires_before)
84
+ }
85
+ if (expires_after) {
86
+ query = query.gte('expires_at', expires_after)
87
+ }
88
+
89
+ const { data, error: err } = await query.range(
90
+ parseInt(offset.toString()),
91
+ parseInt(offset.toString()) + parseInt(limit.toString()) - 1
92
+ )
93
+
94
+ if (err) throw err
95
+
96
+ const sanitized = []
97
+ for (const key of data || []) {
98
+ sanitized.push(await sanitizeRecordData(ctx, key, 'api_key'))
99
+ }
100
+
101
+ return sanitized
102
+ })
103
+ // ─── CHUNK_END: API_KEYS_LIST ────────────────────────────────────────────────
104
+
105
+ // ─── CHUNK_START: API_KEYS_GET ──────────────────────────────────────────────
106
+ /**
107
+ * @chunk-id API_KEYS_GET_1_0_0
108
+ * @version 1.0.0
109
+ * @hash 357f926aeb833ad0ca755e48350534771f491890645134a1b43d2f2a8e4be037
110
+ * @macro API Key Get Handler
111
+ * @micro Returns a single API key record with joins (no raw key material)
112
+ * @inputs ctx: CoreContext — Request context with principal and database
113
+ * @inputs _body: any — Request body (unused for GET)
114
+ * @outputs Sanitized API key record with integration and createdBy joins
115
+ * @depends-on [createHandler, sanitizeRecordData]
116
+ * @depended-by [Netlify function routing]
117
+ * @side-effects [DB single row query, permission sanitization]
118
+ * @tags api-keys, get, crud, single-record
119
+ */
120
+ export const get = createHandler(async (ctx, _body) => {
121
+ const { id } = ctx.query || {}
122
+
123
+ if (!id) {
124
+ throw new Error('API key ID is required')
125
+ }
126
+
127
+ const { data, error: err } = await ctx.db
128
+ .from('api_keys')
129
+ .select(`
130
+ *,
131
+ integration:integrations(id, name, provider, integration_type),
132
+ created_by_person:people(id, full_name, email)
133
+ `)
134
+ .eq('id', id)
135
+ .single()
136
+
137
+ if (err) throw err
138
+
139
+ return await sanitizeRecordData(ctx, data, 'api_key')
140
+ })
141
+ // ─── CHUNK_END: API_KEYS_GET ────────────────────────────────────────────────
142
+
143
+ // ─── CHUNK_START: API_KEYS_CREATE ──────────────────────────────────────────────
144
+ /**
145
+ * @chunk-id API_KEYS_CREATE_1_0_0
146
+ * @version 1.0.0
147
+ * @hash 8d00c97111cddebc2b3821a1fee3e6cf4c6b7c55fc20cd19d70865d728c3387c
148
+ * @macro API Key Create Handler
149
+ * @micro Creates new API key via RPC with validation and audit logging
150
+ * @inputs ctx: CoreContext — Request context with principal and database
151
+ * @inputs body: object — API key configuration data
152
+ * @outputs RPC result containing api_key_id and plaintext key_value
153
+ * @depends-on [createHandler, emitLog]
154
+ * @depended-by [Netlify function routing]
155
+ * @side-effects [RPC call, audit logging]
156
+ * @tags api-keys, create, crud, rpc, audit
157
+ */
158
+ export const create = createHandler(async (ctx, body) => {
159
+ const { integration_id, name, key_type, key_prefix, permissions, rate_limit, expires_at, metadata } = body
160
+
161
+ if (!name) {
162
+ throw new Error('name is required')
163
+ }
164
+
165
+ if (!ctx.accountId) {
166
+ throw new Error('Account context required')
167
+ }
168
+
169
+ const { data, error: err } = await ctx.db
170
+ .rpc('create_api_key', {
171
+ integration_id,
172
+ name,
173
+ key_type: key_type || 'private',
174
+ key_prefix: key_prefix || 'sk_',
175
+ permissions: permissions || {},
176
+ rate_limit: rate_limit || 1000,
177
+ expires_at,
178
+ metadata: metadata || {},
179
+ created_by: ctx.principal?.id,
180
+ account_id: ctx.accountId
181
+ })
182
+
183
+ if (err) throw err
184
+
185
+ await emitLog(ctx, 'api_key.created',
186
+ { type: 'api_key', id: data[0]?.api_key_id },
187
+ { after: { name, key_type, rate_limit } }
188
+ )
189
+
190
+ return data
191
+ })
192
+ // ─── CHUNK_END: API_KEYS_CREATE ────────────────────────────────────────────────
193
+
194
+ // ─── CHUNK_START: API_KEYS_VALIDATE ──────────────────────────────────────────────
195
+ /**
196
+ * @chunk-id API_KEYS_VALIDATE_1_0_0
197
+ * @version 1.0.0
198
+ * @hash 05791f9b2c23bfebed01dffaa1430e896b89d311c5a51409704d731200eb621a
199
+ * @macro API Key Validation Handler
200
+ * @micro Validates API key and checks permissions via RPC
201
+ * @inputs ctx: CoreContext — Request context with principal and database
202
+ * @inputs body: object — key_value and optional required_permissions
203
+ * @outputs RPC validation result with is_valid, account_id, permissions
204
+ * @depends-on [createHandler]
205
+ * @depended-by [Netlify function routing, middleware]
206
+ * @side-effects [RPC validation call]
207
+ * @tags api-keys, validate, rpc, authentication
208
+ */
209
+ export const validate = createHandler(async (ctx, body) => {
210
+ const { key_value, required_permissions } = body
211
+
212
+ if (!key_value) {
213
+ throw new Error('key_value is required')
214
+ }
215
+
216
+ const { data, error: err } = await ctx.db
217
+ .rpc('validate_api_key', {
218
+ key_value,
219
+ required_permissions: required_permissions || {}
220
+ })
221
+
222
+ if (err) throw err
223
+
224
+ return data
225
+ })
226
+ // ─── CHUNK_END: API_KEYS_VALIDATE ────────────────────────────────────────────────
227
+
228
+ // ─── CHUNK_START: API_KEYS_REVOKE ──────────────────────────────────────────────
229
+ /**
230
+ * @chunk-id API_KEYS_REVOKE_1_0_0
231
+ * @version 1.0.0
232
+ * @hash 3302286a12c1315616470fcfbd3cbdc8dcf63dd00211a71159f3325bab95607a
233
+ * @macro API Key Revoke Handler
234
+ * @micro Soft-deactivates API key with validation and audit logging
235
+ * @inputs ctx: CoreContext — Request context with principal and database
236
+ * @inputs body: object — API key ID to revoke
237
+ * @outputs Updated API key record with is_active: false
238
+ * @depends-on [createHandler, emitLog]
239
+ * @depended-by [Netlify function routing]
240
+ * @side-effects [DB update, audit logging]
241
+ * @tags api-keys, revoke, crud, audit
242
+ */
243
+ export const revoke = createHandler(async (ctx, body) => {
244
+ const { id } = body
245
+
246
+ if (!id) {
247
+ throw new Error('API key ID is required')
248
+ }
249
+
250
+ const { data, error: err } = await ctx.db
251
+ .from('api_keys')
252
+ .update({ is_active: false, updated_at: new Date().toISOString() })
253
+ .eq('id', id)
254
+ .select()
255
+ .single()
256
+
257
+ if (err) throw err
258
+
259
+ await emitLog(ctx, 'api_key.revoked',
260
+ { type: 'api_key', id },
261
+ { after: { revoked_by: ctx.principal?.id } }
262
+ )
263
+
264
+ return data
265
+ })
266
+ // ─── CHUNK_END: API_KEYS_REVOKE ────────────────────────────────────────────────
267
+
268
+ // ─── CHUNK_START: API_KEYS_LIST_USAGE_LOGS ──────────────────────────────────────────────
269
+ /**
270
+ * @chunk-id API_KEYS_LIST_USAGE_LOGS_1_0_0
271
+ * @version 1.0.0
272
+ * @hash f21e004490dd983c8f20dc1d1f4db33e158334d19e38a4ace5e99389a8a96ded
273
+ * @macro API Key Usage Logs Handler
274
+ * @micro Lists paginated API key usage logs with filtering and joins
275
+ * @inputs ctx: CoreContext — Request context with principal and database
276
+ * @inputs _body: any — Request body (unused for GET)
277
+ * @outputs Array of usage log records with api_key joins
278
+ * @depends-on [createHandler]
279
+ * @depended-by [Netlify function routing]
280
+ * @side-effects [DB queries with filtering]
281
+ * @tags api-keys, usage-logs, pagination, monitoring
282
+ */
283
+ export const listUsageLogs = createHandler(async (ctx, _body) => {
284
+ const { api_key_id, response_status, success, date_from, date_to, limit = 100, offset = 0 } = ctx.query || {}
285
+
286
+ if (!ctx.accountId) {
287
+ throw new Error('Account context required')
288
+ }
289
+
290
+ let query = ctx.db
291
+ .from('api_key_usage_logs')
292
+ .select(`
293
+ *,
294
+ api_key:api_keys(id, name, key_type)
295
+ `)
296
+ .order('created_at', { ascending: false })
297
+
298
+ if (api_key_id) {
299
+ query = query.eq('api_key_id', api_key_id)
300
+ }
301
+ if (response_status) {
302
+ query = query.eq('response_status', parseInt(response_status.toString()))
303
+ }
304
+ if (success !== undefined) {
305
+ query = query.eq('success', success === 'true')
306
+ }
307
+ if (date_from) {
308
+ query = query.gte('created_at', date_from)
309
+ }
310
+ if (date_to) {
311
+ query = query.lte('created_at', date_to)
312
+ }
313
+
314
+ const { data, error: err } = await query.range(
315
+ parseInt(offset.toString()),
316
+ parseInt(offset.toString()) + parseInt(limit.toString()) - 1
317
+ )
318
+
319
+ if (err) throw err
320
+
321
+ return data
322
+ })
323
+ // ─── CHUNK_END: API_KEYS_LIST_USAGE_LOGS ────────────────────────────────────────────────
324
+
325
+ // ─── MAIN HANDLER ────────────────────────────────────────────────────────────
326
+
327
+ // ─── CHUNK_START: API_KEYS_HANDLER ──────────────────────────────────────────────
328
+ /**
329
+ * @chunk-id API_KEYS_HANDLER_1_0_0
330
+ * @version 1.0.0
331
+ * @hash 6c2da419bea6f12b0fe654e2aad6c5ebac3d5993c2547a47d239f44197d90a68
332
+ * @macro API Keys Router
333
+ * @micro Routes HTTP methods and actions to appropriate handlers
334
+ * @inputs ctx: CoreContext — Request context with principal and database
335
+ * @inputs body: any — Request body for POST operations
336
+ * @outputs Varies — Depends on routed handler (list/get/create/validate/revoke/usage-logs)
337
+ * @depends-on [createHandler, list, get, create, validate, revoke, listUsageLogs]
338
+ * @depended-by [Netlify function routing]
339
+ * @side-effects [Delegates to appropriate handler]
340
+ * @tags api-keys, router, crud, netlify-function
341
+ */
342
+ export const handler = createHandler(async (ctx, body) => {
343
+ const { action } = ctx.query || {}
344
+ const method = ctx.query?.method || 'GET'
345
+
346
+ switch (action) {
347
+ case 'validate':
348
+ if (method === 'POST') {
349
+ return await validate(ctx, body)
350
+ }
351
+ break
352
+ case 'revoke':
353
+ if (method === 'POST') {
354
+ return await revoke(ctx, body)
355
+ }
356
+ break
357
+ case 'usage-logs':
358
+ if (method === 'GET') {
359
+ return await listUsageLogs(ctx, body)
360
+ }
361
+ break
362
+ default:
363
+ if (method === 'GET') {
364
+ if (ctx.query?.id) {
365
+ return await get(ctx, body)
366
+ } else {
367
+ return await list(ctx, body)
368
+ }
369
+ } else if (method === 'POST') {
370
+ return await create(ctx, body)
371
+ }
372
+ }
373
+
374
+ throw new Error('Invalid action or method')
375
+ })
376
+ // ─── CHUNK_END: API_KEYS_HANDLER ────────────────────────────────────────────────