spine-framework 0.3.124 → 0.3.126

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (319) hide show
  1. package/.framework/cli/commands/agents.ts +35 -37
  2. package/.framework/cli/commands/auth.ts +35 -34
  3. package/.framework/cli/commands/create-app.ts +104 -40
  4. package/.framework/cli/commands/dev.ts +104 -69
  5. package/.framework/cli/commands/doctor.ts +179 -69
  6. package/.framework/cli/commands/generate.ts +83 -143
  7. package/.framework/cli/commands/init.ts +72 -34
  8. package/.framework/cli/commands/install-app.ts +260 -125
  9. package/.framework/cli/commands/items.ts +33 -44
  10. package/.framework/cli/commands/migrate.ts +122 -40
  11. package/.framework/cli/commands/migrations.ts +33 -40
  12. package/.framework/cli/commands/pipelines.ts +31 -39
  13. package/.framework/cli/commands/status.ts +47 -23
  14. package/.framework/cli/commands/system.ts +47 -37
  15. package/.framework/cli/commands/test.ts +112 -68
  16. package/.framework/cli/commands/validate-app.ts +215 -121
  17. package/.framework/cli/context.ts +112 -130
  18. package/.framework/cli/env-loader.ts +47 -18
  19. package/.framework/cli/index.ts +81 -42
  20. package/.framework/docs/runtime-types.md +1024 -0
  21. package/.framework/functions/_shared/agent-runner.ts +1296 -961
  22. package/.framework/functions/_shared/app-manifest.ts +82 -68
  23. package/.framework/functions/_shared/audit.ts +135 -83
  24. package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
  25. package/.framework/functions/_shared/db.ts +80 -126
  26. package/.framework/functions/_shared/hash-api-key.ts +63 -0
  27. package/.framework/functions/_shared/index.ts +224 -335
  28. package/.framework/functions/_shared/kb.ts +319 -0
  29. package/.framework/functions/_shared/llm.ts +92 -0
  30. package/.framework/functions/_shared/logging.ts +288 -0
  31. package/.framework/functions/_shared/middleware.ts +329 -365
  32. package/.framework/functions/_shared/outcomes.ts +36 -0
  33. package/.framework/functions/_shared/permissions.ts +359 -643
  34. package/.framework/functions/_shared/pipeline-runner.ts +243 -316
  35. package/.framework/functions/_shared/principal.ts +376 -468
  36. package/.framework/functions/_shared/resolve-credentials.ts +102 -0
  37. package/.framework/functions/_shared/resolve-ids.ts +188 -16
  38. package/.framework/functions/_shared/retry-deliveries.ts +104 -0
  39. package/.framework/functions/_shared/schema-utils.ts +611 -373
  40. package/.framework/functions/_shared/testing.ts +207 -137
  41. package/.framework/functions/_shared/tracing.ts +276 -0
  42. package/.framework/functions/_shared/trigger-engine.ts +159 -211
  43. package/.framework/functions/_shared/webhook-registration.ts +95 -81
  44. package/.framework/functions/_shared/webhook-registry.ts +153 -75
  45. package/.framework/functions/account-nodes.ts +31 -53
  46. package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
  47. package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
  48. package/.framework/functions/adapters/openai-outbound.ts +40 -0
  49. package/.framework/functions/admin-data.ts +685 -537
  50. package/.framework/functions/admin-funnel.ts +31 -20
  51. package/.framework/functions/admin-install-funnel.ts +47 -28
  52. package/.framework/functions/admin-signals.ts +47 -29
  53. package/.framework/functions/ai-agents.ts +122 -147
  54. package/.framework/functions/ai-interactions.ts +180 -90
  55. package/.framework/functions/api-keys.ts +250 -192
  56. package/.framework/functions/apps.ts +203 -197
  57. package/.framework/functions/auth.ts +98 -91
  58. package/.framework/functions/cil-agent-ingest.ts +773 -0
  59. package/.framework/functions/cil-agent.ts +592 -0
  60. package/.framework/functions/cil-callmap.ts +1227 -0
  61. package/.framework/functions/cil-config.ts +583 -0
  62. package/.framework/functions/cil-context.ts +445 -0
  63. package/.framework/functions/cil-doc.ts +1752 -0
  64. package/.framework/functions/cil-embeddings.ts +1202 -0
  65. package/.framework/functions/cil-graph.ts +585 -0
  66. package/.framework/functions/cil-ingest.ts +2416 -0
  67. package/.framework/functions/cil-pipeline.ts +318 -0
  68. package/.framework/functions/cil-project.ts +499 -0
  69. package/.framework/functions/cil-validate.ts +469 -0
  70. package/.framework/functions/debug-auth.ts +73 -53
  71. package/.framework/functions/deliveries.ts +117 -0
  72. package/.framework/functions/embeddings.ts +528 -516
  73. package/.framework/functions/eval-harness.ts +158 -106
  74. package/.framework/functions/integration-outbound.ts +311 -0
  75. package/.framework/functions/integration-routes.ts +240 -466
  76. package/.framework/functions/integrations.ts +132 -140
  77. package/.framework/functions/invites.ts +401 -201
  78. package/.framework/functions/item-progress.ts +113 -53
  79. package/.framework/functions/kb.ts +28 -0
  80. package/.framework/functions/logs.ts +239 -222
  81. package/.framework/functions/observability.ts +308 -259
  82. package/.framework/functions/pipeline-executions.ts +179 -235
  83. package/.framework/functions/pipelines.ts +163 -205
  84. package/.framework/functions/prompt-configs.ts +109 -156
  85. package/.framework/functions/roles.ts +97 -147
  86. package/.framework/functions/system-cron.ts +132 -218
  87. package/.framework/functions/system.ts +112 -52
  88. package/.framework/functions/tests.ts +32 -28
  89. package/.framework/functions/timers.ts +162 -210
  90. package/.framework/functions/triggers.ts +282 -346
  91. package/.framework/functions/types.ts +283 -400
  92. package/.framework/migrations/001_core_schema.sql +630 -0
  93. package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
  94. package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
  95. package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
  96. package/.framework/migrations/005_core_observability.sql +598 -0
  97. package/.framework/migrations/006_security_hardening_rls.sql +97 -0
  98. package/.framework/migrations/007_kb_article_list.sql +237 -0
  99. package/.framework/migrations/008_items_target.sql +8 -0
  100. package/.framework/migrations/009_roles_slug_unique.sql +11 -0
  101. package/.framework/public/spine.config.json +91 -0
  102. package/.framework/scripts/app-install-cli.ts +112 -98
  103. package/.framework/src/App.tsx +67 -20
  104. package/.framework/src/apps/admin/index.tsx +97 -27
  105. package/.framework/src/components/AppWrapper.tsx +50 -11
  106. package/.framework/src/components/CustomAppLoader.tsx +131 -22
  107. package/.framework/src/components/admin/AdminListPage.tsx +75 -8
  108. package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
  109. package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
  110. package/.framework/src/components/admin/PageInstructions.tsx +49 -0
  111. package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
  112. package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
  113. package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
  114. package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
  115. package/.framework/src/components/app-sidebar.tsx +50 -3
  116. package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
  117. package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
  118. package/.framework/src/components/kb/KBArticleList.tsx +557 -0
  119. package/.framework/src/components/layout/AppShell.tsx +54 -16
  120. package/.framework/src/components/layout/Header.tsx +50 -38
  121. package/.framework/src/components/layout/Layout.tsx +48 -32
  122. package/.framework/src/components/layout/Sidebar.tsx +167 -16
  123. package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
  124. package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
  125. package/.framework/src/components/runtime/DataFilters.tsx +78 -1
  126. package/.framework/src/components/runtime/DataHeader.tsx +32 -29
  127. package/.framework/src/components/runtime/DataListPage.tsx +161 -2
  128. package/.framework/src/components/runtime/DataStats.tsx +48 -1
  129. package/.framework/src/components/runtime/DataTable.tsx +153 -1
  130. package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
  131. package/.framework/src/components/runtime/index.ts +16 -9
  132. package/.framework/src/components/search-form.tsx +33 -1
  133. package/.framework/src/components/shared/AgentView.tsx +48 -51
  134. package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
  135. package/.framework/src/components/shared/InviteManager.tsx +113 -52
  136. package/.framework/src/components/shared/MemberList.tsx +182 -0
  137. package/.framework/src/components/shared/SchemaFields.tsx +96 -78
  138. package/.framework/src/components/ui/DataTable.tsx +86 -56
  139. package/.framework/src/components/ui/Form.tsx +188 -109
  140. package/.framework/src/components/ui/ItemCard.tsx +86 -58
  141. package/.framework/src/components/ui/ItemListView.tsx +88 -61
  142. package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
  143. package/.framework/src/components/ui/Modal.tsx +81 -4
  144. package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
  145. package/.framework/src/components/ui/accordion.tsx +97 -5
  146. package/.framework/src/components/ui/alert-dialog.tsx +225 -13
  147. package/.framework/src/components/ui/alert.tsx +113 -6
  148. package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
  149. package/.framework/src/components/ui/avatar.tsx +129 -7
  150. package/.framework/src/components/ui/badge.tsx +65 -3
  151. package/.framework/src/components/ui/breadcrumb.tsx +145 -8
  152. package/.framework/src/components/ui/button-group.tsx +81 -4
  153. package/.framework/src/components/ui/button.tsx +49 -2
  154. package/.framework/src/components/ui/calendar.tsx +65 -3
  155. package/.framework/src/components/ui/card.tsx +145 -8
  156. package/.framework/src/components/ui/carousel.tsx +129 -7
  157. package/.framework/src/components/ui/chart.tsx +161 -10
  158. package/.framework/src/components/ui/checkbox.tsx +49 -2
  159. package/.framework/src/components/ui/collapsible.tsx +81 -5
  160. package/.framework/src/components/ui/combobox.tsx +305 -20
  161. package/.framework/src/components/ui/command.tsx +177 -11
  162. package/.framework/src/components/ui/context-menu.tsx +273 -17
  163. package/.framework/src/components/ui/dialog.tsx +209 -27
  164. package/.framework/src/components/ui/direction.tsx +64 -4
  165. package/.framework/src/components/ui/drawer.tsx +193 -12
  166. package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
  167. package/.framework/src/components/ui/empty.tsx +145 -9
  168. package/.framework/src/components/ui/field.tsx +209 -14
  169. package/.framework/src/components/ui/hover-card.tsx +81 -4
  170. package/.framework/src/components/ui/input-group.tsx +162 -10
  171. package/.framework/src/components/ui/input-otp.tsx +98 -5
  172. package/.framework/src/components/ui/input.tsx +49 -2
  173. package/.framework/src/components/ui/item.tsx +225 -13
  174. package/.framework/src/components/ui/kbd.tsx +65 -3
  175. package/.framework/src/components/ui/label.tsx +49 -2
  176. package/.framework/src/components/ui/menubar.tsx +289 -17
  177. package/.framework/src/components/ui/native-select.tsx +97 -5
  178. package/.framework/src/components/ui/navigation-menu.tsx +177 -10
  179. package/.framework/src/components/ui/pagination.tsx +161 -9
  180. package/.framework/src/components/ui/popover.tsx +145 -8
  181. package/.framework/src/components/ui/progress.tsx +49 -2
  182. package/.framework/src/components/ui/radio-group.tsx +65 -3
  183. package/.framework/src/components/ui/resizable.tsx +82 -4
  184. package/.framework/src/components/ui/scroll-area.tsx +65 -3
  185. package/.framework/src/components/ui/select.tsx +193 -11
  186. package/.framework/src/components/ui/separator.tsx +49 -2
  187. package/.framework/src/components/ui/sheet.tsx +193 -11
  188. package/.framework/src/components/ui/sidebar.tsx +481 -38
  189. package/.framework/src/components/ui/skeleton.tsx +49 -2
  190. package/.framework/src/components/ui/slider.tsx +49 -2
  191. package/.framework/src/components/ui/sonner.tsx +49 -2
  192. package/.framework/src/components/ui/spinner.tsx +49 -2
  193. package/.framework/src/components/ui/switch.tsx +49 -2
  194. package/.framework/src/components/ui/table-primitives.tsx +160 -33
  195. package/.framework/src/components/ui/table.tsx +161 -9
  196. package/.framework/src/components/ui/tabs.tsx +113 -6
  197. package/.framework/src/components/ui/textarea.tsx +49 -2
  198. package/.framework/src/components/ui/toggle-group.tsx +81 -4
  199. package/.framework/src/components/ui/toggle.tsx +65 -3
  200. package/.framework/src/components/ui/tooltip.tsx +97 -5
  201. package/.framework/src/contexts/AppContext.tsx +129 -45
  202. package/.framework/src/contexts/AuthContext.tsx +187 -144
  203. package/.framework/src/hooks/use-mobile.ts +48 -2
  204. package/.framework/src/hooks/useApi.ts +208 -159
  205. package/.framework/src/hooks/useAppPath.ts +32 -23
  206. package/.framework/src/hooks/useApps.ts +51 -20
  207. package/.framework/src/hooks/useEntityList.ts +32 -78
  208. package/.framework/src/hooks/useEntityRecord.ts +35 -96
  209. package/.framework/src/hooks/useForm.ts +32 -92
  210. package/.framework/src/hooks/useListSchema.ts +49 -78
  211. package/.framework/src/hooks/useSchemaRecord.ts +114 -105
  212. package/.framework/src/lib/api.ts +195 -116
  213. package/.framework/src/lib/supabase.ts +98 -64
  214. package/.framework/src/lib/utils.ts +287 -151
  215. package/.framework/src/main.tsx +49 -3
  216. package/.framework/src/pages/DashboardPage.tsx +52 -29
  217. package/.framework/src/pages/NotFoundPage.tsx +32 -10
  218. package/.framework/src/pages/SetupPage.tsx +32 -12
  219. package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
  220. package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
  221. package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
  222. package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
  223. package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
  224. package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
  225. package/.framework/src/pages/admin/AppsPage.tsx +49 -2
  226. package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
  227. package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
  228. package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
  229. package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
  230. package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
  231. package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
  232. package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
  233. package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
  234. package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
  235. package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
  236. package/.framework/src/pages/admin/LogsPage.tsx +422 -75
  237. package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
  238. package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
  239. package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
  240. package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
  241. package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
  242. package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
  243. package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
  244. package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
  245. package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
  246. package/.framework/src/pages/admin/RolesPage.tsx +171 -18
  247. package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
  248. package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
  249. package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
  250. package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
  251. package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
  252. package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
  253. package/.framework/src/pages/admin/TimersPage.tsx +48 -20
  254. package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
  255. package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
  256. package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
  257. package/.framework/src/pages/admin/TypesPage.tsx +48 -20
  258. package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
  259. package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
  260. package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
  261. package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
  262. package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
  263. package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
  264. package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
  265. package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
  266. package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
  267. package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
  268. package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
  269. package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
  270. package/.framework/src/pages/auth/LoginPage.tsx +50 -23
  271. package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
  272. package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
  273. package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
  274. package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
  275. package/.framework/src/types/auth.ts +128 -71
  276. package/.framework/src/types/types.ts +373 -157
  277. package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
  278. package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
  279. package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
  280. package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
  281. package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
  282. package/docs/README.md +9 -130
  283. package/netlify.toml +5 -2
  284. package/package.json +13 -25
  285. package/scripts/kb-ingest-docs.ts +203 -0
  286. package/spine.config.json +65 -4
  287. package/.framework/migrations/001_schema.sql +0 -425
  288. package/.framework/migrations/002_rls_and_functions.sql +0 -763
  289. package/.framework/migrations/004_enhancements.sql +0 -43
  290. package/.framework/migrations/005_auth_user_trigger.sql +0 -105
  291. package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
  292. package/.framework/migrations/016_invites.sql +0 -27
  293. package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
  294. package/.framework/migrations/018_apps_required_roles.sql +0 -17
  295. package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
  296. package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
  297. package/.framework/migrations/021_app_domains.sql +0 -112
  298. package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
  299. package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
  300. package/.framework/migrations/024_messages_account_id.sql +0 -9
  301. package/.framework/migrations/025_retype_threads_messages.sql +0 -240
  302. package/.framework/migrations/026_fix_rls_policies.sql +0 -47
  303. package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
  304. package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
  305. package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
  306. package/.framework/migrations/030_messages_updated_by.sql +0 -6
  307. package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
  308. package/docs/APPS.md +0 -232
  309. package/docs/ARCHITECTURE.md +0 -246
  310. package/docs/INSTALL.md +0 -155
  311. package/docs/design-schema-spec.md +0 -1837
  312. package/docs/dev-guides/01-create-an-app.md +0 -183
  313. package/docs/dev-guides/02-create-a-function.md +0 -178
  314. package/docs/dev-guides/03-create-a-component.md +0 -178
  315. package/docs/dev-guides/04-webhook-handlers.md +0 -129
  316. package/docs/dev-guides/05-testing.md +0 -168
  317. package/docs/dev-guides/README.md +0 -40
  318. package/docs/npm-packages-plan.md +0 -288
  319. package/docs/spine-core--api-reference.md +0 -822
