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
@@ -1,240 +0,0 @@
1
- -- Migration 025: Retype existing support/community threads and messages
2
- -- After creating support_thread, support_reply, community_thread, community_reply
3
- -- types, this migration retypes existing rows that were created with the generic
4
- -- thread/message types and re-stamps design_schema/validation_schema.
5
- --
6
- -- It is self-contained: it creates/updates the required types first so that the
7
- -- migration does not depend on app seed files having already been run.
8
- --
9
- -- It preserves the existing design_schema.scope (inherited from the parent record)
10
- -- so account-scoped support records stay account-scoped and platform-scoped
11
- -- community records stay platform-scoped.
12
-
13
- -- Helper function to pick the first active type by slug
14
- CREATE OR REPLACE FUNCTION public._tmp_first_type_id(p_slug text)
15
- RETURNS uuid AS $$
16
- SELECT id FROM public.types WHERE slug = p_slug AND is_active = true ORDER BY created_at LIMIT 1;
17
- $$ LANGUAGE sql STABLE;
18
-
19
- -- 0. Ensure the required types exist and have the correct scope/kind.
20
-
21
- -- 0a. Fix generic thread and message types: scope should be account.
22
- -- (They may be under any app_id; we update all active ones.)
23
- UPDATE public.types
24
- SET design_schema = jsonb_set(
25
- COALESCE(design_schema, '{}'::jsonb),
26
- '{scope}',
27
- '"account"'
28
- )
29
- WHERE slug IN ('thread', 'message')
30
- AND is_active = true
31
- AND COALESCE(design_schema->>'scope', 'platform') != 'account';
32
-
33
- -- 0b. Deactivate any stale community_reply item type so it does not shadow the
34
- -- message type. It is safe to deactivate because no items should reference it.
35
- UPDATE public.types
36
- SET is_active = false
37
- WHERE slug = 'community_reply'
38
- AND kind = 'item'
39
- AND is_active = true;
40
-
41
- -- 0c. Determine the owner app_id for the new domain types.
42
- -- Prefer the app that owns support_ticket/community_post; fall back to portal,
43
- -- then any active app.
44
- DO $$
45
- DECLARE
46
- v_owner_app_id uuid;
47
- BEGIN
48
- SELECT app_id INTO v_owner_app_id
49
- FROM public.types
50
- WHERE slug IN ('support_ticket', 'community_post')
51
- AND is_active = true
52
- LIMIT 1;
53
-
54
- IF v_owner_app_id IS NULL THEN
55
- SELECT id INTO v_owner_app_id FROM public.apps WHERE slug = 'portal' AND is_active = true LIMIT 1;
56
- END IF;
57
-
58
- IF v_owner_app_id IS NULL THEN
59
- SELECT id INTO v_owner_app_id FROM public.apps WHERE is_active = true LIMIT 1;
60
- END IF;
61
-
62
- -- Create the four domain types if they don't already exist with the correct kind.
63
-
64
- -- support_thread
65
- IF NOT EXISTS (SELECT 1 FROM public.types WHERE slug = 'support_thread' AND kind = 'thread' AND is_active = true) THEN
66
- INSERT INTO public.types (id, app_id, kind, slug, name, description, icon, color, ownership, is_active, validation_schema, design_schema)
67
- VALUES (
68
- gen_random_uuid(),
69
- v_owner_app_id,
70
- 'thread',
71
- 'support_thread',
72
- 'Support Thread',
73
- 'Customer-visible conversation thread attached to a support ticket',
74
- 'message-square',
75
- '#EF4444',
76
- 'tenant',
77
- true,
78
- '{}'::jsonb,
79
- jsonb_build_object(
80
- 'scope', 'account',
81
- 'record_permissions', jsonb_build_object(
82
- 'system_admin', ARRAY['create', 'read', 'update', 'delete'],
83
- 'support_admin', ARRAY['create', 'read', 'update'],
84
- 'support', ARRAY['create', 'read', 'update'],
85
- 'member_admin', ARRAY['create', 'read', 'update'],
86
- 'member', ARRAY['create', 'read', 'update']
87
- )
88
- )
89
- );
90
- END IF;
91
-
92
- -- support_reply
93
- IF NOT EXISTS (SELECT 1 FROM public.types WHERE slug = 'support_reply' AND kind = 'message' AND is_active = true) THEN
94
- INSERT INTO public.types (id, app_id, kind, slug, name, description, icon, color, ownership, is_active, validation_schema, design_schema)
95
- VALUES (
96
- gen_random_uuid(),
97
- v_owner_app_id,
98
- 'message',
99
- 'support_reply',
100
- 'Support Reply',
101
- 'Customer or agent message within a support thread',
102
- 'message-circle',
103
- '#EF4444',
104
- 'tenant',
105
- true,
106
- '{}'::jsonb,
107
- jsonb_build_object(
108
- 'scope', 'account',
109
- 'record_permissions', jsonb_build_object(
110
- 'system_admin', ARRAY['create', 'read', 'update', 'delete'],
111
- 'support_admin', ARRAY['create', 'read', 'update'],
112
- 'support', ARRAY['create', 'read', 'update'],
113
- 'member_admin', ARRAY['create', 'read', 'update'],
114
- 'member', ARRAY['create', 'read', 'update']
115
- )
116
- )
117
- );
118
- END IF;
119
-
120
- -- community_thread
121
- IF NOT EXISTS (SELECT 1 FROM public.types WHERE slug = 'community_thread' AND kind = 'thread' AND is_active = true) THEN
122
- INSERT INTO public.types (id, app_id, kind, slug, name, description, icon, color, ownership, is_active, validation_schema, design_schema)
123
- VALUES (
124
- gen_random_uuid(),
125
- v_owner_app_id,
126
- 'thread',
127
- 'community_thread',
128
- 'Community Thread',
129
- 'Public discussion thread attached to a community post',
130
- 'users',
131
- '#6366F1',
132
- 'tenant',
133
- true,
134
- '{}'::jsonb,
135
- jsonb_build_object(
136
- 'scope', 'platform',
137
- 'record_permissions', jsonb_build_object(
138
- 'system_admin', ARRAY['create', 'read', 'update', 'delete'],
139
- 'support_admin', ARRAY['create', 'read', 'update'],
140
- 'support', ARRAY['create', 'read', 'update'],
141
- 'member_admin', ARRAY['create', 'read', 'update'],
142
- 'member', ARRAY['create', 'read', 'update']
143
- )
144
- )
145
- );
146
- END IF;
147
-
148
- -- community_reply
149
- IF NOT EXISTS (SELECT 1 FROM public.types WHERE slug = 'community_reply' AND kind = 'message' AND is_active = true) THEN
150
- INSERT INTO public.types (id, app_id, kind, slug, name, description, icon, color, ownership, is_active, validation_schema, design_schema)
151
- VALUES (
152
- gen_random_uuid(),
153
- v_owner_app_id,
154
- 'message',
155
- 'community_reply',
156
- 'Community Reply',
157
- 'Public reply within a community thread',
158
- 'message-circle',
159
- '#22C55E',
160
- 'tenant',
161
- true,
162
- '{}'::jsonb,
163
- jsonb_build_object(
164
- 'scope', 'platform',
165
- 'record_permissions', jsonb_build_object(
166
- 'system_admin', ARRAY['create', 'read', 'update', 'delete'],
167
- 'support_admin', ARRAY['create', 'read', 'update'],
168
- 'support', ARRAY['create', 'read', 'update'],
169
- 'member_admin', ARRAY['create', 'read', 'update'],
170
- 'member', ARRAY['create', 'read', 'update']
171
- )
172
- )
173
- );
174
- END IF;
175
- END $$;
176
-
177
- -- 1. Support threads -> support_thread
178
- UPDATE public.threads t
179
- SET
180
- type_id = public._tmp_first_type_id('support_thread'),
181
- design_schema = jsonb_set(
182
- (SELECT design_schema FROM public.types WHERE id = public._tmp_first_type_id('support_thread')),
183
- '{scope}',
184
- COALESCE(t.design_schema->'scope', '"account"')::jsonb
185
- ),
186
- validation_schema = (SELECT validation_schema FROM public.types WHERE id = public._tmp_first_type_id('support_thread'))
187
- FROM public.items i
188
- WHERE t.target_type = 'items'
189
- AND t.target_id = i.id
190
- AND i.type_id = public._tmp_first_type_id('support_ticket')
191
- AND t.type_id != public._tmp_first_type_id('support_thread');
192
-
193
- -- 2. Community threads -> community_thread
194
- UPDATE public.threads t
195
- SET
196
- type_id = public._tmp_first_type_id('community_thread'),
197
- design_schema = jsonb_set(
198
- (SELECT design_schema FROM public.types WHERE id = public._tmp_first_type_id('community_thread')),
199
- '{scope}',
200
- COALESCE(t.design_schema->'scope', '"platform"')::jsonb
201
- ),
202
- validation_schema = (SELECT validation_schema FROM public.types WHERE id = public._tmp_first_type_id('community_thread'))
203
- FROM public.items i
204
- WHERE t.target_type = 'items'
205
- AND t.target_id = i.id
206
- AND i.type_id = public._tmp_first_type_id('community_post')
207
- AND t.type_id != public._tmp_first_type_id('community_thread');
208
-
209
- -- 3. Support messages -> support_reply
210
- UPDATE public.messages m
211
- SET
212
- type_id = public._tmp_first_type_id('support_reply'),
213
- design_schema = jsonb_set(
214
- (SELECT design_schema FROM public.types WHERE id = public._tmp_first_type_id('support_reply')),
215
- '{scope}',
216
- COALESCE(t.design_schema->'scope', '"account"')::jsonb
217
- ),
218
- validation_schema = (SELECT validation_schema FROM public.types WHERE id = public._tmp_first_type_id('support_reply'))
219
- FROM public.threads t
220
- WHERE m.thread_id = t.id
221
- AND t.type_id = public._tmp_first_type_id('support_thread')
222
- AND m.type_id != public._tmp_first_type_id('support_reply');
223
-
224
- -- 4. Community messages -> community_reply
225
- UPDATE public.messages m
226
- SET
227
- type_id = public._tmp_first_type_id('community_reply'),
228
- design_schema = jsonb_set(
229
- (SELECT design_schema FROM public.types WHERE id = public._tmp_first_type_id('community_reply')),
230
- '{scope}',
231
- COALESCE(t.design_schema->'scope', '"platform"')::jsonb
232
- ),
233
- validation_schema = (SELECT validation_schema FROM public.types WHERE id = public._tmp_first_type_id('community_reply'))
234
- FROM public.threads t
235
- WHERE m.thread_id = t.id
236
- AND t.type_id = public._tmp_first_type_id('community_thread')
237
- AND m.type_id != public._tmp_first_type_id('community_reply');
238
-
239
- -- Drop the temporary helper
240
- DROP FUNCTION IF EXISTS public._tmp_first_type_id(text);
@@ -1,47 +0,0 @@
1
- -- Migration 026: Fix RLS policies to use current_actor_id() and runtime design_schema scope
2
- --
3
- -- The policies for threads and messages were using auth.uid() inside get_accessible_accounts(),
4
- -- but that function expects the internal person_id (from current_actor_id()). This broke account
5
- -- hierarchy checks for regular users. Additionally, the policies hardcoded the 'platform' scope
6
- -- check. This migration makes them scope-driven: any non-platform scope is treated as account-scoped.
7
- --
8
- -- Threads and messages now look at the runtime record's stamped design_schema for access, and
9
- -- messages also filter by visibility so internal support notes stay internal.
10
-
11
- -- threads (runtime record design_schema is the source of truth for scope)
12
- DROP POLICY IF EXISTS threads_access ON public.threads;
13
- CREATE POLICY threads_access ON public.threads FOR ALL
14
- USING (
15
- design_schema->>'scope' = 'platform' AND public.current_actor_id() IS NOT NULL
16
- OR account_id IN (SELECT public.get_accessible_accounts(public.current_actor_id()))
17
- OR public.current_actor_id() IS NULL
18
- );
19
-
20
- -- messages (inherits thread access from the runtime record design_schema; visibility
21
- -- filters internal notes to support/support_admin roles)
22
- DROP POLICY IF EXISTS messages_access ON public.messages;
23
- CREATE POLICY messages_access ON public.messages FOR ALL
24
- USING (
25
- EXISTS (
26
- SELECT 1 FROM public.threads t
27
- WHERE t.id = messages.thread_id
28
- AND (
29
- t.design_schema->>'scope' = 'platform' AND public.current_actor_id() IS NOT NULL
30
- OR t.account_id IN (SELECT public.get_accessible_accounts(public.current_actor_id()))
31
- )
32
- )
33
- AND (
34
- messages.visibility IS NULL
35
- OR messages.visibility = 'external'
36
- OR (
37
- messages.visibility = 'internal'
38
- AND EXISTS (
39
- SELECT 1 FROM public.people p
40
- JOIN public.roles r ON p.role_id = r.id
41
- WHERE p.id = public.current_actor_id()
42
- AND (r.slug IN ('support', 'support_admin') OR r.is_system = true)
43
- )
44
- )
45
- )
46
- OR public.current_actor_id() IS NULL
47
- );
@@ -1,176 +0,0 @@
1
- -- Migration 027: Embedding lifecycle — approved_at, revoked_at, content_hash
2
- --
3
- -- Adds three columns to the embeddings table so that:
4
- -- 1. Only approved embeddings are returned by match_embeddings (hard filter, not prompt-based).
5
- -- 2. Embeddings are invalidated automatically when their source item is unpublished or deleted.
6
- -- 3. Re-embedding is skipped when content has not changed (content_hash deduplication).
7
- --
8
- -- Adds filter_item_types parameter to match_embeddings RPC so agents can restrict
9
- -- retrieval to specific content types (kb_article, code_chunk, db_schema, etc.) at
10
- -- the DB layer rather than relying on post-processing.
11
- --
12
- -- Adds helper functions revoke_embeddings_for_item and approve_embeddings_for_item
13
- -- called by the items_embedding_sync trigger.
14
- --
15
- -- IMPORTANT: approved_at defaults to now() so all existing embeddings are treated
16
- -- as approved. revoked_at defaults to NULL (not revoked).
17
-
18
- -- ============================================
19
- -- COLUMNS
20
- -- ============================================
21
-
22
- ALTER TABLE public.embeddings
23
- ADD COLUMN IF NOT EXISTS approved_at timestamptz DEFAULT now(),
24
- ADD COLUMN IF NOT EXISTS revoked_at timestamptz DEFAULT NULL,
25
- ADD COLUMN IF NOT EXISTS content_hash text DEFAULT NULL;
26
-
27
- -- Partial index for fast active-embedding lookups (approved and not revoked)
28
- CREATE INDEX IF NOT EXISTS embeddings_active_idx
29
- ON public.embeddings (account_id, document_id)
30
- WHERE approved_at IS NOT NULL AND revoked_at IS NULL;
31
-
32
- -- ============================================
33
- -- HELPER FUNCTIONS
34
- -- ============================================
35
-
36
- -- Revoke all embeddings for a given item (called when item leaves published state)
37
- CREATE OR REPLACE FUNCTION public.revoke_embeddings_for_item(p_item_id uuid)
38
- RETURNS integer
39
- LANGUAGE plpgsql
40
- SECURITY DEFINER
41
- SET search_path = public
42
- AS $$
43
- DECLARE
44
- v_count integer;
45
- BEGIN
46
- UPDATE public.embeddings
47
- SET revoked_at = now()
48
- WHERE document_id = p_item_id::text
49
- AND revoked_at IS NULL;
50
-
51
- GET DIAGNOSTICS v_count = ROW_COUNT;
52
- RETURN v_count;
53
- END;
54
- $$;
55
-
56
- -- Approve all embeddings for a given item (called when item re-enters published state)
57
- CREATE OR REPLACE FUNCTION public.approve_embeddings_for_item(p_item_id uuid)
58
- RETURNS integer
59
- LANGUAGE plpgsql
60
- SECURITY DEFINER
61
- SET search_path = public
62
- AS $$
63
- DECLARE
64
- v_count integer;
65
- BEGIN
66
- UPDATE public.embeddings
67
- SET approved_at = now(),
68
- revoked_at = NULL
69
- WHERE document_id = p_item_id::text;
70
-
71
- GET DIAGNOSTICS v_count = ROW_COUNT;
72
- RETURN v_count;
73
- END;
74
- $$;
75
-
76
- GRANT EXECUTE ON FUNCTION public.revoke_embeddings_for_item(uuid) TO service_role;
77
- GRANT EXECUTE ON FUNCTION public.approve_embeddings_for_item(uuid) TO service_role;
78
-
79
- -- ============================================
80
- -- ITEMS → EMBEDDINGS SYNC TRIGGER
81
- -- ============================================
82
- -- When an item's status changes, keep its embeddings in sync automatically.
83
- -- published → approve (clear revoked_at, set approved_at)
84
- -- anything → revoke (set revoked_at, leave approved_at intact for audit)
85
-
86
- CREATE OR REPLACE FUNCTION public.sync_item_embeddings()
87
- RETURNS TRIGGER
88
- LANGUAGE plpgsql
89
- SECURITY DEFINER
90
- SET search_path = public
91
- AS $$
92
- BEGIN
93
- -- Only act on status changes
94
- IF OLD.status IS NOT DISTINCT FROM NEW.status THEN
95
- RETURN NEW;
96
- END IF;
97
-
98
- IF NEW.status = 'published' THEN
99
- PERFORM public.approve_embeddings_for_item(NEW.id);
100
- ELSE
101
- PERFORM public.revoke_embeddings_for_item(NEW.id);
102
- END IF;
103
-
104
- RETURN NEW;
105
- END;
106
- $$;
107
-
108
- DROP TRIGGER IF EXISTS items_embedding_sync ON public.items;
109
- CREATE TRIGGER items_embedding_sync
110
- AFTER UPDATE OF status ON public.items
111
- FOR EACH ROW
112
- EXECUTE FUNCTION public.sync_item_embeddings();
113
-
114
- -- ============================================
115
- -- UPDATED match_embeddings RPC
116
- -- ============================================
117
- -- Adds filter_item_types parameter and hard approved_at / revoked_at filter.
118
- -- Backward compatible: existing callers that omit filter_item_types get the same
119
- -- behaviour as before, except that revoked / unapproved embeddings are now excluded.
120
-
121
- CREATE OR REPLACE FUNCTION public.match_embeddings(
122
- query_embedding vector(1536),
123
- match_count int DEFAULT 10,
124
- filter_account_ids uuid[] DEFAULT NULL,
125
- filter_vector_type text DEFAULT NULL,
126
- similarity_threshold float DEFAULT 0.15,
127
- filter_item_types text[] DEFAULT NULL
128
- )
129
- RETURNS TABLE (
130
- id uuid,
131
- document_id text,
132
- content text,
133
- metadata jsonb,
134
- account_id uuid,
135
- similarity float
136
- )
137
- LANGUAGE plpgsql
138
- SECURITY DEFINER
139
- SET search_path = public
140
- AS $$
141
- BEGIN
142
- RETURN QUERY
143
- SELECT
144
- e.id,
145
- e.document_id,
146
- e.content,
147
- e.metadata,
148
- e.account_id,
149
- 1 - (e.embedding <=> query_embedding) AS similarity
150
- FROM public.embeddings e
151
- WHERE
152
- -- ── Hard lifecycle filter — never negotiable ──────────────────────────
153
- e.approved_at IS NOT NULL
154
- AND e.revoked_at IS NULL
155
-
156
- -- ── Account scope (NULL = no account filter — platform-wide search) ───
157
- AND (filter_account_ids IS NULL OR e.account_id = ANY(filter_account_ids))
158
-
159
- -- ── Vector type (NULL = all types) ────────────────────────────────────
160
- AND (filter_vector_type IS NULL OR e.metadata->>'vector_type' = filter_vector_type)
161
-
162
- -- ── Item type (NULL = all item types) ─────────────────────────────────
163
- AND (filter_item_types IS NULL OR e.metadata->>'item_type' = ANY(filter_item_types))
164
-
165
- -- ── Similarity gate ───────────────────────────────────────────────────
166
- AND (1 - (e.embedding <=> query_embedding)) >= similarity_threshold
167
-
168
- ORDER BY e.embedding <=> query_embedding
169
- LIMIT match_count;
170
- END;
171
- $$;
172
-
173
- -- Re-grant execute to all roles (replace = drop+create resets grants)
174
- GRANT EXECUTE ON FUNCTION public.match_embeddings(vector, int, uuid[], text, float, text[]) TO authenticated;
175
- GRANT EXECUTE ON FUNCTION public.match_embeddings(vector, int, uuid[], text, float, text[]) TO service_role;
176
- GRANT EXECUTE ON FUNCTION public.match_embeddings(vector, int, uuid[], text, float, text[]) TO anon;
@@ -1,49 +0,0 @@
1
- -- Migration 028: Add AI metadata fields to support_reply/community_reply design_schema
2
- --
3
- -- Existing message rows were stamped with the old design_schema, which did not
4
- -- declare permissions for AI metadata fields (message_type, confidence, retrieved_sources,
5
- -- feedback, etc.). The permission sanitizer therefore stripped those fields from API
6
- -- responses, hiding the AI label, confidence badge, sources, and feedback UI.
7
- --
8
- -- This migration updates both the type definitions and the stamped design_schema on
9
- -- every existing message record so the new fields are readable (and feedback writable
10
- -- by members) without loosening the permission model.
11
-
12
- DO $$
13
- DECLARE
14
- ai_fields jsonb := '{
15
- "message_type": { "data_type": "text", "label": "Message Type", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } },
16
- "confidence": { "data_type": "number", "label": "AI Confidence", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } },
17
- "retrieval_confidence": { "data_type": "number", "label": "Retrieval Confidence", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } },
18
- "retrieved_sources": { "data_type": "json", "label": "Retrieved Sources", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } },
19
- "agent_id": { "data_type": "text", "label": "Agent ID", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } },
20
- "prompt_config_id": { "data_type": "text", "label": "Prompt Config ID", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } },
21
- "sender_type": { "data_type": "text", "label": "Sender Type", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } },
22
- "feedback": { "data_type": "text", "label": "Feedback", "system": true, "permissions": { "system_admin": ["read", "write"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read", "write"], "member": ["read", "write"] } },
23
- "feedback_at": { "data_type": "datetime", "label": "Feedback At", "system": true, "permissions": { "system_admin": ["read", "write"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read", "write"], "member": ["read", "write"] } },
24
- "escalated": { "data_type": "boolean", "label": "Escalated", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } },
25
- "suggested_title": { "data_type": "text", "label": "Suggested Title", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } },
26
- "tool_calls": { "data_type": "json", "label": "Tool Calls", "system": true, "permissions": { "system_admin": ["read"], "support_admin": ["read"], "support": ["read"], "member_admin": ["read"], "member": ["read"] } }
27
- }'::jsonb;
28
- BEGIN
29
- -- Update type definitions
30
- UPDATE types
31
- SET design_schema = jsonb_set(
32
- design_schema,
33
- '{fields}',
34
- COALESCE(design_schema->'fields', '{}'::jsonb) || ai_fields
35
- )
36
- WHERE slug IN ('support_reply', 'community_reply')
37
- AND kind = 'message';
38
-
39
- -- Update stamped design_schema on existing messages
40
- UPDATE messages
41
- SET design_schema = jsonb_set(
42
- design_schema,
43
- '{fields}',
44
- COALESCE(design_schema->'fields', '{}'::jsonb) || ai_fields
45
- )
46
- WHERE type_id IN (
47
- SELECT id FROM types WHERE slug IN ('support_reply', 'community_reply') AND kind = 'message'
48
- );
49
- END $$;
@@ -1,41 +0,0 @@
1
- -- Migration 029: Tighten the support_triage prompt so the AI escalates when no relevant knowledge is retrieved.
2
- --
3
- -- The previous prompt told the agent to "respond helpfully and accurately" without
4
- -- explicitly forbidding general-knowledge answers or clarifying questions. This led to
5
- -- the AI asking questions even when the knowledge base was empty. This migration
6
- -- updates both the prompt_config and the agent's system_prompt to enforce:
7
- -- 1. answer only from retrieved knowledge
8
- -- 2. escalate immediately when no relevant knowledge is retrieved
9
- -- 3. never ask the customer clarifying questions
10
-
11
- UPDATE prompt_configs
12
- SET context_template = 'A customer has submitted the following support request:
13
-
14
- {{user_message}}
15
-
16
- You may only answer using the relevant information provided in this prompt under ''## Relevant Information''.
17
-
18
- Rules:
19
- - If no relevant information is provided, or if it is insufficient to answer confidently, you MUST escalate to a human agent.
20
- - Do not ask the customer clarifying questions.
21
- - Do not answer from general knowledge or make up information.
22
- - Be concise, accurate, and empathetic.
23
-
24
- If you escalate, write a brief message telling the customer that a human support agent will review their request and follow up shortly.',
25
- output_mode = 'text',
26
- updated_at = now()
27
- WHERE slug = 'support_triage';
28
-
29
- UPDATE ai_agents
30
- SET system_prompt = 'You are a first-line support agent for a software platform. Your goal is to resolve customer issues accurately and efficiently on the first response, using only the knowledge retrieved for you.
31
-
32
- Guidelines:
33
- - Be concise and clear. Customers want answers, not essays.
34
- - You may only answer using the retrieved knowledge base articles and prior cases provided in your context.
35
- - If no relevant knowledge is retrieved, or if it is insufficient to answer confidently, escalate to a human agent immediately.
36
- - Do not ask the customer clarifying questions.
37
- - Never fabricate feature behaviour, make promises about the product, or answer from general knowledge.
38
- - If you escalate, tell the customer that a human support agent will review their request and follow up shortly.
39
- - Tone: professional but warm. Match the customer''s level of formality.',
40
- updated_at = now()
41
- WHERE name = 'Support Triage Agent';
@@ -1,6 +0,0 @@
1
- -- Migration 030: Add missing updated_by column to messages table
2
- -- The messages table was created without updated_by, causing PATCH requests
3
- -- via admin-data to fail when the audit stamp tries to set that field.
4
-
5
- ALTER TABLE public.messages
6
- ADD COLUMN IF NOT EXISTS updated_by uuid REFERENCES public.people(id) ON DELETE SET NULL;
@@ -1,35 +0,0 @@
1
- -- Migration 031: Add unique constraints required for idempotent app seed upserts
2
- --
3
- -- The install-app seeder uses ON CONFLICT(app_id, name) for ai_agents and
4
- -- pipelines, and ON CONFLICT(app_id, slug) for prompt_configs. Without these
5
- -- constraints the seeder falls back to plain INSERT, causing duplicates on
6
- -- re-install.
7
- --
8
- -- Safe to re-run: uses IF NOT EXISTS guard via DO block.
9
-
10
- DO $$
11
- BEGIN
12
- -- ai_agents: unique on (app_id, name)
13
- IF NOT EXISTS (
14
- SELECT 1 FROM pg_constraint
15
- WHERE conname = 'ai_agents_app_id_name_key'
16
- ) THEN
17
- ALTER TABLE public.ai_agents ADD CONSTRAINT ai_agents_app_id_name_key UNIQUE (app_id, name);
18
- END IF;
19
-
20
- -- prompt_configs: unique on (app_id, slug)
21
- IF NOT EXISTS (
22
- SELECT 1 FROM pg_constraint
23
- WHERE conname = 'prompt_configs_app_id_slug_key'
24
- ) THEN
25
- ALTER TABLE public.prompt_configs ADD CONSTRAINT prompt_configs_app_id_slug_key UNIQUE (app_id, slug);
26
- END IF;
27
-
28
- -- pipelines: unique on (app_id, name)
29
- IF NOT EXISTS (
30
- SELECT 1 FROM pg_constraint
31
- WHERE conname = 'pipelines_app_id_name_key'
32
- ) THEN
33
- ALTER TABLE public.pipelines ADD CONSTRAINT pipelines_app_id_name_key UNIQUE (app_id, name);
34
- END IF;
35
- END $$;