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.
- package/.framework/cli/commands/agents.ts +35 -37
- package/.framework/cli/commands/auth.ts +35 -34
- package/.framework/cli/commands/create-app.ts +104 -40
- package/.framework/cli/commands/dev.ts +104 -69
- package/.framework/cli/commands/doctor.ts +179 -69
- package/.framework/cli/commands/generate.ts +83 -143
- package/.framework/cli/commands/init.ts +72 -34
- package/.framework/cli/commands/install-app.ts +260 -125
- package/.framework/cli/commands/items.ts +33 -44
- package/.framework/cli/commands/migrate.ts +122 -40
- package/.framework/cli/commands/migrations.ts +33 -40
- package/.framework/cli/commands/pipelines.ts +31 -39
- package/.framework/cli/commands/status.ts +47 -23
- package/.framework/cli/commands/system.ts +47 -37
- package/.framework/cli/commands/test.ts +112 -68
- package/.framework/cli/commands/validate-app.ts +215 -121
- package/.framework/cli/context.ts +112 -130
- package/.framework/cli/env-loader.ts +47 -18
- package/.framework/cli/index.ts +81 -42
- package/.framework/docs/runtime-types.md +1024 -0
- package/.framework/functions/_shared/agent-runner.ts +1296 -961
- package/.framework/functions/_shared/app-manifest.ts +82 -68
- package/.framework/functions/_shared/audit.ts +135 -83
- package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
- package/.framework/functions/_shared/db.ts +80 -126
- package/.framework/functions/_shared/hash-api-key.ts +63 -0
- package/.framework/functions/_shared/index.ts +224 -335
- package/.framework/functions/_shared/kb.ts +319 -0
- package/.framework/functions/_shared/llm.ts +92 -0
- package/.framework/functions/_shared/logging.ts +288 -0
- package/.framework/functions/_shared/middleware.ts +329 -365
- package/.framework/functions/_shared/outcomes.ts +36 -0
- package/.framework/functions/_shared/permissions.ts +359 -643
- package/.framework/functions/_shared/pipeline-runner.ts +243 -316
- package/.framework/functions/_shared/principal.ts +376 -468
- package/.framework/functions/_shared/resolve-credentials.ts +102 -0
- package/.framework/functions/_shared/resolve-ids.ts +188 -16
- package/.framework/functions/_shared/retry-deliveries.ts +104 -0
- package/.framework/functions/_shared/schema-utils.ts +611 -373
- package/.framework/functions/_shared/testing.ts +207 -137
- package/.framework/functions/_shared/tracing.ts +276 -0
- package/.framework/functions/_shared/trigger-engine.ts +159 -211
- package/.framework/functions/_shared/webhook-registration.ts +95 -81
- package/.framework/functions/_shared/webhook-registry.ts +153 -75
- package/.framework/functions/account-nodes.ts +31 -53
- package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
- package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
- package/.framework/functions/adapters/openai-outbound.ts +40 -0
- package/.framework/functions/admin-data.ts +685 -537
- package/.framework/functions/admin-funnel.ts +31 -20
- package/.framework/functions/admin-install-funnel.ts +47 -28
- package/.framework/functions/admin-signals.ts +47 -29
- package/.framework/functions/ai-agents.ts +122 -147
- package/.framework/functions/ai-interactions.ts +180 -90
- package/.framework/functions/api-keys.ts +250 -192
- package/.framework/functions/apps.ts +203 -197
- package/.framework/functions/auth.ts +98 -91
- package/.framework/functions/cil-agent-ingest.ts +773 -0
- package/.framework/functions/cil-agent.ts +592 -0
- package/.framework/functions/cil-callmap.ts +1227 -0
- package/.framework/functions/cil-config.ts +583 -0
- package/.framework/functions/cil-context.ts +445 -0
- package/.framework/functions/cil-doc.ts +1752 -0
- package/.framework/functions/cil-embeddings.ts +1202 -0
- package/.framework/functions/cil-graph.ts +585 -0
- package/.framework/functions/cil-ingest.ts +2416 -0
- package/.framework/functions/cil-pipeline.ts +318 -0
- package/.framework/functions/cil-project.ts +499 -0
- package/.framework/functions/cil-validate.ts +469 -0
- package/.framework/functions/debug-auth.ts +73 -53
- package/.framework/functions/deliveries.ts +117 -0
- package/.framework/functions/embeddings.ts +528 -516
- package/.framework/functions/eval-harness.ts +158 -106
- package/.framework/functions/integration-outbound.ts +311 -0
- package/.framework/functions/integration-routes.ts +240 -466
- package/.framework/functions/integrations.ts +132 -140
- package/.framework/functions/invites.ts +401 -201
- package/.framework/functions/item-progress.ts +113 -53
- package/.framework/functions/kb.ts +28 -0
- package/.framework/functions/logs.ts +239 -222
- package/.framework/functions/observability.ts +308 -259
- package/.framework/functions/pipeline-executions.ts +179 -235
- package/.framework/functions/pipelines.ts +163 -205
- package/.framework/functions/prompt-configs.ts +109 -156
- package/.framework/functions/roles.ts +97 -147
- package/.framework/functions/system-cron.ts +132 -218
- package/.framework/functions/system.ts +112 -52
- package/.framework/functions/tests.ts +32 -28
- package/.framework/functions/timers.ts +162 -210
- package/.framework/functions/triggers.ts +282 -346
- package/.framework/functions/types.ts +283 -400
- package/.framework/migrations/001_core_schema.sql +630 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
- package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
- package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
- package/.framework/migrations/005_core_observability.sql +598 -0
- package/.framework/migrations/006_security_hardening_rls.sql +97 -0
- package/.framework/migrations/007_kb_article_list.sql +237 -0
- package/.framework/migrations/008_items_target.sql +8 -0
- package/.framework/migrations/009_roles_slug_unique.sql +11 -0
- package/.framework/public/spine.config.json +91 -0
- package/.framework/scripts/app-install-cli.ts +112 -98
- package/.framework/src/App.tsx +67 -20
- package/.framework/src/apps/admin/index.tsx +97 -27
- package/.framework/src/components/AppWrapper.tsx +50 -11
- package/.framework/src/components/CustomAppLoader.tsx +131 -22
- package/.framework/src/components/admin/AdminListPage.tsx +75 -8
- package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
- package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
- package/.framework/src/components/admin/PageInstructions.tsx +49 -0
- package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
- package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
- package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
- package/.framework/src/components/app-sidebar.tsx +50 -3
- package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
- package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
- package/.framework/src/components/kb/KBArticleList.tsx +557 -0
- package/.framework/src/components/layout/AppShell.tsx +54 -16
- package/.framework/src/components/layout/Header.tsx +50 -38
- package/.framework/src/components/layout/Layout.tsx +48 -32
- package/.framework/src/components/layout/Sidebar.tsx +167 -16
- package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
- package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
- package/.framework/src/components/runtime/DataFilters.tsx +78 -1
- package/.framework/src/components/runtime/DataHeader.tsx +32 -29
- package/.framework/src/components/runtime/DataListPage.tsx +161 -2
- package/.framework/src/components/runtime/DataStats.tsx +48 -1
- package/.framework/src/components/runtime/DataTable.tsx +153 -1
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
- package/.framework/src/components/runtime/index.ts +16 -9
- package/.framework/src/components/search-form.tsx +33 -1
- package/.framework/src/components/shared/AgentView.tsx +48 -51
- package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
- package/.framework/src/components/shared/InviteManager.tsx +113 -52
- package/.framework/src/components/shared/MemberList.tsx +182 -0
- package/.framework/src/components/shared/SchemaFields.tsx +96 -78
- package/.framework/src/components/ui/DataTable.tsx +86 -56
- package/.framework/src/components/ui/Form.tsx +188 -109
- package/.framework/src/components/ui/ItemCard.tsx +86 -58
- package/.framework/src/components/ui/ItemListView.tsx +88 -61
- package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
- package/.framework/src/components/ui/Modal.tsx +81 -4
- package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
- package/.framework/src/components/ui/accordion.tsx +97 -5
- package/.framework/src/components/ui/alert-dialog.tsx +225 -13
- package/.framework/src/components/ui/alert.tsx +113 -6
- package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
- package/.framework/src/components/ui/avatar.tsx +129 -7
- package/.framework/src/components/ui/badge.tsx +65 -3
- package/.framework/src/components/ui/breadcrumb.tsx +145 -8
- package/.framework/src/components/ui/button-group.tsx +81 -4
- package/.framework/src/components/ui/button.tsx +49 -2
- package/.framework/src/components/ui/calendar.tsx +65 -3
- package/.framework/src/components/ui/card.tsx +145 -8
- package/.framework/src/components/ui/carousel.tsx +129 -7
- package/.framework/src/components/ui/chart.tsx +161 -10
- package/.framework/src/components/ui/checkbox.tsx +49 -2
- package/.framework/src/components/ui/collapsible.tsx +81 -5
- package/.framework/src/components/ui/combobox.tsx +305 -20
- package/.framework/src/components/ui/command.tsx +177 -11
- package/.framework/src/components/ui/context-menu.tsx +273 -17
- package/.framework/src/components/ui/dialog.tsx +209 -27
- package/.framework/src/components/ui/direction.tsx +64 -4
- package/.framework/src/components/ui/drawer.tsx +193 -12
- package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
- package/.framework/src/components/ui/empty.tsx +145 -9
- package/.framework/src/components/ui/field.tsx +209 -14
- package/.framework/src/components/ui/hover-card.tsx +81 -4
- package/.framework/src/components/ui/input-group.tsx +162 -10
- package/.framework/src/components/ui/input-otp.tsx +98 -5
- package/.framework/src/components/ui/input.tsx +49 -2
- package/.framework/src/components/ui/item.tsx +225 -13
- package/.framework/src/components/ui/kbd.tsx +65 -3
- package/.framework/src/components/ui/label.tsx +49 -2
- package/.framework/src/components/ui/menubar.tsx +289 -17
- package/.framework/src/components/ui/native-select.tsx +97 -5
- package/.framework/src/components/ui/navigation-menu.tsx +177 -10
- package/.framework/src/components/ui/pagination.tsx +161 -9
- package/.framework/src/components/ui/popover.tsx +145 -8
- package/.framework/src/components/ui/progress.tsx +49 -2
- package/.framework/src/components/ui/radio-group.tsx +65 -3
- package/.framework/src/components/ui/resizable.tsx +82 -4
- package/.framework/src/components/ui/scroll-area.tsx +65 -3
- package/.framework/src/components/ui/select.tsx +193 -11
- package/.framework/src/components/ui/separator.tsx +49 -2
- package/.framework/src/components/ui/sheet.tsx +193 -11
- package/.framework/src/components/ui/sidebar.tsx +481 -38
- package/.framework/src/components/ui/skeleton.tsx +49 -2
- package/.framework/src/components/ui/slider.tsx +49 -2
- package/.framework/src/components/ui/sonner.tsx +49 -2
- package/.framework/src/components/ui/spinner.tsx +49 -2
- package/.framework/src/components/ui/switch.tsx +49 -2
- package/.framework/src/components/ui/table-primitives.tsx +160 -33
- package/.framework/src/components/ui/table.tsx +161 -9
- package/.framework/src/components/ui/tabs.tsx +113 -6
- package/.framework/src/components/ui/textarea.tsx +49 -2
- package/.framework/src/components/ui/toggle-group.tsx +81 -4
- package/.framework/src/components/ui/toggle.tsx +65 -3
- package/.framework/src/components/ui/tooltip.tsx +97 -5
- package/.framework/src/contexts/AppContext.tsx +129 -45
- package/.framework/src/contexts/AuthContext.tsx +187 -144
- package/.framework/src/hooks/use-mobile.ts +48 -2
- package/.framework/src/hooks/useApi.ts +208 -159
- package/.framework/src/hooks/useAppPath.ts +32 -23
- package/.framework/src/hooks/useApps.ts +51 -20
- package/.framework/src/hooks/useEntityList.ts +32 -78
- package/.framework/src/hooks/useEntityRecord.ts +35 -96
- package/.framework/src/hooks/useForm.ts +32 -92
- package/.framework/src/hooks/useListSchema.ts +49 -78
- package/.framework/src/hooks/useSchemaRecord.ts +114 -105
- package/.framework/src/lib/api.ts +195 -116
- package/.framework/src/lib/supabase.ts +98 -64
- package/.framework/src/lib/utils.ts +287 -151
- package/.framework/src/main.tsx +49 -3
- package/.framework/src/pages/DashboardPage.tsx +52 -29
- package/.framework/src/pages/NotFoundPage.tsx +32 -10
- package/.framework/src/pages/SetupPage.tsx +32 -12
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
- package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
- package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
- package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
- package/.framework/src/pages/admin/AppsPage.tsx +49 -2
- package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
- package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
- package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
- package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
- package/.framework/src/pages/admin/LogsPage.tsx +422 -75
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
- package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
- package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
- package/.framework/src/pages/admin/RolesPage.tsx +171 -18
- package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
- package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
- package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
- package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
- package/.framework/src/pages/admin/TimersPage.tsx +48 -20
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
- package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
- package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
- package/.framework/src/pages/admin/TypesPage.tsx +48 -20
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
- package/.framework/src/pages/auth/LoginPage.tsx +50 -23
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
- package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
- package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
- package/.framework/src/types/auth.ts +128 -71
- package/.framework/src/types/types.ts +373 -157
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
- package/docs/README.md +9 -130
- package/netlify.toml +5 -2
- package/package.json +13 -25
- package/scripts/kb-ingest-docs.ts +203 -0
- package/spine.config.json +65 -4
- package/.framework/migrations/001_schema.sql +0 -425
- package/.framework/migrations/002_rls_and_functions.sql +0 -763
- package/.framework/migrations/004_enhancements.sql +0 -43
- package/.framework/migrations/005_auth_user_trigger.sql +0 -105
- package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
- package/.framework/migrations/016_invites.sql +0 -27
- package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
- package/.framework/migrations/018_apps_required_roles.sql +0 -17
- package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
- package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
- package/.framework/migrations/021_app_domains.sql +0 -112
- package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
- package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
- package/.framework/migrations/024_messages_account_id.sql +0 -9
- package/.framework/migrations/025_retype_threads_messages.sql +0 -240
- package/.framework/migrations/026_fix_rls_policies.sql +0 -47
- package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
- package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
- package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
- package/.framework/migrations/030_messages_updated_by.sql +0 -6
- package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
- package/docs/APPS.md +0 -232
- package/docs/ARCHITECTURE.md +0 -246
- package/docs/INSTALL.md +0 -155
- package/docs/design-schema-spec.md +0 -1837
- package/docs/dev-guides/01-create-an-app.md +0 -183
- package/docs/dev-guides/02-create-a-function.md +0 -178
- package/docs/dev-guides/03-create-a-component.md +0 -178
- package/docs/dev-guides/04-webhook-handlers.md +0 -129
- package/docs/dev-guides/05-testing.md +0 -168
- package/docs/dev-guides/README.md +0 -40
- package/docs/npm-packages-plan.md +0 -288
- package/docs/spine-core--api-reference.md +0 -822
|
@@ -1,10 +1,5 @@
|
|
|
1
|
-
--
|
|
2
|
-
--
|
|
3
|
-
-- runtime types, admin app, and RPC functions.
|
|
4
|
-
|
|
5
|
-
-- ============================================
|
|
6
|
-
-- 1. SYSTEM ROLE (system_admin)
|
|
7
|
-
-- ============================================
|
|
1
|
+
-- Spine v2 consolidated core system data
|
|
2
|
+
-- System roles and essential platform records.
|
|
8
3
|
|
|
9
4
|
INSERT INTO public.roles (id, slug, name, description, permissions, is_system, is_active, is_protected, app_id, account_id)
|
|
10
5
|
VALUES (
|
|
@@ -19,136 +14,25 @@ VALUES (
|
|
|
19
14
|
NULL,
|
|
20
15
|
NULL
|
|
21
16
|
)
|
|
22
|
-
ON CONFLICT (app_id, slug) DO NOTHING;
|
|
23
|
-
|
|
24
|
-
-- NOTE: System account inserted after types are seeded (section 5) to satisfy FK constraint.
|
|
25
|
-
|
|
26
|
-
-- ============================================
|
|
27
|
-
-- 3. SYSTEM APP (spine-core)
|
|
28
|
-
-- ============================================
|
|
29
|
-
|
|
30
|
-
INSERT INTO public.apps (id, slug, name, description, version, app_type, source, is_active, is_system, renderer, route_prefix)
|
|
31
|
-
VALUES (
|
|
32
|
-
gen_random_uuid(),
|
|
33
|
-
'spine-core',
|
|
34
|
-
'Spine Core',
|
|
35
|
-
'Core Spine runtime - provides accounts, people, items, threads, messages, links, attachments, watchers',
|
|
36
|
-
'1.0.0',
|
|
37
|
-
'system',
|
|
38
|
-
'builtin',
|
|
39
|
-
true,
|
|
40
|
-
true,
|
|
41
|
-
'none',
|
|
42
|
-
NULL
|
|
43
|
-
)
|
|
44
17
|
ON CONFLICT (slug) DO NOTHING;
|
|
45
18
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
gen_random_uuid(),
|
|
57
|
-
'
|
|
58
|
-
'
|
|
59
|
-
'
|
|
60
|
-
|
|
61
|
-
'slate',
|
|
62
|
-
'1.0.0',
|
|
63
|
-
'system',
|
|
64
|
-
'builtin',
|
|
65
|
-
'{}'::jsonb,
|
|
66
|
-
'[]'::jsonb,
|
|
67
|
-
'system_admin',
|
|
68
|
-
true,
|
|
69
|
-
true,
|
|
70
|
-
'/admin',
|
|
71
|
-
'custom'
|
|
72
|
-
)
|
|
73
|
-
ON CONFLICT (slug) DO UPDATE SET
|
|
74
|
-
route_prefix = EXCLUDED.route_prefix,
|
|
75
|
-
renderer = EXCLUDED.renderer,
|
|
76
|
-
min_role = EXCLUDED.min_role,
|
|
77
|
-
is_system = EXCLUDED.is_system,
|
|
78
|
-
app_type = EXCLUDED.app_type;
|
|
79
|
-
|
|
80
|
-
-- ============================================
|
|
81
|
-
-- 5. RUNTIME ENTITY TYPES (8 core types)
|
|
82
|
-
-- ============================================
|
|
83
|
-
|
|
84
|
-
DO $$
|
|
85
|
-
DECLARE
|
|
86
|
-
v_spine_core_app_id uuid;
|
|
87
|
-
v_system_account_id uuid;
|
|
88
|
-
BEGIN
|
|
89
|
-
SELECT id INTO v_spine_core_app_id FROM public.apps WHERE slug = 'spine-core' LIMIT 1;
|
|
90
|
-
SELECT id INTO v_system_account_id FROM public.accounts WHERE slug = 'spine-system' LIMIT 1;
|
|
91
|
-
|
|
92
|
-
-- 5.1 accounts type
|
|
93
|
-
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
94
|
-
VALUES (
|
|
95
|
-
gen_random_uuid(),
|
|
96
|
-
v_spine_core_app_id,
|
|
97
|
-
'account',
|
|
98
|
-
'account',
|
|
99
|
-
'Account',
|
|
100
|
-
'Organization or tenant account',
|
|
101
|
-
jsonb_build_object(
|
|
102
|
-
'scope', 'account',
|
|
103
|
-
'record_permissions', jsonb_build_object('system_admin', ARRAY['create', 'read', 'update', 'delete']),
|
|
104
|
-
'fields', jsonb_build_object(
|
|
105
|
-
'slug', jsonb_build_object('data_type', 'text', 'label', 'Slug', 'required', true, 'system', true, 'validation', null),
|
|
106
|
-
'display_name', jsonb_build_object('data_type', 'text', 'label', 'Display Name', 'required', true, 'system', true, 'validation', null),
|
|
107
|
-
'description', jsonb_build_object('data_type', 'textarea', 'label', 'Description', 'required', false, 'system', true, 'validation', null),
|
|
108
|
-
'is_active', jsonb_build_object('data_type', 'boolean', 'label', 'Active', 'required', true, 'system', true, 'validation', null),
|
|
109
|
-
'created_at', jsonb_build_object('data_type', 'datetime', 'label', 'Created', 'required', false, 'system', true, 'readonly', true, 'validation', null),
|
|
110
|
-
'updated_at', jsonb_build_object('data_type', 'datetime', 'label', 'Updated', 'required', false, 'system', true, 'readonly', true, 'validation', null)
|
|
111
|
-
),
|
|
112
|
-
'views', jsonb_build_object(
|
|
113
|
-
'default_list', jsonb_build_object('type', 'list', 'display', 'table', 'label', 'Accounts',
|
|
114
|
-
'fields', jsonb_build_object(
|
|
115
|
-
'display_name', jsonb_build_object('sortable', true, 'display_type', 'text'),
|
|
116
|
-
'slug', jsonb_build_object('sortable', true, 'display_type', 'text'),
|
|
117
|
-
'is_active', jsonb_build_object('sortable', true, 'display_type', 'badge')
|
|
118
|
-
)
|
|
119
|
-
),
|
|
120
|
-
'default_detail', jsonb_build_object('type', 'detail', 'label', 'Account',
|
|
121
|
-
'sections', jsonb_build_array(
|
|
122
|
-
jsonb_build_object('title', 'Overview', 'fields', jsonb_build_array('slug', 'display_name', 'description', 'is_active')),
|
|
123
|
-
jsonb_build_object('title', 'Metadata', 'fields', jsonb_build_array('created_at', 'updated_at'))
|
|
124
|
-
)
|
|
125
|
-
)
|
|
126
|
-
)
|
|
127
|
-
),
|
|
128
|
-
'{}'::jsonb,
|
|
129
|
-
'pack',
|
|
130
|
-
true
|
|
131
|
-
)
|
|
132
|
-
|
|
133
|
-
ON CONFLICT (app_id, kind, slug) DO NOTHING;
|
|
134
|
-
|
|
135
|
-
-- 2. MASTER SYSTEM ACCOUNT (inserted here to satisfy FK on type_id)
|
|
136
|
-
INSERT INTO public.accounts (id, slug, display_name, description, data, is_active, design_schema, validation_schema, type_id)
|
|
137
|
-
SELECT
|
|
138
|
-
gen_random_uuid(),
|
|
139
|
-
'spine-system',
|
|
140
|
-
'Spine System',
|
|
141
|
-
'Master system account for internal Spine operations',
|
|
142
|
-
'{}'::jsonb,
|
|
143
|
-
true,
|
|
144
|
-
design_schema,
|
|
145
|
-
validation_schema,
|
|
146
|
-
id
|
|
147
|
-
FROM public.types WHERE slug = 'account' LIMIT 1
|
|
148
|
-
ON CONFLICT (slug) DO NOTHING;
|
|
19
|
+
INSERT INTO public.roles (id, slug, name, description, permissions, is_system, is_active, is_protected, app_id, account_id)
|
|
20
|
+
VALUES
|
|
21
|
+
(gen_random_uuid(), 'engineering', 'Engineering', 'Engineering — work tracking, delivery, quality, and code intelligence', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
22
|
+
(gen_random_uuid(), 'engineering_admin', 'Engineering Admin', 'Engineering administrator with invitation and configuration privileges', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
23
|
+
(gen_random_uuid(), 'product', 'Product', 'Product — discovery, prioritization, and roadmap ownership', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
24
|
+
(gen_random_uuid(), 'docs', 'Docs', 'Docs — documentation and knowledge-base authoring', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
25
|
+
(gen_random_uuid(), 'qa', 'QA', 'QA — test plans, test runs, and quality gates', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
26
|
+
(gen_random_uuid(), 'devops', 'DevOps', 'DevOps — delivery, observability, and incident response', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
27
|
+
(gen_random_uuid(), 'management', 'Management', 'Management — cross-team oversight and operational control', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
28
|
+
(gen_random_uuid(), 'sales', 'Sales', 'Sales — opportunities, deals, and customer communications', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
29
|
+
(gen_random_uuid(), 'csm', 'Customer Success Manager', 'CSM — account health, support, and customer success', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
30
|
+
(gen_random_uuid(), 'tam', 'Technical Account Manager', 'TAM — technical account health and technical signals', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
31
|
+
(gen_random_uuid(), 'support', 'Support', 'Support — tickets, community moderation, and knowledge base', '["*"]'::jsonb, true, true, false, NULL, NULL),
|
|
32
|
+
(gen_random_uuid(), 'support_admin', 'Support Admin', 'Support administrator — can invite and manage support staff', '["*"]'::jsonb, true, true, false, NULL, NULL)
|
|
33
|
+
ON CONFLICT (slug) DO NOTHING;
|
|
149
34
|
|
|
150
|
-
|
|
151
|
-
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
35
|
+
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
152
36
|
VALUES (
|
|
153
37
|
gen_random_uuid(),
|
|
154
38
|
v_spine_core_app_id,
|
|
@@ -194,8 +78,7 @@ BEGIN
|
|
|
194
78
|
|
|
195
79
|
ON CONFLICT (app_id, kind, slug) DO NOTHING;
|
|
196
80
|
|
|
197
|
-
|
|
198
|
-
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
81
|
+
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
199
82
|
VALUES (
|
|
200
83
|
gen_random_uuid(),
|
|
201
84
|
v_spine_core_app_id,
|
|
@@ -238,8 +121,7 @@ BEGIN
|
|
|
238
121
|
|
|
239
122
|
ON CONFLICT (app_id, kind, slug) DO NOTHING;
|
|
240
123
|
|
|
241
|
-
|
|
242
|
-
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
124
|
+
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
243
125
|
VALUES (
|
|
244
126
|
gen_random_uuid(),
|
|
245
127
|
v_spine_core_app_id,
|
|
@@ -290,8 +172,7 @@ BEGIN
|
|
|
290
172
|
|
|
291
173
|
ON CONFLICT (app_id, kind, slug) DO NOTHING;
|
|
292
174
|
|
|
293
|
-
|
|
294
|
-
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
175
|
+
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
295
176
|
VALUES (
|
|
296
177
|
gen_random_uuid(),
|
|
297
178
|
v_spine_core_app_id,
|
|
@@ -341,8 +222,7 @@ BEGIN
|
|
|
341
222
|
|
|
342
223
|
ON CONFLICT (app_id, kind, slug) DO NOTHING;
|
|
343
224
|
|
|
344
|
-
|
|
345
|
-
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
225
|
+
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
346
226
|
VALUES (
|
|
347
227
|
gen_random_uuid(),
|
|
348
228
|
v_spine_core_app_id,
|
|
@@ -386,8 +266,7 @@ BEGIN
|
|
|
386
266
|
|
|
387
267
|
ON CONFLICT (app_id, kind, slug) DO NOTHING;
|
|
388
268
|
|
|
389
|
-
|
|
390
|
-
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
269
|
+
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
391
270
|
VALUES (
|
|
392
271
|
gen_random_uuid(),
|
|
393
272
|
v_spine_core_app_id,
|
|
@@ -432,8 +311,7 @@ BEGIN
|
|
|
432
311
|
|
|
433
312
|
ON CONFLICT (app_id, kind, slug) DO NOTHING;
|
|
434
313
|
|
|
435
|
-
|
|
436
|
-
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
314
|
+
INSERT INTO public.types (id, app_id, kind, slug, name, description, design_schema, validation_schema, ownership, is_active)
|
|
437
315
|
VALUES (
|
|
438
316
|
gen_random_uuid(),
|
|
439
317
|
v_spine_core_app_id,
|
|
@@ -478,17 +356,12 @@ BEGIN
|
|
|
478
356
|
|
|
479
357
|
ON CONFLICT (app_id, kind, slug) DO NOTHING;
|
|
480
358
|
|
|
481
|
-
|
|
482
|
-
UPDATE public.accounts
|
|
359
|
+
UPDATE public.accounts
|
|
483
360
|
SET type_id = (SELECT id FROM public.types WHERE slug = 'account' AND app_id = v_spine_core_app_id LIMIT 1)
|
|
484
361
|
WHERE slug = 'spine-system';
|
|
485
362
|
|
|
486
363
|
END $$;
|
|
487
364
|
|
|
488
|
-
-- ============================================
|
|
489
|
-
-- 6. RPC FUNCTION: get_account_apps
|
|
490
|
-
-- ============================================
|
|
491
|
-
|
|
492
365
|
CREATE OR REPLACE FUNCTION public.get_account_apps(
|
|
493
366
|
account_id uuid,
|
|
494
367
|
include_system boolean DEFAULT true,
|
|
@@ -547,4 +420,4 @@ BEGIN
|
|
|
547
420
|
a.app_type,
|
|
548
421
|
a.name;
|
|
549
422
|
END;
|
|
550
|
-
$function$;
|
|
423
|
+
$function$;
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
-- Spine v2 consolidated RPCs and integration broker
|
|
2
|
+
-- Vector search RPC, integration broker schema, and broker RLS/policies.
|
|
3
|
+
|
|
4
|
+
DO $$
|
|
5
|
+
BEGIN
|
|
6
|
+
IF NOT EXISTS (
|
|
7
|
+
SELECT 1 FROM pg_indexes
|
|
8
|
+
WHERE schemaname = 'public'
|
|
9
|
+
AND tablename = 'embeddings'
|
|
10
|
+
AND indexname = 'embeddings_embedding_hnsw_idx'
|
|
11
|
+
) THEN
|
|
12
|
+
EXECUTE 'CREATE INDEX embeddings_embedding_hnsw_idx
|
|
13
|
+
ON public.embeddings
|
|
14
|
+
USING hnsw (embedding vector_cosine_ops)
|
|
15
|
+
WITH (m = 16, ef_construction = 64)';
|
|
16
|
+
END IF;
|
|
17
|
+
END
|
|
18
|
+
$$;
|
|
19
|
+
|
|
20
|
+
CREATE OR REPLACE FUNCTION public.match_embeddings(
|
|
21
|
+
query_embedding vector(1536),
|
|
22
|
+
match_count int DEFAULT 10,
|
|
23
|
+
filter_account_ids uuid[] DEFAULT NULL,
|
|
24
|
+
filter_vector_type text DEFAULT NULL,
|
|
25
|
+
similarity_threshold float DEFAULT 0.15
|
|
26
|
+
)
|
|
27
|
+
RETURNS TABLE (
|
|
28
|
+
id uuid,
|
|
29
|
+
document_id text,
|
|
30
|
+
content text,
|
|
31
|
+
metadata jsonb,
|
|
32
|
+
account_id uuid,
|
|
33
|
+
similarity float
|
|
34
|
+
)
|
|
35
|
+
LANGUAGE plpgsql
|
|
36
|
+
SECURITY DEFINER
|
|
37
|
+
SET search_path = public
|
|
38
|
+
AS $$
|
|
39
|
+
BEGIN
|
|
40
|
+
RETURN QUERY
|
|
41
|
+
SELECT
|
|
42
|
+
e.id,
|
|
43
|
+
e.document_id,
|
|
44
|
+
e.content,
|
|
45
|
+
e.metadata,
|
|
46
|
+
e.account_id,
|
|
47
|
+
1 - (e.embedding <=> query_embedding) AS similarity
|
|
48
|
+
FROM public.embeddings e
|
|
49
|
+
WHERE
|
|
50
|
+
(filter_account_ids IS NULL OR e.account_id = ANY(filter_account_ids))
|
|
51
|
+
AND (filter_vector_type IS NULL OR e.metadata->>'vector_type' = filter_vector_type)
|
|
52
|
+
AND (1 - (e.embedding <=> query_embedding)) >= similarity_threshold
|
|
53
|
+
ORDER BY e.embedding <=> query_embedding
|
|
54
|
+
LIMIT match_count;
|
|
55
|
+
END
|
|
56
|
+
$$;
|
|
57
|
+
|
|
58
|
+
GRANT EXECUTE ON FUNCTION public.match_embeddings(vector, int, uuid[], text, float) TO authenticated;
|
|
59
|
+
GRANT EXECUTE ON FUNCTION public.match_embeddings(vector, int, uuid[], text, float) TO service_role;
|
|
60
|
+
|
|
61
|
+
CREATE OR REPLACE FUNCTION public.search_similar_embeddings(
|
|
62
|
+
p_account_id uuid,
|
|
63
|
+
p_model_id text,
|
|
64
|
+
p_query_embedding vector(1536),
|
|
65
|
+
p_limit int DEFAULT 10,
|
|
66
|
+
p_threshold float DEFAULT 0.7
|
|
67
|
+
)
|
|
68
|
+
RETURNS TABLE (
|
|
69
|
+
id uuid,
|
|
70
|
+
document_id text,
|
|
71
|
+
content text,
|
|
72
|
+
metadata jsonb,
|
|
73
|
+
similarity float
|
|
74
|
+
)
|
|
75
|
+
LANGUAGE plpgsql
|
|
76
|
+
SECURITY DEFINER
|
|
77
|
+
SET search_path = public
|
|
78
|
+
AS $$
|
|
79
|
+
BEGIN
|
|
80
|
+
RETURN QUERY
|
|
81
|
+
SELECT
|
|
82
|
+
e.id,
|
|
83
|
+
e.document_id,
|
|
84
|
+
e.content,
|
|
85
|
+
e.metadata,
|
|
86
|
+
1 - (e.embedding <=> p_query_embedding) AS similarity
|
|
87
|
+
FROM public.embeddings e
|
|
88
|
+
WHERE
|
|
89
|
+
e.account_id = p_account_id
|
|
90
|
+
AND e.model_id = p_model_id
|
|
91
|
+
AND e.approved_at IS NOT NULL
|
|
92
|
+
AND e.revoked_at IS NULL
|
|
93
|
+
AND (1 - (e.embedding <=> p_query_embedding)) >= p_threshold
|
|
94
|
+
ORDER BY e.embedding <=> p_query_embedding
|
|
95
|
+
LIMIT p_limit;
|
|
96
|
+
END
|
|
97
|
+
$$;
|
|
98
|
+
|
|
99
|
+
GRANT EXECUTE ON FUNCTION public.search_similar_embeddings(uuid, text, vector, int, float) TO authenticated;
|
|
100
|
+
GRANT EXECUTE ON FUNCTION public.search_similar_embeddings(uuid, text, vector, int, float) TO service_role;
|
|
101
|
+
|
|
102
|
+
-- ============================================
|
|
103
|
+
-- INTEGRATIONS: restore/augment columns
|
|
104
|
+
-- ============================================
|
|
105
|
+
|
|
106
|
+
ALTER TABLE public.integrations
|
|
107
|
+
ADD COLUMN IF NOT EXISTS slug text,
|
|
108
|
+
ADD COLUMN IF NOT EXISTS integration_type text NOT NULL DEFAULT 'webhook',
|
|
109
|
+
ADD COLUMN IF NOT EXISTS provider text,
|
|
110
|
+
ADD COLUMN IF NOT EXISTS version text,
|
|
111
|
+
ADD COLUMN IF NOT EXISTS credentials jsonb DEFAULT '{}',
|
|
112
|
+
ADD COLUMN IF NOT EXISTS is_configured boolean DEFAULT false,
|
|
113
|
+
ADD COLUMN IF NOT EXISTS created_by uuid,
|
|
114
|
+
ADD COLUMN IF NOT EXISTS ownership text DEFAULT 'tenant';
|
|
115
|
+
|
|
116
|
+
COMMENT ON COLUMN public.integrations.integration_type IS 'Semantic category: webhook, oauth, api, scheduled_sync';
|
|
117
|
+
COMMENT ON COLUMN public.integrations.provider IS 'Provider name: stripe, kibo, make, openai, etc.';
|
|
118
|
+
COMMENT ON COLUMN public.integrations.credentials IS 'Secrets map with source/value pairs: { field: { source: value|env_var, value: string } }';
|
|
119
|
+
COMMENT ON COLUMN public.integrations.is_configured IS 'True when required credentials are present';
|
|
120
|
+
|
|
121
|
+
-- Replace the old unique key with one that scopes by account
|
|
122
|
+
ALTER TABLE public.integrations DROP CONSTRAINT IF EXISTS integrations_app_id_slug_key;
|
|
123
|
+
ALTER TABLE public.integrations ADD CONSTRAINT integrations_app_account_slug_key UNIQUE (app_id, account_id, slug);
|
|
124
|
+
|
|
125
|
+
ALTER TABLE public.integrations ADD CONSTRAINT fk_integrations_created_by
|
|
126
|
+
FOREIGN KEY (created_by) REFERENCES public.people(id) ON DELETE SET NULL;
|
|
127
|
+
|
|
128
|
+
-- ============================================
|
|
129
|
+
-- API KEYS: restore/augment columns
|
|
130
|
+
-- ============================================
|
|
131
|
+
|
|
132
|
+
ALTER TABLE public.api_keys
|
|
133
|
+
ADD COLUMN IF NOT EXISTS app_id uuid,
|
|
134
|
+
ADD COLUMN IF NOT EXISTS slug text,
|
|
135
|
+
ADD COLUMN IF NOT EXISTS integration_id uuid,
|
|
136
|
+
ADD COLUMN IF NOT EXISTS key_prefix text,
|
|
137
|
+
ADD COLUMN IF NOT EXISTS key_hash text,
|
|
138
|
+
ADD COLUMN IF NOT EXISTS key_type text NOT NULL DEFAULT 'inbound',
|
|
139
|
+
ADD COLUMN IF NOT EXISTS permissions jsonb DEFAULT '[]',
|
|
140
|
+
ADD COLUMN IF NOT EXISTS scopes text[] DEFAULT '{}',
|
|
141
|
+
ADD COLUMN IF NOT EXISTS rate_limit integer DEFAULT 100,
|
|
142
|
+
ADD COLUMN IF NOT EXISTS expires_at timestamptz,
|
|
143
|
+
ADD COLUMN IF NOT EXISTS is_internal boolean DEFAULT false,
|
|
144
|
+
ADD COLUMN IF NOT EXISTS machine_type text,
|
|
145
|
+
ADD COLUMN IF NOT EXISTS created_by uuid,
|
|
146
|
+
ADD COLUMN IF NOT EXISTS ownership text DEFAULT 'tenant';
|
|
147
|
+
|
|
148
|
+
COMMENT ON COLUMN public.api_keys.integration_id IS 'The integration this key is bound to';
|
|
149
|
+
COMMENT ON COLUMN public.api_keys.key_prefix IS 'Plaintext first N chars used for key lookup and UI';
|
|
150
|
+
COMMENT ON COLUMN public.api_keys.key_hash IS 'Salted slow hash of the full key';
|
|
151
|
+
COMMENT ON COLUMN public.api_keys.key_type IS 'inbound, outbound, internal, cli';
|
|
152
|
+
COMMENT ON COLUMN public.api_keys.rate_limit IS 'Requests per rate_limit_window_seconds';
|
|
153
|
+
|
|
154
|
+
ALTER TABLE public.api_keys ADD CONSTRAINT fk_api_keys_integration
|
|
155
|
+
FOREIGN KEY (integration_id) REFERENCES public.integrations(id) ON DELETE CASCADE;
|
|
156
|
+
ALTER TABLE public.api_keys ADD CONSTRAINT fk_api_keys_created_by
|
|
157
|
+
FOREIGN KEY (created_by) REFERENCES public.people(id) ON DELETE SET NULL;
|
|
158
|
+
|
|
159
|
+
-- Unique key for key_hash (multiple NULLs allowed)
|
|
160
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_api_keys_key_hash ON public.api_keys(key_hash) WHERE key_hash IS NOT NULL;
|
|
161
|
+
|
|
162
|
+
-- Scope api_keys slug by account as well
|
|
163
|
+
ALTER TABLE public.api_keys DROP CONSTRAINT IF EXISTS api_keys_app_id_slug_key;
|
|
164
|
+
ALTER TABLE public.api_keys ADD CONSTRAINT api_keys_app_account_slug_key UNIQUE (app_id, account_id, slug);
|
|
165
|
+
|
|
166
|
+
-- ============================================
|
|
167
|
+
-- API KEY USAGE LOGS
|
|
168
|
+
-- ============================================
|
|
169
|
+
|
|
170
|
+
CREATE TABLE IF NOT EXISTS public.api_key_usage_logs (
|
|
171
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
172
|
+
api_key_id uuid NOT NULL,
|
|
173
|
+
account_id uuid,
|
|
174
|
+
request_method text,
|
|
175
|
+
request_path text,
|
|
176
|
+
request_ip text,
|
|
177
|
+
user_agent text,
|
|
178
|
+
response_status integer,
|
|
179
|
+
response_size integer,
|
|
180
|
+
duration_ms integer,
|
|
181
|
+
success boolean DEFAULT true,
|
|
182
|
+
error_message text,
|
|
183
|
+
metadata jsonb DEFAULT '{}',
|
|
184
|
+
created_at timestamptz DEFAULT now()
|
|
185
|
+
);
|
|
186
|
+
|
|
187
|
+
CREATE INDEX IF NOT EXISTS idx_api_key_usage_logs_api_key_id ON public.api_key_usage_logs(api_key_id);
|
|
188
|
+
CREATE INDEX IF NOT EXISTS idx_api_key_usage_logs_created_at ON public.api_key_usage_logs(created_at);
|
|
189
|
+
|
|
190
|
+
ALTER TABLE public.api_key_usage_logs ADD CONSTRAINT fk_akul_api_key
|
|
191
|
+
FOREIGN KEY (api_key_id) REFERENCES public.api_keys(id) ON DELETE CASCADE;
|
|
192
|
+
ALTER TABLE public.api_key_usage_logs ADD CONSTRAINT fk_akul_account
|
|
193
|
+
FOREIGN KEY (account_id) REFERENCES public.accounts(id) ON DELETE SET NULL;
|
|
194
|
+
|
|
195
|
+
-- ============================================
|
|
196
|
+
-- WEBHOOK HANDLERS
|
|
197
|
+
-- ============================================
|
|
198
|
+
|
|
199
|
+
CREATE TABLE IF NOT EXISTS public.webhook_handlers (
|
|
200
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
201
|
+
app_id uuid,
|
|
202
|
+
account_id uuid,
|
|
203
|
+
name text NOT NULL,
|
|
204
|
+
function_name text NOT NULL,
|
|
205
|
+
description text,
|
|
206
|
+
events text[] DEFAULT '{}',
|
|
207
|
+
is_active boolean DEFAULT true,
|
|
208
|
+
is_deleted boolean DEFAULT false,
|
|
209
|
+
deleted_at timestamptz,
|
|
210
|
+
created_at timestamptz DEFAULT now(),
|
|
211
|
+
updated_at timestamptz DEFAULT now(),
|
|
212
|
+
UNIQUE (app_id, account_id, name)
|
|
213
|
+
);
|
|
214
|
+
|
|
215
|
+
CREATE INDEX IF NOT EXISTS idx_webhook_handlers_name ON public.webhook_handlers(name) WHERE is_active = true AND is_deleted = false;
|
|
216
|
+
CREATE INDEX IF NOT EXISTS idx_webhook_handlers_account ON public.webhook_handlers(account_id) WHERE is_deleted = false;
|
|
217
|
+
CREATE INDEX IF NOT EXISTS idx_webhook_handlers_events ON public.webhook_handlers USING GIN(events) WHERE is_active = true;
|
|
218
|
+
|
|
219
|
+
ALTER TABLE public.webhook_handlers ADD CONSTRAINT fk_webhook_handlers_app
|
|
220
|
+
FOREIGN KEY (app_id) REFERENCES public.apps(id) ON DELETE SET NULL;
|
|
221
|
+
ALTER TABLE public.webhook_handlers ADD CONSTRAINT fk_webhook_handlers_account
|
|
222
|
+
FOREIGN KEY (account_id) REFERENCES public.accounts(id) ON DELETE CASCADE;
|
|
223
|
+
|
|
224
|
+
COMMENT ON TABLE public.webhook_handlers IS 'Dynamic registry for webhook handlers. Custom functions self-register here to be discoverable by the integration-routes handler without static imports.';
|
|
225
|
+
|
|
226
|
+
-- ============================================
|
|
227
|
+
-- WEBHOOK DELIVERIES (inbound + outbound ledger)
|
|
228
|
+
-- ============================================
|
|
229
|
+
|
|
230
|
+
CREATE TABLE IF NOT EXISTS public.webhook_deliveries (
|
|
231
|
+
id uuid PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
232
|
+
app_id uuid,
|
|
233
|
+
account_id uuid,
|
|
234
|
+
direction text NOT NULL CHECK (direction IN ('inbound', 'outbound')),
|
|
235
|
+
integration_id uuid,
|
|
236
|
+
api_key_id uuid,
|
|
237
|
+
handler_name text,
|
|
238
|
+
action_slug text,
|
|
239
|
+
record_id uuid,
|
|
240
|
+
external_id text,
|
|
241
|
+
payload jsonb DEFAULT '{}',
|
|
242
|
+
status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'processing', 'delivered', 'failed', 'cancelled')),
|
|
243
|
+
attempt_count integer DEFAULT 0,
|
|
244
|
+
max_attempts integer DEFAULT 3,
|
|
245
|
+
next_attempt_at timestamptz,
|
|
246
|
+
last_error text,
|
|
247
|
+
response_status integer,
|
|
248
|
+
response_body jsonb,
|
|
249
|
+
duration_ms integer,
|
|
250
|
+
created_at timestamptz DEFAULT now(),
|
|
251
|
+
updated_at timestamptz DEFAULT now()
|
|
252
|
+
);
|
|
253
|
+
|
|
254
|
+
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_status_next_attempt ON public.webhook_deliveries(status, next_attempt_at);
|
|
255
|
+
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_integration_external ON public.webhook_deliveries(integration_id, external_id);
|
|
256
|
+
CREATE INDEX IF NOT EXISTS idx_webhook_deliveries_account_created ON public.webhook_deliveries(account_id, created_at);
|
|
257
|
+
|
|
258
|
+
ALTER TABLE public.webhook_deliveries ADD CONSTRAINT fk_webhook_deliveries_integration
|
|
259
|
+
FOREIGN KEY (integration_id) REFERENCES public.integrations(id) ON DELETE SET NULL;
|
|
260
|
+
ALTER TABLE public.webhook_deliveries ADD CONSTRAINT fk_webhook_deliveries_api_key
|
|
261
|
+
FOREIGN KEY (api_key_id) REFERENCES public.api_keys(id) ON DELETE SET NULL;
|
|
262
|
+
|
|
263
|
+
COMMENT ON TABLE public.webhook_deliveries IS 'Shared delivery/retry ledger for inbound and outbound integration calls.';
|
|
264
|
+
|
|
265
|
+
-- ============================================
|
|
266
|
+
-- DROP UNUSED integration_routes
|
|
267
|
+
-- ============================================
|
|
268
|
+
|
|
269
|
+
DROP TABLE IF EXISTS public.integration_routes CASCADE;
|
|
270
|
+
|
|
271
|
+
-- ============================================
|
|
272
|
+
-- RLS
|
|
273
|
+
-- ============================================
|
|
274
|
+
|
|
275
|
+
ALTER TABLE public.integrations ENABLE ROW LEVEL SECURITY;
|
|
276
|
+
ALTER TABLE public.api_keys ENABLE ROW LEVEL SECURITY;
|
|
277
|
+
ALTER TABLE public.api_key_usage_logs ENABLE ROW LEVEL SECURITY;
|
|
278
|
+
ALTER TABLE public.webhook_handlers ENABLE ROW LEVEL SECURITY;
|
|
279
|
+
ALTER TABLE public.webhook_deliveries ENABLE ROW LEVEL SECURITY;
|
|
280
|
+
|
|
281
|
+
DROP POLICY IF EXISTS integrations_access ON public.integrations;
|
|
282
|
+
CREATE POLICY integrations_access ON public.integrations FOR ALL
|
|
283
|
+
USING (account_id IN (SELECT public.get_accessible_accounts(auth.uid()))
|
|
284
|
+
OR auth.uid() IS NULL);
|
|
285
|
+
|
|
286
|
+
DROP POLICY IF EXISTS api_keys_access ON public.api_keys;
|
|
287
|
+
CREATE POLICY api_keys_access ON public.api_keys FOR ALL
|
|
288
|
+
USING (account_id IN (SELECT public.get_accessible_accounts(auth.uid()))
|
|
289
|
+
OR auth.uid() IS NULL);
|
|
290
|
+
|
|
291
|
+
DROP POLICY IF EXISTS akul_access ON public.api_key_usage_logs;
|
|
292
|
+
CREATE POLICY akul_access ON public.api_key_usage_logs FOR ALL
|
|
293
|
+
USING (account_id IN (SELECT public.get_accessible_accounts(auth.uid()))
|
|
294
|
+
OR auth.uid() IS NULL);
|
|
295
|
+
|
|
296
|
+
DROP POLICY IF EXISTS webhook_handlers_access ON public.webhook_handlers;
|
|
297
|
+
CREATE POLICY webhook_handlers_access ON public.webhook_handlers FOR ALL
|
|
298
|
+
USING (account_id IN (SELECT public.get_accessible_accounts(auth.uid()))
|
|
299
|
+
OR auth.uid() IS NULL);
|
|
300
|
+
|
|
301
|
+
DROP POLICY IF EXISTS webhook_deliveries_access ON public.webhook_deliveries;
|
|
302
|
+
CREATE POLICY webhook_deliveries_access ON public.webhook_deliveries FOR ALL
|
|
303
|
+
USING (account_id IN (SELECT public.get_accessible_accounts(auth.uid()))
|
|
304
|
+
OR auth.uid() IS NULL);
|
|
305
|
+
|
|
306
|
+
-- Service role bypass for all broker tables
|
|
307
|
+
DROP POLICY IF EXISTS integrations_service_role ON public.integrations;
|
|
308
|
+
CREATE POLICY integrations_service_role ON public.integrations FOR ALL TO service_role USING (true) WITH CHECK (true);
|
|
309
|
+
|
|
310
|
+
DROP POLICY IF EXISTS api_keys_service_role ON public.api_keys;
|
|
311
|
+
CREATE POLICY api_keys_service_role ON public.api_keys FOR ALL TO service_role USING (true) WITH CHECK (true);
|
|
312
|
+
|
|
313
|
+
DROP POLICY IF EXISTS akul_service_role ON public.api_key_usage_logs;
|
|
314
|
+
CREATE POLICY akul_service_role ON public.api_key_usage_logs FOR ALL TO service_role USING (true) WITH CHECK (true);
|
|
315
|
+
|
|
316
|
+
DROP POLICY IF EXISTS webhook_handlers_service_role ON public.webhook_handlers;
|
|
317
|
+
CREATE POLICY webhook_handlers_service_role ON public.webhook_handlers FOR ALL TO service_role USING (true) WITH CHECK (true);
|
|
318
|
+
|
|
319
|
+
DROP POLICY IF EXISTS webhook_deliveries_service_role ON public.webhook_deliveries;
|
|
320
|
+
CREATE POLICY webhook_deliveries_service_role ON public.webhook_deliveries FOR ALL TO service_role USING (true) WITH CHECK (true);
|
|
321
|
+
|
|
322
|
+
-- ============================================
|
|
323
|
+
-- updated_at triggers
|
|
324
|
+
-- ============================================
|
|
325
|
+
|
|
326
|
+
CREATE OR REPLACE FUNCTION public.set_updated_at()
|
|
327
|
+
RETURNS TRIGGER AS $$
|
|
328
|
+
BEGIN
|
|
329
|
+
NEW.updated_at = now();
|
|
330
|
+
RETURN NEW;
|
|
331
|
+
END;
|
|
332
|
+
$$ LANGUAGE plpgsql;
|
|
333
|
+
|
|
334
|
+
DROP TRIGGER IF EXISTS set_updated_at_integrations ON public.integrations;
|
|
335
|
+
CREATE TRIGGER set_updated_at_integrations
|
|
336
|
+
BEFORE UPDATE ON public.integrations
|
|
337
|
+
FOR EACH ROW EXECUTE FUNCTION public.set_updated_at();
|
|
338
|
+
|
|
339
|
+
DROP TRIGGER IF EXISTS set_updated_at_api_keys ON public.api_keys;
|
|
340
|
+
CREATE TRIGGER set_updated_at_api_keys
|
|
341
|
+
BEFORE UPDATE ON public.api_keys
|
|
342
|
+
FOR EACH ROW EXECUTE FUNCTION public.set_updated_at();
|
|
343
|
+
|
|
344
|
+
DROP TRIGGER IF EXISTS set_updated_at_webhook_handlers ON public.webhook_handlers;
|
|
345
|
+
CREATE TRIGGER set_updated_at_webhook_handlers
|
|
346
|
+
BEFORE UPDATE ON public.webhook_handlers
|
|
347
|
+
FOR EACH ROW EXECUTE FUNCTION public.set_updated_at();
|
|
348
|
+
|
|
349
|
+
DROP TRIGGER IF EXISTS set_updated_at_webhook_deliveries ON public.webhook_deliveries;
|
|
350
|
+
CREATE TRIGGER set_updated_at_webhook_deliveries
|
|
351
|
+
BEFORE UPDATE ON public.webhook_deliveries
|
|
352
|
+
FOR EACH ROW EXECUTE FUNCTION public.set_updated_at();
|
|
353
|
+
|
|
354
|
+
-- ============================================
|
|
355
|
+
-- SEED: webhook_event type, openai integration, generic handler
|
|
356
|
+
-- ============================================
|
|
357
|
+
|
|
358
|
+
INSERT INTO public.types (
|
|
359
|
+
app_id, kind, slug, name, description, icon, color,
|
|
360
|
+
design_schema, validation_schema, ownership, is_active
|
|
361
|
+
)
|
|
362
|
+
VALUES (
|
|
363
|
+
NULL,
|
|
364
|
+
'item',
|
|
365
|
+
'webhook_event',
|
|
366
|
+
'Webhook Event',
|
|
367
|
+
'Raw or normalized inbound webhook payload captured by the generic adapter for debugging.',
|
|
368
|
+
'radio-receiver',
|
|
369
|
+
'#6366F1',
|
|
370
|
+
'{"scope":"account","fields":{"provider":{"data_type":"text","label":"Provider","required":false,"system":false},"event":{"data_type":"text","label":"Event","required":false,"system":false},"payload":{"data_type":"json","label":"Payload","required":true,"system":false},"headers":{"data_type":"json","label":"Headers","required":false,"system":false}},"views":{"default_list":{"type":"list","display":"table","label":"Webhook Events","fields":{"provider":{"display_type":"text"},"event":{"display_type":"text"},"created_at":{"display_type":"timestamp"}},"default_sort":{"field":"created_at","direction":"desc"}},"default_detail":{"type":"detail","label":"Webhook Event","sections":[{"title":"Payload","fields":{"provider":{"display_type":"input"},"event":{"display_type":"input"},"payload":{"display_type":"textarea"},"headers":{"display_type":"textarea"}}}]},"record_permissions":{"system-admin":["create","read","update","delete"]},"functionality":null}',
|
|
371
|
+
'{}',
|
|
372
|
+
'system',
|
|
373
|
+
true
|
|
374
|
+
)
|
|
375
|
+
ON CONFLICT (app_id, kind, slug) DO NOTHING;
|
|
376
|
+
|
|
377
|
+
INSERT INTO public.integrations (
|
|
378
|
+
app_id, account_id, slug, name, description,
|
|
379
|
+
integration_type, provider, version, config, credentials,
|
|
380
|
+
is_active, is_system, is_configured, ownership
|
|
381
|
+
)
|
|
382
|
+
VALUES (
|
|
383
|
+
NULL, NULL, 'openai', 'OpenAI', 'System OpenAI integration for AI agent and embedding calls.', 'api', 'openai', 'v1',
|
|
384
|
+
'{"base_url":"https://api.openai.com/v1","outbound_adapter":"adapters/openai-outbound","models":{"chat":"gpt-4o-mini","embedding":"text-embedding-3-small"}}',
|
|
385
|
+
'{"api_token":{"source":"env_var","value":"OPENAI_API_KEY"}}',
|
|
386
|
+
true, true, true, 'system'
|
|
387
|
+
)
|
|
388
|
+
ON CONFLICT (app_id, account_id, slug) DO NOTHING;
|
|
389
|
+
|
|
390
|
+
INSERT INTO public.webhook_handlers (
|
|
391
|
+
app_id, account_id, name, function_name, description, events, is_active
|
|
392
|
+
)
|
|
393
|
+
VALUES (
|
|
394
|
+
NULL, NULL, 'generic-webhook', 'adapters/generic-webhook-inbound',
|
|
395
|
+
'Generic pass-through adapter that stores the raw webhook payload as a webhook_event item.',
|
|
396
|
+
'{}', true
|
|
397
|
+
)
|
|
398
|
+
ON CONFLICT (app_id, account_id, name) DO NOTHING;
|
|
399
|
+
|
|
400
|
+
INSERT INTO public.webhook_handlers (
|
|
401
|
+
app_id, account_id, name, function_name, description, events, is_active
|
|
402
|
+
)
|
|
403
|
+
VALUES (
|
|
404
|
+
NULL, NULL, 'portal-signals', 'custom/apps/portal/functions/custom_portal-signals',
|
|
405
|
+
'Portal funnel signal adapter that transforms portal engagement payloads into funnel_signal records.',
|
|
406
|
+
'{"funnel.signal"}', true
|
|
407
|
+
)
|
|
408
|
+
ON CONFLICT (app_id, account_id, name) DO NOTHING;
|
|
409
|
+
|
|
410
|
+
INSERT INTO public.integrations (
|
|
411
|
+
app_id, account_id, slug, name, description,
|
|
412
|
+
integration_type, provider, version, config, credentials,
|
|
413
|
+
is_active, is_system, is_configured, ownership
|
|
414
|
+
)
|
|
415
|
+
VALUES (
|
|
416
|
+
NULL, NULL, 'generic-http', 'Generic HTTP Webhook', 'System generic outbound webhook for pipeline webhook stages.', 'api', 'generic', 'v1',
|
|
417
|
+
'{"outbound_adapter":"adapters/generic-webhook-outbound"}',
|
|
418
|
+
'{"api_token":{"source":"value","value":""}}',
|
|
419
|
+
true, true, true, 'system'
|
|
420
|
+
)
|
|
421
|
+
ON CONFLICT (app_id, account_id, slug) DO NOTHING;
|