@@ -0,0 +1,237 @@
1
+ -- KB article list cache: a single row per scope/account that stores the
2
+ -- pre-built ordered tree of KB articles. Updated by trigger on structural
3
+ -- changes (parent, order, title, status, type) but NOT on content edits.
4
+
5
+ -- 1. Create the kb-article-list type
6
+ INSERT INTO public.types (
7
+ app_id, kind, slug, name, description, icon, color,
8
+ design_schema, validation_schema, ownership, is_active, created_at, updated_at
9
+ )
10
+ VALUES (
11
+ NULL,
12
+ 'item',
13
+ 'kb-article-list',
14
+ 'KB Article List',
15
+ 'Cached ordered article trees for the KB UI',
16
+ 'List',
17
+ NULL,
18
+ $JSON${
19
+ "scope": "platform",
20
+ "fields": {
21
+ "title": { "data_type": "text", "label": "Title", "required": true, "system": true },
22
+ "status": { "data_type": "select", "label": "Status", "required": true, "system": true, "options": ["draft", "published", "archived"] },
23
+ "trees": { "data_type": "json", "label": "Trees", "required": false }
24
+ },
25
+ "views": {
26
+ "default_list": {
27
+ "type": "list",
28
+ "label": "KB Article Lists",
29
+ "fields": {
30
+ "title": { "sortable": true, "display_type": "text" },
31
+ "status": { "sortable": true, "display_type": "badge" },
32
+ "created_at": { "sortable": true, "display_type": "timestamp" }
33
+ },
34
+ "default_sort": { "field": "created_at", "direction": "desc" }
35
+ },
36
+ "default_detail": {
37
+ "type": "detail",
38
+ "label": "KB Article List",
39
+ "sections": [
40
+ {
41
+ "title": "Core",
42
+ "fields": {
43
+ "title": { "display_type": "input" },
44
+ "status": { "display_type": "select" },
45
+ "trees": { "display_type": "textarea" }
46
+ }
47
+ }
48
+ ]
49
+ }
50
+ },
51
+ "record_permissions": {
52
+ "all": ["read"],
53
+ "system-admin": ["create", "read", "update", "delete"],
54
+ "admin": ["create", "read", "update", "delete"],
55
+ "member": ["read"]
56
+ },
57
+ "functionality": null
58
+ }$JSON$::jsonb,
59
+ $JSON${
60
+ "fields": {
61
+ "title": { "data_type": "text", "required": true },
62
+ "status": { "data_type": "select", "required": true, "options": ["draft", "published", "archived"] }
63
+ }
64
+ }$JSON$::jsonb,
65
+ NULL,
66
+ true,
67
+ now(),
68
+ now()
69
+ )
70
+ ON CONFLICT (slug) DO UPDATE SET
71
+ design_schema = EXCLUDED.design_schema,
72
+ validation_schema = EXCLUDED.validation_schema,
73
+ is_active = true,
74
+ updated_at = now();
75
+
76
+ -- 2. Function to rebuild the cache for a given account + scope
77
+ CREATE OR REPLACE FUNCTION public.rebuild_kb_cache(p_account_id uuid, p_scope text)
78
+ RETURNS void
79
+ LANGUAGE plpgsql
80
+ SECURITY DEFINER
81
+ AS $$
82
+ DECLARE
83
+ v_cache_type_id uuid := (SELECT id FROM public.types WHERE slug = 'kb-article-list');
84
+ v_data jsonb := '{}'::jsonb;
85
+ v_tree jsonb;
86
+ r RECORD;
87
+ v_title text := CASE p_scope WHEN 'global' THEN 'KB Article List - Global' ELSE 'KB Article List - Account' END;
88
+ v_type_slugs text[] := CASE p_scope
89
+ WHEN 'global' THEN ARRAY['kb-spine-public', 'kb-spine-internal', 'kb-spine-admin']
90
+ ELSE ARRAY['kb-account']
91
+ END;
92
+ BEGIN
93
+ FOR r IN
94
+ SELECT t.id AS type_id, t.slug AS type_slug
95
+ FROM public.types t
96
+ WHERE t.slug = ANY(v_type_slugs)
97
+ LOOP
98
+ SELECT COALESCE(jsonb_agg(
99
+ jsonb_build_object(
100
+ 'id', i.id,
101
+ 'title', i.title,
102
+ 'status', i.status,
103
+ 'type_slug', r.type_slug,
104
+ 'type_id', r.type_id,
105
+ 'data', jsonb_build_object(
106
+ 'parent_id', i.data->>'parent_id',
107
+ 'order', COALESCE((i.data->>'order')::int, 0),
108
+ 'description', i.data->>'description'
109
+ )
110
+ ) ORDER BY COALESCE((i.data->>'order')::int, 0), i.title
111
+ ), '[]'::jsonb)
112
+ INTO v_tree
113
+ FROM public.items i
114
+ WHERE i.type_id = r.type_id
115
+ AND i.status != 'deleted'
116
+ AND i.account_id = p_account_id;
117
+
118
+ v_data := jsonb_set(v_data, ARRAY[r.type_slug], v_tree);
119
+ END LOOP;
120
+
121
+ UPDATE public.items
122
+ SET data = jsonb_build_object('trees', v_data),
123
+ updated_at = now(),
124
+ title = v_title
125
+ WHERE type_id = v_cache_type_id
126
+ AND account_id = p_account_id
127
+ AND status != 'deleted';
128
+
129
+ IF NOT FOUND THEN
130
+ INSERT INTO public.items (
131
+ type_id, account_id, app_id, title, description, status,
132
+ data, is_active, design_schema, validation_schema,
133
+ created_by, updated_by, created_at, updated_at
134
+ )
135
+ SELECT
136
+ v_cache_type_id, p_account_id, NULL, v_title, NULL, 'published',
137
+ jsonb_build_object('trees', v_data), true,
138
+ t.design_schema, t.validation_schema,
139
+ NULL, NULL, now(), now()
140
+ FROM public.types t
141
+ WHERE t.id = v_cache_type_id;
142
+ END IF;
143
+ END;
144
+ $$;
145
+
146
+ -- 3. Trigger function to decide when to rebuild
147
+ CREATE OR REPLACE FUNCTION public.trg_rebuild_kb_article_list()
148
+ RETURNS trigger
149
+ LANGUAGE plpgsql
150
+ SECURITY DEFINER
151
+ AS $$
152
+ DECLARE
153
+ p_type_id uuid;
154
+ p_account_id uuid;
155
+ p_scope text;
156
+ BEGIN
157
+ IF TG_OP = 'DELETE' THEN
158
+ p_type_id := OLD.type_id;
159
+ p_account_id := OLD.account_id;
160
+ ELSE
161
+ p_type_id := NEW.type_id;
162
+ p_account_id := NEW.account_id;
163
+ END IF;
164
+
165
+ -- don't recurse on the cache record itself
166
+ IF p_type_id = (SELECT id FROM public.types WHERE slug = 'kb-article-list') THEN
167
+ RETURN COALESCE(NEW, OLD);
168
+ END IF;
169
+
170
+ -- only the KB article types we care about
171
+ IF p_type_id NOT IN (
172
+ SELECT id FROM public.types WHERE slug IN (
173
+ 'kb-spine-public', 'kb-spine-internal', 'kb-spine-admin', 'kb-account'
174
+ )
175
+ ) THEN
176
+ RETURN COALESCE(NEW, OLD);
177
+ END IF;
178
+
179
+ -- on UPDATE, skip if only the article body/content changed
180
+ IF TG_OP = 'UPDATE' THEN
181
+ IF NEW.type_id = OLD.type_id AND
182
+ NEW.title = OLD.title AND
183
+ NEW.status = OLD.status AND
184
+ NEW.data->>'parent_id' IS NOT DISTINCT FROM OLD.data->>'parent_id' AND
185
+ NEW.data->>'order' IS NOT DISTINCT FROM OLD.data->>'order'
186
+ THEN
187
+ RETURN NEW;
188
+ END IF;
189
+ END IF;
190
+
191
+ p_scope := CASE
192
+ WHEN p_type_id IN (
193
+ SELECT id FROM public.types WHERE slug IN (
194
+ 'kb-spine-public', 'kb-spine-internal', 'kb-spine-admin'
195
+ )
196
+ ) THEN 'global'
197
+ ELSE 'account'
198
+ END;
199
+
200
+ PERFORM public.rebuild_kb_cache(p_account_id, p_scope);
201
+ RETURN COALESCE(NEW, OLD);
202
+ END;
203
+ $$;
204
+
205
+ DROP TRIGGER IF EXISTS trg_rebuild_kb_article_list ON public.items;
206
+ CREATE TRIGGER trg_rebuild_kb_article_list
207
+ AFTER INSERT OR UPDATE OR DELETE ON public.items
208
+ FOR EACH ROW
209
+ EXECUTE FUNCTION public.trg_rebuild_kb_article_list();
210
+
211
+ -- 4. Seed initial cache records for existing accounts
212
+ DO $$
213
+ DECLARE
214
+ global_account_id uuid;
215
+ acc_id uuid;
216
+ BEGIN
217
+ -- global cache (where the global KB types live)
218
+ SELECT i.account_id INTO global_account_id
219
+ FROM public.items i
220
+ JOIN public.types t ON i.type_id = t.id
221
+ WHERE t.slug = 'kb-spine-public'
222
+ LIMIT 1;
223
+
224
+ IF global_account_id IS NOT NULL THEN
225
+ PERFORM public.rebuild_kb_cache(global_account_id, 'global');
226
+ END IF;
227
+
228
+ -- account-specific caches
229
+ FOR acc_id IN
230
+ SELECT DISTINCT i.account_id
231
+ FROM public.items i
232
+ JOIN public.types t ON i.type_id = t.id
233
+ WHERE t.slug = 'kb-account'
234
+ LOOP
235
+ PERFORM public.rebuild_kb_cache(acc_id, 'account');
236
+ END LOOP;
237
+ END $$;
@@ -0,0 +1,8 @@
1
+ -- Add target scoping columns to public.items to align with threads, links, and watchers.
2
+ -- This lets any item (note, ticket, deal, etc.) be explicitly scoped to a person or account.
3
+
4
+ ALTER TABLE public.items
5
+ ADD COLUMN IF NOT EXISTS target_type text,
6
+ ADD COLUMN IF NOT EXISTS target_id uuid;
7
+
8
+ CREATE INDEX IF NOT EXISTS idx_items_target ON public.items (target_type, target_id);
@@ -0,0 +1,11 @@
1
+ -- Idempotent: safe for fresh (001 already has this) and existing DBs.
2
+ -- If duplicates exist, the DBA must dedupe before running; this migration
3
+ -- will fail with a clear constraint-violation error until they do.
4
+
5
+ ALTER TABLE public.roles
6
+ DROP CONSTRAINT IF EXISTS roles_app_id_slug_key;
7
+
8
+ DROP INDEX IF EXISTS roles_app_id_slug_key;
9
+
10
+ CREATE UNIQUE INDEX IF NOT EXISTS roles_slug_key
11
+ ON public.roles (slug);
@@ -0,0 +1,91 @@
1
+ {
2
+ "$schema": "./.framework/schemas/spine.config.schema.json",
3
+ "registration": {
4
+ "default_app": "workbench",
5
+ "default_role": "engineering",
6
+ "allow_url_override": true,
7
+ "default_app_by_role": {
8
+ "member": "portal",
9
+ "member_admin": "portal",
10
+ "support": "cortex",
11
+ "support_admin": "cortex",
12
+ "sales": "cortex",
13
+ "csm": "cortex",
14
+ "tam": "cortex",
15
+ "engineering": "workbench",
16
+ "engineering_admin": "workbench",
17
+ "devops": "workbench",
18
+ "product": "workbench",
19
+ "docs": "workbench",
20
+ "qa": "workbench",
21
+ "management": "workbench",
22
+ "system_admin": "workbench"
23
+ },
24
+ "apps": {
25
+ "portal": {
26
+ "roles": [
27
+ "member",
28
+ "member_admin",
29
+ "support",
30
+ "support_admin",
31
+ "sales",
32
+ "csm",
33
+ "tam",
34
+ "engineering",
35
+ "engineering_admin",
36
+ "product",
37
+ "docs",
38
+ "qa",
39
+ "devops",
40
+ "management"
41
+ ],
42
+ "default_role": "member",
43
+ "path": "/portal",
44
+ "enabled": true,
45
+ "account_strategy": "new"
46
+ },
47
+ "cortex": {
48
+ "roles": [
49
+ "support",
50
+ "support_admin",
51
+ "sales",
52
+ "csm",
53
+ "tam",
54
+ "engineering",
55
+ "engineering_admin",
56
+ "product",
57
+ "docs",
58
+ "qa",
59
+ "devops",
60
+ "management"
61
+ ],
62
+ "default_role": "support",
63
+ "path": "/cortex",
64
+ "enabled": true,
65
+ "account_strategy": "existing",
66
+ "target_account": "spine-system"
67
+ },
68
+ "workbench": {
69
+ "roles": [
70
+ "engineering",
71
+ "engineering_admin",
72
+ "product",
73
+ "docs",
74
+ "qa",
75
+ "devops",
76
+ "management",
77
+ "support",
78
+ "support_admin",
79
+ "sales",
80
+ "csm",
81
+ "tam"
82
+ ],
83
+ "default_role": "engineering",
84
+ "path": "/workbench",
85
+ "enabled": true,
86
+ "account_strategy": "existing",
87
+ "target_account": "spine-system"
88
+ }
89
+ }
90
+ }
91
+ }