spine-framework 0.3.17 → 0.3.18
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/create-app.ts +1 -1
- package/.framework/cli/commands/dev.ts +215 -33
- package/.framework/cli/index.ts +37 -75
- package/.framework/functions/_shared/app-manifest.ts +8 -15
- package/.framework/functions/_shared/db.ts +11 -15
- package/.framework/functions/_shared/index.ts +7 -16
- package/.framework/functions/_shared/principal.ts +4 -62
- package/.framework/functions/_shared/resolve-ids.ts +6 -6
- package/.framework/functions/_shared/webhook-registry.ts +43 -1
- package/.framework/functions/admin-funnel.ts +104 -0
- package/.framework/functions/admin-install-funnel.ts +225 -0
- package/.framework/functions/admin-signals.ts +241 -0
- package/.framework/functions/integration-routes.ts +4 -8
- package/.framework/migrations/001_schema.sql +406 -0
- package/.framework/migrations/002_rls_and_functions.sql +710 -0
- package/.framework/migrations/003_system_data.sql +520 -0
- package/.framework/migrations/004_enhancements.sql +43 -0
- package/.framework/public/_redirects +3 -0
- package/.framework/public/spine-logo.jpg +0 -0
- package/.framework/public/spine-logo.svg +3 -0
- package/{scripts → .framework/scripts}/assemble-frontend.sh +8 -5
- package/{scripts → .framework/scripts}/assemble-functions.sh +4 -47
- package/{scripts → .framework/scripts}/assemble.sh +2 -8
- package/{scripts → .framework/scripts}/boundary-check.sh +5 -9
- package/{scripts → .framework/scripts}/check-core-integrity.sh +0 -0
- package/.framework/seeds/link_types/account_cli_instances.json +9 -0
- package/.framework/seeds/types/funnel_signal_use.json +98 -0
- package/.framework/seeds/types/spine_instance.json +109 -0
- package/.framework/src/App.tsx +11 -21
- package/.framework/src/components/CustomAppLoader.tsx +2 -19
- package/.framework/src/components/ui/accordion.tsx +1 -1
- package/.framework/src/components/ui/alert-dialog.tsx +1 -1
- package/.framework/src/components/ui/aspect-ratio.tsx +1 -1
- package/.framework/src/components/ui/avatar.tsx +1 -1
- package/.framework/src/components/ui/badge.tsx +2 -2
- package/.framework/src/components/ui/breadcrumb.tsx +2 -2
- package/.framework/src/components/ui/button-group.tsx +2 -2
- package/.framework/src/components/ui/button.tsx +2 -2
- package/.framework/src/components/ui/chart.tsx +6 -1
- package/.framework/src/components/ui/checkbox.tsx +1 -1
- package/.framework/src/components/ui/collapsible.tsx +1 -1
- package/.framework/src/components/ui/context-menu.tsx +1 -1
- package/.framework/src/components/ui/dialog.tsx +1 -1
- package/.framework/src/components/ui/direction.tsx +17 -1
- package/.framework/src/components/ui/dropdown-menu.tsx +1 -1
- package/.framework/src/components/ui/hover-card.tsx +1 -1
- package/.framework/src/components/ui/item.tsx +2 -2
- package/.framework/src/components/ui/label.tsx +1 -1
- package/.framework/src/components/ui/menubar.tsx +1 -1
- package/.framework/src/components/ui/navigation-menu.tsx +1 -1
- package/.framework/src/components/ui/popover.tsx +1 -1
- package/.framework/src/components/ui/progress.tsx +1 -1
- package/.framework/src/components/ui/radio-group.tsx +1 -1
- package/.framework/src/components/ui/scroll-area.tsx +1 -1
- package/.framework/src/components/ui/select.tsx +1 -1
- package/.framework/src/components/ui/separator.tsx +1 -1
- package/.framework/src/components/ui/sheet.tsx +1 -1
- package/.framework/src/components/ui/sidebar.tsx +6 -6
- package/.framework/src/components/ui/slider.tsx +1 -1
- package/.framework/src/components/ui/switch.tsx +1 -1
- package/.framework/src/components/ui/tabs.tsx +1 -1
- package/.framework/src/components/ui/toggle-group.tsx +1 -1
- package/.framework/src/components/ui/toggle.tsx +1 -1
- package/.framework/src/components/ui/tooltip.tsx +1 -1
- package/.framework/src/pages/auth/LoginPage.tsx +10 -9
- package/LICENSE.md +63 -93
- package/README.md +254 -129
- package/custom/.devin/skills/install-app/SKILL.md +39 -0
- package/custom/.devin/workflows/app-install.yaml +83 -0
- package/custom/README.md +79 -0
- package/docs/APPS.md +232 -0
- package/docs/ARCHITECTURE.md +246 -0
- package/docs/INSTALL.md +155 -0
- package/docs/README.md +170 -0
- package/docs/design-schema-spec.md +1837 -0
- package/docs/dev-guides/01-create-an-app.md +183 -0
- package/docs/dev-guides/02-create-a-function.md +178 -0
- package/docs/dev-guides/03-create-a-component.md +178 -0
- package/docs/dev-guides/04-webhook-handlers.md +129 -0
- package/docs/dev-guides/05-testing.md +168 -0
- package/docs/dev-guides/README.md +40 -0
- package/docs/npm-packages-plan.md +288 -0
- package/docs/spine-core--api-reference.md +822 -0
- package/package.json +78 -150
- package/.framework/cli/bin.cjs +0 -14
- package/.framework/cli/commands/claim.ts +0 -430
- package/.framework/cli/commands/init.ts +0 -219
- package/.framework/cli/commands/install-app.ts +0 -685
- package/.framework/cli/commands/migrate.ts +0 -178
- package/.framework/cli/commands/publish.ts +0 -191
- package/.framework/cli/commands/status.ts +0 -268
- package/.framework/cli/commands/uninstall-app.ts +0 -166
- package/.framework/cli/commands/update-app.ts +0 -397
- package/.framework/cli/welcome.cjs +0 -45
- package/.framework/config/signal-client.ts +0 -147
- package/.framework/config/signals.ts +0 -70
- package/.framework/docs/STABILITY.md +0 -52
- package/.framework/docs/examples/custom-app/README.md +0 -77
- package/.framework/docs/examples/custom-function/README.md +0 -27
- package/.framework/docs/examples/custom-function/handler.ts +0 -48
- package/.framework/docs/examples/custom-webhook/README.md +0 -68
- package/.framework/functions/handler-registry.ts +0 -22
- package/.framework/functions/signal.ts +0 -168
- package/.framework/migrations/000_foundation.sql +0 -1302
- package/.framework/migrations/001_seed.sql +0 -163
- package/.framework/migrations/002_seed_constraints.sql +0 -19
- package/.framework/migrations/003_auth_user_trigger.sql +0 -67
- package/.framework/migrations/004_app_version_tracking.sql +0 -8
- package/.framework/migrations/005_pipelines_slug_stages.sql +0 -21
- package/.framework/src/pages/auth/RegisterPage.tsx +0 -163
- package/CHANGELOG.md +0 -71
- package/STRUCTURE.md +0 -150
- package/bin/spine-framework.cjs +0 -62
- package/bin/welcome.cjs +0 -58
- package/bin/ws-shim.ts +0 -10
- package/config/components.json +0 -25
- package/config/deno.lock +0 -108
- package/config/package-lock.json +0 -17183
- package/config/postcss.config.cjs +0 -10
- package/config/tailwind.config.cjs +0 -78
- package/config/tsconfig.build.json +0 -32
- package/config/tsconfig.cli.json +0 -18
- package/config/tsconfig.json +0 -41
- package/config/tsconfig.node.json +0 -17
- package/config/tsconfig.node.tsbuildinfo +0 -1
- package/config/tsconfig.tsbuildinfo +0 -1
- package/config/typedoc.json +0 -16
- package/config/vite.config.d.ts +0 -2
- package/config/vite.config.ts +0 -71
- package/dist/cli/commands/agents.d.ts +0 -39
- package/dist/cli/commands/agents.d.ts.map +0 -1
- package/dist/cli/commands/auth.d.ts +0 -36
- package/dist/cli/commands/auth.d.ts.map +0 -1
- package/dist/cli/commands/claim.d.ts +0 -38
- package/dist/cli/commands/claim.d.ts.map +0 -1
- package/dist/cli/commands/create-app.d.ts +0 -23
- package/dist/cli/commands/create-app.d.ts.map +0 -1
- package/dist/cli/commands/dev.d.ts +0 -24
- package/dist/cli/commands/dev.d.ts.map +0 -1
- package/dist/cli/commands/doctor.d.ts +0 -42
- package/dist/cli/commands/doctor.d.ts.map +0 -1
- package/dist/cli/commands/generate.d.ts +0 -36
- package/dist/cli/commands/generate.d.ts.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -20
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/install-app.d.ts +0 -30
- package/dist/cli/commands/install-app.d.ts.map +0 -1
- package/dist/cli/commands/items.d.ts +0 -45
- package/dist/cli/commands/items.d.ts.map +0 -1
- package/dist/cli/commands/migrate.d.ts +0 -21
- package/dist/cli/commands/migrate.d.ts.map +0 -1
- package/dist/cli/commands/migrations.d.ts +0 -41
- package/dist/cli/commands/migrations.d.ts.map +0 -1
- package/dist/cli/commands/pipelines.d.ts +0 -40
- package/dist/cli/commands/pipelines.d.ts.map +0 -1
- package/dist/cli/commands/publish.d.ts +0 -23
- package/dist/cli/commands/publish.d.ts.map +0 -1
- package/dist/cli/commands/status.d.ts +0 -23
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/system.d.ts +0 -29
- package/dist/cli/commands/system.d.ts.map +0 -1
- package/dist/cli/commands/test.d.ts +0 -46
- package/dist/cli/commands/test.d.ts.map +0 -1
- package/dist/cli/commands/uninstall-app.d.ts +0 -23
- package/dist/cli/commands/uninstall-app.d.ts.map +0 -1
- package/dist/cli/commands/update-app.d.ts +0 -24
- package/dist/cli/commands/update-app.d.ts.map +0 -1
- package/dist/cli/context.d.ts +0 -88
- package/dist/cli/context.d.ts.map +0 -1
- package/dist/cli/env-loader.d.ts +0 -14
- package/dist/cli/env-loader.d.ts.map +0 -1
- package/dist/cli/index.d.ts +0 -44
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/config/signals.d.ts +0 -82
- package/dist/config/signals.d.ts.map +0 -1
- package/dist/functions/_shared/agent-runner.d.ts +0 -156
- package/dist/functions/_shared/agent-runner.d.ts.map +0 -1
- package/dist/functions/_shared/app-manifest.d.ts +0 -68
- package/dist/functions/_shared/app-manifest.d.ts.map +0 -1
- package/dist/functions/_shared/audit.d.ts +0 -91
- package/dist/functions/_shared/audit.d.ts.map +0 -1
- package/dist/functions/_shared/db.d.ts +0 -125
- package/dist/functions/_shared/db.d.ts.map +0 -1
- package/dist/functions/_shared/index.d.ts +0 -299
- package/dist/functions/_shared/index.d.ts.map +0 -1
- package/dist/functions/_shared/middleware.d.ts +0 -315
- package/dist/functions/_shared/middleware.d.ts.map +0 -1
- package/dist/functions/_shared/permissions.d.ts +0 -626
- package/dist/functions/_shared/permissions.d.ts.map +0 -1
- package/dist/functions/_shared/pipeline-runner.d.ts +0 -124
- package/dist/functions/_shared/pipeline-runner.d.ts.map +0 -1
- package/dist/functions/_shared/principal.d.ts +0 -284
- package/dist/functions/_shared/principal.d.ts.map +0 -1
- package/dist/functions/_shared/resolve-ids.d.ts +0 -10
- package/dist/functions/_shared/resolve-ids.d.ts.map +0 -1
- package/dist/functions/_shared/schema-utils.d.ts +0 -181
- package/dist/functions/_shared/schema-utils.d.ts.map +0 -1
- package/dist/functions/_shared/testing.d.ts +0 -172
- package/dist/functions/_shared/testing.d.ts.map +0 -1
- package/dist/functions/_shared/trigger-engine.d.ts +0 -140
- package/dist/functions/_shared/trigger-engine.d.ts.map +0 -1
- package/dist/functions/_shared/webhook-registration.d.ts +0 -81
- package/dist/functions/_shared/webhook-registration.d.ts.map +0 -1
- package/dist/functions/_shared/webhook-registry.d.ts +0 -41
- package/dist/functions/_shared/webhook-registry.d.ts.map +0 -1
- package/dist/functions/account-nodes.d.ts +0 -48
- package/dist/functions/account-nodes.d.ts.map +0 -1
- package/dist/functions/admin-data.d.ts +0 -178
- package/dist/functions/admin-data.d.ts.map +0 -1
- package/dist/functions/ai-agents.d.ts +0 -125
- package/dist/functions/ai-agents.d.ts.map +0 -1
- package/dist/functions/api-keys.d.ts +0 -140
- package/dist/functions/api-keys.d.ts.map +0 -1
- package/dist/functions/apps.d.ts +0 -163
- package/dist/functions/apps.d.ts.map +0 -1
- package/dist/functions/auth.d.ts +0 -74
- package/dist/functions/auth.d.ts.map +0 -1
- package/dist/functions/debug-auth.d.ts +0 -33
- package/dist/functions/debug-auth.d.ts.map +0 -1
- package/dist/functions/embeddings.d.ts +0 -205
- package/dist/functions/embeddings.d.ts.map +0 -1
- package/dist/functions/handler-registry.d.ts +0 -22
- package/dist/functions/handler-registry.d.ts.map +0 -1
- package/dist/functions/integration-routes.d.ts +0 -45
- package/dist/functions/integration-routes.d.ts.map +0 -1
- package/dist/functions/integrations.d.ts +0 -124
- package/dist/functions/integrations.d.ts.map +0 -1
- package/dist/functions/item-progress.d.ts +0 -41
- package/dist/functions/item-progress.d.ts.map +0 -1
- package/dist/functions/logs.d.ts +0 -162
- package/dist/functions/logs.d.ts.map +0 -1
- package/dist/functions/observability.d.ts +0 -123
- package/dist/functions/observability.d.ts.map +0 -1
- package/dist/functions/pipeline-executions.d.ts +0 -190
- package/dist/functions/pipeline-executions.d.ts.map +0 -1
- package/dist/functions/pipelines.d.ts +0 -171
- package/dist/functions/pipelines.d.ts.map +0 -1
- package/dist/functions/prompt-configs.d.ts +0 -125
- package/dist/functions/prompt-configs.d.ts.map +0 -1
- package/dist/functions/roles.d.ts +0 -118
- package/dist/functions/roles.d.ts.map +0 -1
- package/dist/functions/signal.d.ts +0 -73
- package/dist/functions/signal.d.ts.map +0 -1
- package/dist/functions/system-cron.d.ts +0 -65
- package/dist/functions/system-cron.d.ts.map +0 -1
- package/dist/functions/system.d.ts +0 -29
- package/dist/functions/system.d.ts.map +0 -1
- package/dist/functions/tests.d.ts +0 -28
- package/dist/functions/tests.d.ts.map +0 -1
- package/dist/functions/timers.d.ts +0 -139
- package/dist/functions/timers.d.ts.map +0 -1
- package/dist/functions/triggers.d.ts +0 -203
- package/dist/functions/triggers.d.ts.map +0 -1
- package/dist/functions/types.d.ts +0 -151
- package/dist/functions/types.d.ts.map +0 -1
- package/dist/src/types/types.d.ts +0 -364
- package/dist/src/types/types.d.ts.map +0 -1
- package/index.html +0 -13
- package/netlify.toml +0 -36
- package/package-project.json +0 -71
- package/scripts/ingest-chunks.cjs +0 -202
- package/scripts/kb-chunk-parser.cjs +0 -312
- package/scripts/kb-chunk-parser.ts +0 -330
- package/scripts/load-test-app-install.ts +0 -484
- package/scripts/netlify-dev-wrapper.sh +0 -22
- package/vitest.config.ts +0 -45
- /package/{scripts → .framework/scripts}/app-install-cli.ts +0 -0
- /package/{scripts → .framework/scripts}/build-manifest.sh +0 -0
- /package/{scripts → .framework/scripts}/verify-integrity.sh +0 -0
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
-- =============================================================================
|
|
2
|
-
-- 001_seed.sql
|
|
3
|
-
-- Spine Framework — Bare minimum bootstrap data for a fresh install
|
|
4
|
-
-- Generated from live production DB audit: May 28, 2026
|
|
5
|
-
-- =============================================================================
|
|
6
|
-
-- Run AFTER 000_foundation.sql.
|
|
7
|
-
--
|
|
8
|
-
-- This file contains ONLY what is required for Spine to boot and for a
|
|
9
|
-
-- system_admin to log in and interact with the framework. Nothing more.
|
|
10
|
-
--
|
|
11
|
-
-- What requires seeding before the app can function:
|
|
12
|
-
-- 1. system_admin role — people.role_id FK target
|
|
13
|
-
-- 2. spine-core app — required by runtime; people/accounts ref app_id
|
|
14
|
-
-- 3. account type — accounts.type_id is NOT NULL
|
|
15
|
-
-- 4. person type — people.type_id is NOT NULL
|
|
16
|
-
-- 5. root system account — people.account_id is NOT NULL; the bootstrap
|
|
17
|
-
-- system_admin must belong to an account
|
|
18
|
-
--
|
|
19
|
-
-- Everything else (additional roles, app-specific types, tenant accounts,
|
|
20
|
-
-- app-owned link types) belongs in app seed files or is created via the admin UI.
|
|
21
|
-
-- =============================================================================
|
|
22
|
-
|
|
23
|
-
-- ---------------------------------------------------------------------------
|
|
24
|
-
-- 1. System Role
|
|
25
|
-
-- ---------------------------------------------------------------------------
|
|
26
|
-
INSERT INTO public.roles (slug, name, description, permissions, is_system, is_active, is_protected)
|
|
27
|
-
VALUES (
|
|
28
|
-
'system_admin',
|
|
29
|
-
'System Admin',
|
|
30
|
-
'Full system access — can manage all accounts, types, and system configuration',
|
|
31
|
-
'["*"]'::jsonb,
|
|
32
|
-
true,
|
|
33
|
-
true,
|
|
34
|
-
true
|
|
35
|
-
)
|
|
36
|
-
ON CONFLICT DO NOTHING;
|
|
37
|
-
|
|
38
|
-
-- ---------------------------------------------------------------------------
|
|
39
|
-
-- 1b. Core Roles
|
|
40
|
-
-- These are common roles used by apps but defined at core level
|
|
41
|
-
-- ---------------------------------------------------------------------------
|
|
42
|
-
INSERT INTO public.roles (slug, name, description, permissions, is_system, is_active, is_protected)
|
|
43
|
-
VALUES (
|
|
44
|
-
'member',
|
|
45
|
-
'Member',
|
|
46
|
-
'Standard member with read access to platform features',
|
|
47
|
-
'["*"]'::jsonb,
|
|
48
|
-
false,
|
|
49
|
-
true,
|
|
50
|
-
false
|
|
51
|
-
), (
|
|
52
|
-
'support',
|
|
53
|
-
'Support',
|
|
54
|
-
'Support agent with access to CRM, tickets, and customer data',
|
|
55
|
-
'["*"]'::jsonb,
|
|
56
|
-
false,
|
|
57
|
-
true,
|
|
58
|
-
false
|
|
59
|
-
)
|
|
60
|
-
ON CONFLICT DO NOTHING;
|
|
61
|
-
|
|
62
|
-
-- ---------------------------------------------------------------------------
|
|
63
|
-
-- 2. Spine Core App
|
|
64
|
-
-- ---------------------------------------------------------------------------
|
|
65
|
-
INSERT INTO public.apps (slug, name, description, version, app_type, source, is_active, is_system, min_role, config, nav_items, route_prefix, renderer, integration_deps, metadata)
|
|
66
|
-
VALUES (
|
|
67
|
-
'spine-core',
|
|
68
|
-
'Spine Core',
|
|
69
|
-
'Core Spine runtime — provides accounts, people, items, threads, messages, links, attachments, watchers',
|
|
70
|
-
'1.0.0',
|
|
71
|
-
'system',
|
|
72
|
-
'builtin',
|
|
73
|
-
true,
|
|
74
|
-
true,
|
|
75
|
-
NULL,
|
|
76
|
-
'{}'::jsonb,
|
|
77
|
-
'[]'::jsonb,
|
|
78
|
-
NULL,
|
|
79
|
-
'none',
|
|
80
|
-
'[]'::jsonb,
|
|
81
|
-
'{}'::jsonb
|
|
82
|
-
)
|
|
83
|
-
ON CONFLICT (slug) DO NOTHING;
|
|
84
|
-
|
|
85
|
-
-- ---------------------------------------------------------------------------
|
|
86
|
-
-- 3. Core Types
|
|
87
|
-
-- accounts.type_id and people.type_id are both NOT NULL, so these must exist
|
|
88
|
-
-- before any account or person can be created.
|
|
89
|
-
-- ---------------------------------------------------------------------------
|
|
90
|
-
INSERT INTO public.types (app_id, kind, slug, name, description, ownership, is_active, design_schema, validation_schema)
|
|
91
|
-
VALUES
|
|
92
|
-
((SELECT id FROM public.apps WHERE slug = 'spine-core'), 'account', 'account', 'Account', 'Organization or tenant account', 'pack', true,
|
|
93
|
-
'{"views":{"default_list":{"type":"list","label":"Accounts","fields":{"slug":{"sortable":true,"display_type":"text"},"is_active":{"sortable":true,"display_type":"badge"},"display_name":{"sortable":true,"display_type":"text"}},"display":"table"},"default_detail":{"type":"detail","label":"Account","sections":[{"title":"Overview","fields":["slug","display_name","description","is_active"]},{"title":"Metadata","fields":["created_at","updated_at"]}]}},"fields":{"slug":{"label":"Slug","system":true,"required":true,"data_type":"text"},"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"updated_at":{"label":"Updated","system":true,"readonly":true,"required":false,"data_type":"datetime"},"description":{"label":"Description","system":true,"required":false,"data_type":"textarea"},"display_name":{"label":"Display Name","system":true,"required":true,"data_type":"text"}},"record_permissions":{"member":["create","read","update"],"support":["create","read","update"],"system_admin":["create","read","update","delete"]}}'::jsonb,
|
|
94
|
-
'{"fields":{"slug":{"data_type":"text","required":true},"is_active":{"data_type":"boolean","required":true},"created_at":{"data_type":"datetime","required":false},"updated_at":{"data_type":"datetime","required":false},"description":{"data_type":"textarea","required":false},"display_name":{"data_type":"text","required":true}}}'::jsonb),
|
|
95
|
-
((SELECT id FROM public.apps WHERE slug = 'spine-core'), 'person', 'person', 'Person', 'User or contact person', 'pack', true,
|
|
96
|
-
'{"views":{"default_list":{"type":"list","label":"People","fields":{"email":{"sortable":true,"display_type":"text"},"status":{"sortable":true,"display_type":"badge"},"full_name":{"sortable":true,"display_type":"text"},"is_active":{"sortable":true,"display_type":"badge"}},"display":"table"},"default_detail":{"type":"detail","label":"Person","sections":[{"title":"Profile","fields":["full_name","email","phone","avatar_url"]},{"title":"Status","fields":["status","is_active"]},{"title":"Metadata","fields":["created_at","updated_at"]}]}},"fields":{"email":{"label":"Email","system":true,"required":true,"data_type":"email"},"phone":{"label":"Phone","system":true,"required":false,"data_type":"phone"},"status":{"label":"Status","system":true,"required":true,"data_type":"text"},"full_name":{"label":"Full Name","system":true,"required":true,"data_type":"text"},"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"avatar_url":{"label":"Avatar URL","system":true,"required":false,"data_type":"url"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"updated_at":{"label":"Updated","system":true,"readonly":true,"required":false,"data_type":"datetime"}},"record_permissions":{"member":["create","read","update"],"support":["create","read","update"],"system_admin":["create","read","update","delete"]}}'::jsonb,
|
|
97
|
-
'{"fields":{"email":{"data_type":"email","required":true},"phone":{"data_type":"phone","required":false},"status":{"data_type":"text","required":true},"full_name":{"data_type":"text","required":true},"is_active":{"data_type":"boolean","required":true},"avatar_url":{"data_type":"url","required":false},"created_at":{"data_type":"datetime","required":false},"updated_at":{"data_type":"datetime","required":false}}}'::jsonb)
|
|
98
|
-
ON CONFLICT (app_id, kind, slug) DO UPDATE
|
|
99
|
-
SET design_schema = EXCLUDED.design_schema,
|
|
100
|
-
validation_schema = EXCLUDED.validation_schema,
|
|
101
|
-
name = EXCLUDED.name,
|
|
102
|
-
description = EXCLUDED.description;
|
|
103
|
-
|
|
104
|
-
-- ---------------------------------------------------------------------------
|
|
105
|
-
-- 4. Root System Account
|
|
106
|
-
-- The first system_admin person must belong to an account. This is the
|
|
107
|
-
-- bootstrap account for the Spine system itself.
|
|
108
|
-
-- NOTE: The system_admin person record is NOT seeded here — it is created
|
|
109
|
-
-- via Supabase Auth invite + the onboarding flow, which stamps type_id and
|
|
110
|
-
-- role_id onto the resulting people row.
|
|
111
|
-
-- ---------------------------------------------------------------------------
|
|
112
|
-
INSERT INTO public.accounts (type_id, slug, display_name, description, is_active, design_schema, validation_schema)
|
|
113
|
-
VALUES (
|
|
114
|
-
(SELECT id FROM public.types WHERE kind = 'account' AND slug = 'account'),
|
|
115
|
-
'spine-system',
|
|
116
|
-
'Spine System',
|
|
117
|
-
'Root system account for the Spine framework',
|
|
118
|
-
true,
|
|
119
|
-
(SELECT design_schema FROM public.types WHERE kind = 'account' AND slug = 'account'),
|
|
120
|
-
'{}'::jsonb
|
|
121
|
-
)
|
|
122
|
-
ON CONFLICT (slug) DO UPDATE
|
|
123
|
-
SET design_schema = EXCLUDED.design_schema,
|
|
124
|
-
validation_schema = EXCLUDED.validation_schema;
|
|
125
|
-
|
|
126
|
-
-- ---------------------------------------------------------------------------
|
|
127
|
-
-- 5. Core Spine Types
|
|
128
|
-
-- These types are owned by spine-core and provide design_schema for all
|
|
129
|
-
-- built-in framework entities. Apps build on top of these.
|
|
130
|
-
-- ---------------------------------------------------------------------------
|
|
131
|
-
INSERT INTO public.types (app_id, kind, slug, name, description, ownership, is_active, design_schema, validation_schema)
|
|
132
|
-
SELECT
|
|
133
|
-
a.id,
|
|
134
|
-
t.kind,
|
|
135
|
-
t.slug,
|
|
136
|
-
t.name,
|
|
137
|
-
t.description,
|
|
138
|
-
t.ownership,
|
|
139
|
-
true,
|
|
140
|
-
t.design_schema,
|
|
141
|
-
t.validation_schema
|
|
142
|
-
FROM (VALUES
|
|
143
|
-
('alert', 'threshold_alert', 'Threshold Alert', 'System threshold alert configuration for observability', 'tenant', '{"scope":"account","views":{"default_list":{"type":"list","label":"Threshold Alerts","fields":{"title":{"sortable":true,"display_type":"text"},"metric":{"sortable":true,"display_type":"badge"},"status":{"sortable":true,"display_type":"badge"},"is_active":{"sortable":true,"display_type":"badge"}},"display":"table","default_sort":{"field":"created_at","direction":"desc"}},"default_detail":{"type":"detail","label":"Threshold Alert","sections":[{"title":"Alert Config","fields":["title","description","metric","operator","value","window_minutes","pipeline_id"]},{"title":"Status","fields":["status","is_active"]},{"title":"Metadata","fields":["created_at","updated_at"]}]}},"fields":{"title":{"label":"Title","system":true,"required":true,"data_type":"text"},"value":{"label":"Value","system":false,"required":true,"data_type":"number"},"metric":{"label":"Metric","system":false,"required":true,"data_type":"text"},"status":{"label":"Status","system":true,"required":false,"data_type":"text"},"operator":{"label":"Operator","system":false,"required":true,"data_type":"text"},"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"updated_at":{"label":"Updated","system":true,"readonly":true,"required":false,"data_type":"datetime"},"description":{"label":"Description","system":true,"required":false,"data_type":"textarea"},"pipeline_id":{"label":"Pipeline","system":false,"required":false,"data_type":"text"},"window_minutes":{"label":"Window (minutes)","system":false,"required":true,"data_type":"number"}},"record_permissions":{"support":["create","read","update"],"system_admin":["create","read","update","delete"]}}'::jsonb, '{"fields":{"title":{"data_type":"text","required":true},"value":{"data_type":"number","required":true},"metric":{"data_type":"text","required":true},"status":{"data_type":"text","required":false},"operator":{"data_type":"text","required":true},"is_active":{"data_type":"boolean","required":true},"created_at":{"data_type":"datetime","required":false},"updated_at":{"data_type":"datetime","required":false},"description":{"data_type":"textarea","required":false},"pipeline_id":{"data_type":"text","required":false},"window_minutes":{"data_type":"number","required":true}}}'::jsonb),
|
|
144
|
-
('attachment', 'attachment', 'Attachment', 'File attachment or document', 'pack', '{"scope":"account","views":{"default_list":{"type":"list","label":"Attachments","fields":{"filename":{"sortable":true,"display_type":"text"},"file_size":{"sortable":true,"display_type":"number"},"mime_type":{"sortable":true,"display_type":"badge"},"storage_provider":{"sortable":true,"display_type":"badge"}},"display":"table"},"default_detail":{"type":"detail","label":"Attachment","sections":[{"title":"File Info","fields":["filename","file_size","mime_type","storage_path","storage_provider"]},{"title":"Metadata","fields":["is_active","created_at"]}]}},"fields":{"filename":{"label":"Filename","system":true,"required":true,"data_type":"text"},"file_size":{"label":"File Size","system":true,"required":false,"data_type":"number"},"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"mime_type":{"label":"MIME Type","system":true,"required":false,"data_type":"text"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"storage_path":{"label":"Storage Path","system":true,"required":false,"data_type":"text"},"storage_provider":{"label":"Storage Provider","system":true,"required":false,"data_type":"text"}},"record_permissions":{"member":["read"],"support":["create","read","update"],"system_admin":["create","read","update","delete"]}}'::jsonb, '{"fields":{"filename":{"data_type":"text","required":true},"file_size":{"data_type":"number","required":false},"is_active":{"data_type":"boolean","required":true},"mime_type":{"data_type":"text","required":false},"created_at":{"data_type":"datetime","required":false},"storage_path":{"data_type":"text","required":false},"storage_provider":{"data_type":"text","required":false}}}'::jsonb),
|
|
145
|
-
('item', 'item', 'Item', 'Generic work item or record', 'pack', '{"scope":"account","views":{"default_list":{"type":"list","label":"Items","fields":{"title":{"sortable":true,"display_type":"text"},"status":{"sortable":true,"display_type":"badge"},"is_active":{"sortable":true,"display_type":"badge"}},"display":"table"},"default_detail":{"type":"detail","label":"Item","sections":[{"title":"Details","fields":["title","description","status","is_active"]},{"title":"Metadata","fields":["created_at","updated_at"]}]}},"fields":{"title":{"label":"Title","system":true,"required":true,"data_type":"text"},"status":{"label":"Status","system":true,"required":true,"data_type":"text"},"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"updated_at":{"label":"Updated","system":true,"readonly":true,"required":false,"data_type":"datetime"},"description":{"label":"Description","system":true,"required":false,"data_type":"textarea"}},"record_permissions":{"member":["create","read","update"],"support":["create","read","update"],"system_admin":["create","read","update","delete"]}}'::jsonb, '{"fields":{"title":{"data_type":"text","required":true},"status":{"data_type":"text","required":true},"is_active":{"data_type":"boolean","required":true},"created_at":{"data_type":"datetime","required":false},"updated_at":{"data_type":"datetime","required":false},"description":{"data_type":"textarea","required":false}}}'::jsonb),
|
|
146
|
-
('item', 'activity_log', 'Activity Log', 'Audit log for funnel intelligence activities', 'tenant', '{"scope":"platform","views":{"default_list":{"type":"list","label":"Activity Logs","fields":{"action":{"sortable":true,"display_type":"badge"},"account_id":{"sortable":true,"display_type":"text"},"created_at":{"sortable":true,"display_type":"timestamp"}},"display":"table","default_sort":{"field":"created_at","direction":"desc"}}},"fields":{"action":{"label":"Action","options":["lead_score_updated","lifecycle_stage_changed","signal_processed","task_created"],"required":true,"data_type":"text"},"new_score":{"label":"New Score","required":false,"data_type":"integer"},"new_stage":{"label":"New Stage","required":false,"data_type":"text"},"person_id":{"label":"Person ID","required":false,"data_type":"uuid"},"account_id":{"label":"Account ID","required":false,"data_type":"uuid"},"score_delta":{"label":"Score Delta","required":false,"data_type":"integer"},"signal_type":{"label":"Signal Type","required":false,"data_type":"text"}},"record_permissions":{"member":["read"],"support":["create","read","update"],"system_admin":["create","read","update","delete"]}}'::jsonb, '{"fields":{"action":{"data_type":"text","required":true,"options":["lead_score_updated","lifecycle_stage_changed","signal_processed","task_created"]},"new_score":{"data_type":"integer","required":false},"new_stage":{"data_type":"text","required":false},"person_id":{"data_type":"uuid","required":false},"account_id":{"data_type":"uuid","required":false},"score_delta":{"data_type":"integer","required":false},"signal_type":{"data_type":"text","required":false}}}'::jsonb),
|
|
147
|
-
('item', 'task', 'Task', 'Task or action item for follow-up and tracking', 'tenant', '{"scope":"platform","views":{"default_list":{"type":"list","label":"Tasks","fields":{"status":{"sortable":true,"display_type":"badge"},"due_date":{"sortable":true,"display_type":"timestamp"},"priority":{"sortable":true,"display_type":"badge"},"task_type":{"sortable":true,"display_type":"badge"}},"display":"table","default_sort":{"field":"created_at","direction":"desc"}},"default_detail":{"type":"detail","label":"Task","sections":[{"title":"Task Details","fields":["task_type","priority","description","due_date"]},{"title":"Assignment","fields":["account_id","person_id"]},{"title":"Metadata","fields":["status","created_at","updated_at"]}]}},"fields":{"due_date":{"label":"Due Date","required":false,"data_type":"datetime"},"priority":{"label":"Priority","default":"medium","options":["low","medium","high","urgent"],"required":true,"data_type":"text"},"person_id":{"label":"Person ID","required":false,"data_type":"uuid"},"task_type":{"label":"Task Type","options":["lead_review","customer_followup","support_escalation","health_check"],"required":true,"data_type":"text"},"account_id":{"label":"Account ID","required":false,"data_type":"uuid"},"description":{"label":"Description","required":true,"data_type":"textarea"}},"record_permissions":{"member":["read"],"support":["create","read","update"],"system_admin":["create","read","update","delete"]}}'::jsonb, '{"fields":{"due_date":{"data_type":"datetime","required":false},"priority":{"data_type":"text","required":true,"options":["low","medium","high","urgent"]},"person_id":{"data_type":"uuid","required":false},"task_type":{"data_type":"text","required":true,"options":["lead_review","customer_followup","support_escalation","health_check"]},"account_id":{"data_type":"uuid","required":false},"description":{"data_type":"textarea","required":true}}}'::jsonb),
|
|
148
|
-
('link', 'link', 'Link', 'Relationship between entities', 'pack', '{"scope":"account","views":{"default_list":{"type":"list","label":"Links","fields":{"link_type":{"sortable":true,"display_type":"badge"},"source_type":{"sortable":true,"display_type":"text"},"target_type":{"sortable":true,"display_type":"text"}},"display":"table"},"default_detail":{"type":"detail","label":"Link","sections":[{"title":"Relationship","fields":["source_type","target_type","link_type","is_active"]},{"title":"Metadata","fields":["created_at"]}]}},"fields":{"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"link_type":{"label":"Link Type","system":true,"required":false,"data_type":"text"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"source_type":{"label":"Source Type","system":true,"required":true,"data_type":"text"},"target_type":{"label":"Target Type","system":true,"required":true,"data_type":"text"}},"record_permissions":{"member":["create","read"],"support":["create","read","update"],"system_admin":["create","read","update","delete"]}}'::jsonb, '{"fields":{"is_active":{"data_type":"boolean","required":true},"link_type":{"data_type":"text","required":false},"created_at":{"data_type":"datetime","required":false},"source_type":{"data_type":"text","required":true},"target_type":{"data_type":"text","required":true}}}'::jsonb),
|
|
149
|
-
('message', 'message', 'Message', 'Individual message in a thread', 'pack', '{"scope":"platform","views":{"default_list":{"type":"list","label":"Messages","fields":{"content":{"sortable":false,"display_type":"text"},"sequence":{"sortable":true,"display_type":"number"},"direction":{"sortable":true,"display_type":"badge"}},"display":"table"},"default_detail":{"type":"detail","label":"Message","sections":[{"title":"Content","fields":["content","direction","sequence","visibility"]},{"title":"Metadata","fields":["created_at"]}]}},"fields":{"content":{"label":"Content","system":true,"required":true,"data_type":"textarea"},"sequence":{"label":"Sequence","system":true,"required":true,"data_type":"number"},"direction":{"label":"Direction","system":true,"required":true,"data_type":"text"},"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"visibility":{"label":"Visibility","system":true,"required":false,"data_type":"text"},"message_type":{"label":"Message Type","system":true,"required":false,"data_type":"text"}},"record_permissions":{"member":["read","create"],"support":["read","create","update","delete"],"system_admin":["read","create","update","delete"]}}'::jsonb, '{"fields":{"content":{"data_type":"textarea","required":true},"sequence":{"data_type":"number","required":true},"direction":{"data_type":"text","required":true},"is_active":{"data_type":"boolean","required":true},"created_at":{"data_type":"datetime","required":false},"visibility":{"data_type":"text","required":false},"message_type":{"data_type":"text","required":false}}}'::jsonb),
|
|
150
|
-
('progress', 'course_lesson_progress', 'Course Lesson Progress', 'Tracks per-student progress through a course lesson', 'pack', '{"scope":"account","views":{"default_list":{"type":"list","label":"Progress Records","fields":{"score":{"sortable":true,"display_type":"number"},"title":{"sortable":true,"display_type":"text"},"status":{"sortable":true,"display_type":"badge"},"updated_at":{"sortable":true,"display_type":"timestamp"}},"display":"table"},"default_detail":{"type":"detail","label":"Progress Record","sections":[{"title":"Overview","fields":["title","description","status","score"]},{"title":"Activity","fields":["attempts","time_spent","last_position","started_at","completed_at"]},{"title":"Metadata","fields":["is_active","created_at","updated_at"]}]}},"fields":{"score":{"label":"Score","system":true,"required":false,"data_type":"number","validation":{"max":100,"min":0,"integer":true}},"title":{"label":"Title","system":true,"readonly":true,"required":false,"data_type":"text"},"status":{"label":"Status","system":true,"options":["not_started","in_progress","completed"],"required":true,"data_type":"select"},"attempts":{"label":"Attempts","required":false,"data_type":"number","validation":{"min":0,"integer":true}},"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"started_at":{"label":"Started At","readonly":true,"required":false,"data_type":"datetime"},"time_spent":{"label":"Time Spent (s)","required":false,"data_type":"number","validation":{"min":0,"integer":true}},"updated_at":{"label":"Updated","system":true,"readonly":true,"required":false,"data_type":"datetime"},"description":{"label":"Description","system":true,"readonly":true,"required":false,"data_type":"textarea"},"completed_at":{"label":"Completed At","readonly":true,"required":false,"data_type":"datetime"},"last_position":{"label":"Last Position (s)","required":false,"data_type":"number","validation":{"min":0,"integer":true}}},"pipeline":["not_started","in_progress","completed"],"record_permissions":{"member":["create","read","update"],"support":["create","read","update"],"system_admin":["create","read","update","delete"]}}'::jsonb, '{"fields":{"score":{"data_type":"number","required":false,"max":100,"min":0,"integer":true},"title":{"data_type":"text","required":false},"status":{"data_type":"select","required":true,"options":["not_started","in_progress","completed"]},"attempts":{"data_type":"number","required":false,"min":0,"integer":true},"is_active":{"data_type":"boolean","required":true},"created_at":{"data_type":"datetime","required":false},"started_at":{"data_type":"datetime","required":false},"time_spent":{"data_type":"number","required":false,"min":0,"integer":true},"updated_at":{"data_type":"datetime","required":false},"description":{"data_type":"textarea","required":false},"completed_at":{"data_type":"datetime","required":false},"last_position":{"data_type":"number","required":false,"min":0,"integer":true}}}'::jsonb),
|
|
151
|
-
('thread', 'thread', 'Thread', 'Conversation thread for items or entities', 'pack', '{"scope":"platform","views":{"default_list":{"type":"list","label":"Threads","fields":{"title":{"sortable":true,"display_type":"text"},"status":{"sortable":true,"display_type":"badge"},"visibility":{"sortable":true,"display_type":"badge"},"target_type":{"sortable":true,"display_type":"badge"}},"display":"table"},"default_detail":{"type":"detail","label":"Thread","sections":[{"title":"Overview","fields":["title","target_type","visibility","status","is_active"]},{"title":"Metadata","fields":["created_at","updated_at"]}]}},"fields":{"title":{"label":"Title","system":true,"required":false,"data_type":"text"},"status":{"label":"Status","system":true,"required":true,"data_type":"text"},"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"updated_at":{"label":"Updated","system":true,"readonly":true,"required":false,"data_type":"datetime"},"visibility":{"label":"Visibility","system":true,"required":true,"data_type":"text"},"target_type":{"label":"Target Type","system":true,"required":true,"data_type":"text"}},"ai_routing":{"agent_id":{"type":"string","label":"Agent ID"},"prompt_config_id":{"type":"string","label":"Prompt Config ID"}},"record_permissions":{"member":["read","create"],"support":["read","create","update","delete"],"system_admin":["read","create","update","delete"]}}'::jsonb, '{"fields":{"title":{"data_type":"text","required":false},"status":{"data_type":"text","required":true},"is_active":{"data_type":"boolean","required":true},"created_at":{"data_type":"datetime","required":false},"updated_at":{"data_type":"datetime","required":false},"visibility":{"data_type":"text","required":true},"target_type":{"data_type":"text","required":true}}}'::jsonb),
|
|
152
|
-
('watcher', 'watcher', 'Watcher', 'Entity watcher subscription', 'pack', '{"scope":"account","views":{"default_list":{"type":"list","label":"Watchers","fields":{"is_active":{"sortable":true,"display_type":"badge"},"watch_type":{"sortable":true,"display_type":"badge"},"target_type":{"sortable":true,"display_type":"text"},"notification_level":{"sortable":true,"display_type":"badge"}},"display":"table"},"default_detail":{"type":"detail","label":"Watcher","sections":[{"title":"Watch Settings","fields":["target_type","watch_type","notification_level","is_active"]},{"title":"Metadata","fields":["created_at","updated_at"]}]}},"fields":{"is_active":{"label":"Active","system":true,"required":true,"data_type":"boolean"},"created_at":{"label":"Created","system":true,"readonly":true,"required":false,"data_type":"datetime"},"updated_at":{"label":"Updated","system":true,"readonly":true,"required":false,"data_type":"datetime"},"watch_type":{"label":"Watch Type","system":true,"required":false,"data_type":"text"},"target_type":{"label":"Target Type","system":true,"required":true,"data_type":"text"},"notification_level":{"label":"Notification Level","system":true,"required":true,"data_type":"text"}},"record_permissions":{"member":["create","read","delete"],"support":["create","read","delete"],"system_admin":["create","read","update","delete"]}}'::jsonb, '{"fields":{"is_active":{"data_type":"boolean","required":true},"created_at":{"data_type":"datetime","required":false},"updated_at":{"data_type":"datetime","required":false},"watch_type":{"data_type":"text","required":false},"target_type":{"data_type":"text","required":true},"notification_level":{"data_type":"text","required":true}}}'::jsonb)
|
|
153
|
-
) AS t(kind, slug, name, description, ownership, design_schema, validation_schema)
|
|
154
|
-
CROSS JOIN (SELECT id FROM public.apps WHERE slug = 'spine-core') AS a
|
|
155
|
-
ON CONFLICT (app_id, kind, slug) DO UPDATE
|
|
156
|
-
SET design_schema = EXCLUDED.design_schema,
|
|
157
|
-
validation_schema = EXCLUDED.validation_schema,
|
|
158
|
-
name = EXCLUDED.name,
|
|
159
|
-
description = EXCLUDED.description;
|
|
160
|
-
|
|
161
|
-
-- NOTE: No link types are seeded here. All link types are app-owned.
|
|
162
|
-
-- Cortex seeds: account_signals, account_opportunities, analyzed_by, tagged_with
|
|
163
|
-
-- See custom/apps/cortex/seed/link-types.json
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
-- =============================================================================
|
|
2
|
-
-- 002_seed_constraints.sql
|
|
3
|
-
-- Adds unique constraints required for idempotent seed upserts
|
|
4
|
-
-- =============================================================================
|
|
5
|
-
|
|
6
|
-
-- link_types needs unique on (app_id, slug) for seed upserts
|
|
7
|
-
DO $$ BEGIN
|
|
8
|
-
ALTER TABLE public.link_types ADD CONSTRAINT link_types_app_id_slug_key UNIQUE (app_id, slug);
|
|
9
|
-
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
|
10
|
-
|
|
11
|
-
-- triggers needs unique on (app_id, name) for seed upserts
|
|
12
|
-
DO $$ BEGIN
|
|
13
|
-
ALTER TABLE public.triggers ADD CONSTRAINT triggers_app_id_name_key UNIQUE (app_id, name);
|
|
14
|
-
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
|
15
|
-
|
|
16
|
-
-- pipelines needs unique on (app_id, name) for seed upserts
|
|
17
|
-
DO $$ BEGIN
|
|
18
|
-
ALTER TABLE public.pipelines ADD CONSTRAINT pipelines_app_id_name_key UNIQUE (app_id, name);
|
|
19
|
-
EXCEPTION WHEN duplicate_object THEN NULL; END $$;
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
-- =============================================================================
|
|
2
|
-
-- 003_auth_user_trigger.sql
|
|
3
|
-
-- Creates a people record whenever a new Supabase auth user signs up.
|
|
4
|
-
-- Run AFTER 001_seed.sql (requires spine-system account and person type).
|
|
5
|
-
--
|
|
6
|
-
-- First user ever → system_admin role (bootstrap)
|
|
7
|
-
-- Subsequent users → no role (assigned later via admin invite flow)
|
|
8
|
-
-- =============================================================================
|
|
9
|
-
|
|
10
|
-
CREATE OR REPLACE FUNCTION public.handle_new_auth_user()
|
|
11
|
-
RETURNS TRIGGER LANGUAGE plpgsql SECURITY DEFINER SET search_path = public AS $$
|
|
12
|
-
DECLARE
|
|
13
|
-
v_account_id uuid;
|
|
14
|
-
v_type_id uuid;
|
|
15
|
-
v_role_id uuid;
|
|
16
|
-
v_is_first boolean;
|
|
17
|
-
v_design_schema jsonb;
|
|
18
|
-
v_validation_schema jsonb;
|
|
19
|
-
BEGIN
|
|
20
|
-
SELECT id INTO v_account_id FROM public.accounts WHERE slug = 'spine-system' LIMIT 1;
|
|
21
|
-
SELECT id, design_schema, validation_schema
|
|
22
|
-
INTO v_type_id, v_design_schema, v_validation_schema
|
|
23
|
-
FROM public.types WHERE kind = 'person' AND slug = 'person' LIMIT 1;
|
|
24
|
-
|
|
25
|
-
IF v_account_id IS NULL OR v_type_id IS NULL THEN
|
|
26
|
-
RAISE WARNING 'handle_new_auth_user: spine-system account or person type not found — skipping people insert';
|
|
27
|
-
RETURN NEW;
|
|
28
|
-
END IF;
|
|
29
|
-
|
|
30
|
-
-- First person ever gets system_admin; subsequent users get no role
|
|
31
|
-
SELECT NOT EXISTS (SELECT 1 FROM public.people LIMIT 1) INTO v_is_first;
|
|
32
|
-
IF v_is_first THEN
|
|
33
|
-
SELECT id INTO v_role_id FROM public.roles WHERE slug = 'system_admin' LIMIT 1;
|
|
34
|
-
END IF;
|
|
35
|
-
|
|
36
|
-
INSERT INTO public.people (
|
|
37
|
-
id,
|
|
38
|
-
auth_uid,
|
|
39
|
-
email,
|
|
40
|
-
full_name,
|
|
41
|
-
account_id,
|
|
42
|
-
type_id,
|
|
43
|
-
role_id,
|
|
44
|
-
is_active,
|
|
45
|
-
design_schema,
|
|
46
|
-
validation_schema
|
|
47
|
-
) VALUES (
|
|
48
|
-
NEW.id,
|
|
49
|
-
NEW.id,
|
|
50
|
-
NEW.email,
|
|
51
|
-
COALESCE(NEW.raw_user_meta_data->>'full_name', split_part(NEW.email, '@', 1)),
|
|
52
|
-
v_account_id,
|
|
53
|
-
v_type_id,
|
|
54
|
-
v_role_id,
|
|
55
|
-
true,
|
|
56
|
-
v_design_schema,
|
|
57
|
-
COALESCE(v_validation_schema, '{}'::jsonb)
|
|
58
|
-
)
|
|
59
|
-
ON CONFLICT (id) DO NOTHING;
|
|
60
|
-
|
|
61
|
-
RETURN NEW;
|
|
62
|
-
END;
|
|
63
|
-
$$;
|
|
64
|
-
|
|
65
|
-
CREATE OR REPLACE TRIGGER on_auth_user_created
|
|
66
|
-
AFTER INSERT ON auth.users
|
|
67
|
-
FOR EACH ROW EXECUTE FUNCTION public.handle_new_auth_user();
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
-- 004_app_version_tracking.sql
|
|
2
|
-
-- Adds version tracking columns to app_installations so the CLI and
|
|
3
|
-
-- agentic IDE can detect drift between the installed version and the
|
|
4
|
-
-- latest published npm package version.
|
|
5
|
-
|
|
6
|
-
ALTER TABLE public.app_installations
|
|
7
|
-
ADD COLUMN IF NOT EXISTS installed_version varchar,
|
|
8
|
-
ADD COLUMN IF NOT EXISTS package_name varchar;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
-- Migration 005: Add slug to pipelines, rename steps → stages
|
|
2
|
-
-- Adds a human-readable slug for pipeline identification and seed-time resolution.
|
|
3
|
-
-- Renames the `steps` column to `stages` to match pipeline-runner.ts expectations.
|
|
4
|
-
|
|
5
|
-
-- Add slug column (nullable initially so existing rows don't break)
|
|
6
|
-
ALTER TABLE public.pipelines
|
|
7
|
-
ADD COLUMN IF NOT EXISTS slug text;
|
|
8
|
-
|
|
9
|
-
-- Rename steps → stages to match pipeline-runner.ts (reads pipeline.stages)
|
|
10
|
-
ALTER TABLE public.pipelines
|
|
11
|
-
RENAME COLUMN steps TO stages;
|
|
12
|
-
|
|
13
|
-
-- Add unique constraint on (app_id, slug) for seed-time upsert via ON CONFLICT.
|
|
14
|
-
-- Must be a non-partial constraint — PostgREST requires non-partial unique indexes
|
|
15
|
-
-- for ON CONFLICT clause resolution. NULL slugs are naturally excluded from
|
|
16
|
-
-- uniqueness enforcement by Postgres (NULL != NULL), so no partial index is needed.
|
|
17
|
-
DROP INDEX IF EXISTS public.pipelines_app_id_slug_idx;
|
|
18
|
-
ALTER TABLE public.pipelines
|
|
19
|
-
DROP CONSTRAINT IF EXISTS pipelines_app_id_slug_key;
|
|
20
|
-
ALTER TABLE public.pipelines
|
|
21
|
-
ADD CONSTRAINT pipelines_app_id_slug_key UNIQUE (app_id, slug);
|
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/pages/auth/RegisterPage
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-page
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Self-registration page. Renders a centred card with email/password/name
|
|
8
|
-
* inputs. On submit, calls Supabase signUp and navigates to /login with
|
|
9
|
-
* a confirmation message.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
import React, { useState } from 'react'
|
|
13
|
-
import { Link, useNavigate } from 'react-router-dom'
|
|
14
|
-
import { useAuth } from '../../contexts/AuthContext'
|
|
15
|
-
import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
|
|
16
|
-
import { supabase } from '../../lib/supabase'
|
|
17
|
-
|
|
18
|
-
export function RegisterPage() {
|
|
19
|
-
const [email, setEmail] = useState('')
|
|
20
|
-
const [password, setPassword] = useState('')
|
|
21
|
-
const [fullName, setFullName] = useState('')
|
|
22
|
-
const [error, setError] = useState('')
|
|
23
|
-
const [success, setSuccess] = useState('')
|
|
24
|
-
const [isLoading, setIsLoading] = useState(false)
|
|
25
|
-
|
|
26
|
-
const navigate = useNavigate()
|
|
27
|
-
|
|
28
|
-
const handleSubmit = async (e: React.FormEvent) => {
|
|
29
|
-
e.preventDefault()
|
|
30
|
-
setError('')
|
|
31
|
-
setSuccess('')
|
|
32
|
-
setIsLoading(true)
|
|
33
|
-
|
|
34
|
-
try {
|
|
35
|
-
const { error: signUpError } = await supabase.auth.signUp({
|
|
36
|
-
email,
|
|
37
|
-
password,
|
|
38
|
-
options: {
|
|
39
|
-
data: {
|
|
40
|
-
full_name: fullName,
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
})
|
|
44
|
-
|
|
45
|
-
if (signUpError) {
|
|
46
|
-
setError(signUpError.message)
|
|
47
|
-
return
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
setSuccess('Account created! Check your email for a confirmation link.')
|
|
51
|
-
setTimeout(() => navigate('/login'), 3000)
|
|
52
|
-
} catch (err: any) {
|
|
53
|
-
setError(err.message || 'Registration failed')
|
|
54
|
-
} finally {
|
|
55
|
-
setIsLoading(false)
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
return (
|
|
60
|
-
<div className="min-h-screen flex items-center justify-center bg-slate-50 py-12 px-4 sm:px-6 lg:px-8">
|
|
61
|
-
<div className="max-w-md w-full space-y-8">
|
|
62
|
-
<div>
|
|
63
|
-
<div className="mx-auto h-12 w-12 flex items-center justify-center rounded-full bg-slate-900">
|
|
64
|
-
<span className="text-white font-bold text-xl">S</span>
|
|
65
|
-
</div>
|
|
66
|
-
<h2 className="mt-6 text-center text-3xl font-extrabold text-slate-900">
|
|
67
|
-
Create your account
|
|
68
|
-
</h2>
|
|
69
|
-
<p className="mt-2 text-center text-sm text-slate-600">
|
|
70
|
-
Already have an account?{' '}
|
|
71
|
-
<Link to="/login" className="font-medium text-accent-blue hover:text-accent-blue-light">
|
|
72
|
-
Sign in
|
|
73
|
-
</Link>
|
|
74
|
-
</p>
|
|
75
|
-
</div>
|
|
76
|
-
|
|
77
|
-
<form className="mt-8 space-y-6" onSubmit={handleSubmit}>
|
|
78
|
-
{error && (
|
|
79
|
-
<div className="rounded-md bg-red-50 p-4">
|
|
80
|
-
<div className="text-sm text-red-800">{error}</div>
|
|
81
|
-
</div>
|
|
82
|
-
)}
|
|
83
|
-
|
|
84
|
-
{success && (
|
|
85
|
-
<div className="rounded-md bg-green-50 p-4">
|
|
86
|
-
<div className="text-sm text-green-800">{success}</div>
|
|
87
|
-
</div>
|
|
88
|
-
)}
|
|
89
|
-
|
|
90
|
-
<div className="space-y-4">
|
|
91
|
-
<div>
|
|
92
|
-
<label htmlFor="fullName" className="block text-sm font-medium text-slate-700">
|
|
93
|
-
Full name
|
|
94
|
-
</label>
|
|
95
|
-
<input
|
|
96
|
-
id="fullName"
|
|
97
|
-
name="fullName"
|
|
98
|
-
type="text"
|
|
99
|
-
required
|
|
100
|
-
value={fullName}
|
|
101
|
-
onChange={(e) => setFullName(e.target.value)}
|
|
102
|
-
className="mt-1 block w-full px-3 py-2 border border-slate-300 rounded-[5px] shadow-sm placeholder-slate-400 focus:outline-none focus:ring-accent-blue focus:border-accent-blue sm:text-sm"
|
|
103
|
-
placeholder="Enter your full name"
|
|
104
|
-
/>
|
|
105
|
-
</div>
|
|
106
|
-
|
|
107
|
-
<div>
|
|
108
|
-
<label htmlFor="email" className="block text-sm font-medium text-slate-700">
|
|
109
|
-
Email address
|
|
110
|
-
</label>
|
|
111
|
-
<input
|
|
112
|
-
id="email"
|
|
113
|
-
name="email"
|
|
114
|
-
type="email"
|
|
115
|
-
autoComplete="email"
|
|
116
|
-
required
|
|
117
|
-
value={email}
|
|
118
|
-
onChange={(e) => setEmail(e.target.value)}
|
|
119
|
-
className="mt-1 block w-full px-3 py-2 border border-slate-300 rounded-[5px] shadow-sm placeholder-slate-400 focus:outline-none focus:ring-accent-blue focus:border-accent-blue sm:text-sm"
|
|
120
|
-
placeholder="Enter your email"
|
|
121
|
-
/>
|
|
122
|
-
</div>
|
|
123
|
-
|
|
124
|
-
<div>
|
|
125
|
-
<label htmlFor="password" className="block text-sm font-medium text-slate-700">
|
|
126
|
-
Password
|
|
127
|
-
</label>
|
|
128
|
-
<input
|
|
129
|
-
id="password"
|
|
130
|
-
name="password"
|
|
131
|
-
type="password"
|
|
132
|
-
autoComplete="new-password"
|
|
133
|
-
required
|
|
134
|
-
minLength={6}
|
|
135
|
-
value={password}
|
|
136
|
-
onChange={(e) => setPassword(e.target.value)}
|
|
137
|
-
className="mt-1 block w-full px-3 py-2 border border-slate-300 rounded-[5px] shadow-sm placeholder-slate-400 focus:outline-none focus:ring-accent-blue focus:border-accent-blue sm:text-sm"
|
|
138
|
-
placeholder="Choose a password (min 6 characters)"
|
|
139
|
-
/>
|
|
140
|
-
</div>
|
|
141
|
-
</div>
|
|
142
|
-
|
|
143
|
-
<div>
|
|
144
|
-
<button
|
|
145
|
-
type="submit"
|
|
146
|
-
disabled={isLoading}
|
|
147
|
-
className="group relative w-full flex justify-center py-2 px-4 border border-transparent rounded-[5px] shadow-sm text-sm font-medium text-white bg-slate-900 hover:bg-slate-800 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-accent-blue disabled:opacity-50 disabled:cursor-not-allowed"
|
|
148
|
-
>
|
|
149
|
-
{isLoading ? (
|
|
150
|
-
<>
|
|
151
|
-
<LoadingSpinner size="sm" />
|
|
152
|
-
<span className="ml-2">Creating account...</span>
|
|
153
|
-
</>
|
|
154
|
-
) : (
|
|
155
|
-
'Create account'
|
|
156
|
-
)}
|
|
157
|
-
</button>
|
|
158
|
-
</div>
|
|
159
|
-
</form>
|
|
160
|
-
</div>
|
|
161
|
-
</div>
|
|
162
|
-
)
|
|
163
|
-
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
# Changelog — spine-framework
|
|
2
|
-
|
|
3
|
-
All notable changes to this project will be documented in this file.
|
|
4
|
-
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## [0.3.17] — 2026-06-10
|
|
8
|
-
- Fixed `integration-routes.ts` — `resolveIntegration` was querying by `name` instead of `slug`, causing all integration lookups to fail
|
|
9
|
-
|
|
10
|
-
## [0.3.16] — 2026-06-09
|
|
11
|
-
- Added `handler-registry.ts` — static handler import registry generated at assembly time
|
|
12
|
-
- Updated `assemble-functions.sh` — generates `handler-registry.ts` with static imports of all `custom_*.ts` handlers so esbuild bundles them into `integration-routes`
|
|
13
|
-
- Updated `integration-routes.ts` — replaced dynamic `resolveHandler` import with static `HANDLER_REGISTRY` lookup for esbuild-compatible handler loading
|
|
14
|
-
- Removed `loadHandler` and `resolveHandler` from `webhook-registry.ts` — no longer needed with static registry pattern
|
|
15
|
-
|
|
16
|
-
## [0.3.15] — 2026-06-09
|
|
17
|
-
- Fixed `upsertIntegrations` in install-app.ts — now explicitly picks only valid DB columns (name, slug, provider, status, is_active, config) instead of spreading entire record, preventing "description column not found" errors
|
|
18
|
-
|
|
19
|
-
## [0.3.14] — 2026-06-09
|
|
20
|
-
- Fixed `integrations.json` handler config format — changed `"handler": "funnel-signal"` to `"handler": { "path": "funnel-signal" }` to match `integration-routes.ts` step 8 lookup at `config.handler?.path`
|
|
21
|
-
- Removed orphaned `on_funnel_signal_created` trigger from `triggers.json` — the trigger engine routes exclusively through `runPipeline(trigger.pipeline_id, ...)` and has no path to directly invoke a custom function; scoring now happens inline in `custom_funnel-signal.ts`
|
|
22
|
-
- Removed orphaned `funnel-scoring-trigger` handler registration from `webhook-handlers.ts`
|
|
23
|
-
- Deleted orphaned `custom_funnel-scoring-trigger.ts` file
|
|
24
|
-
- Restored `custom_funnel-signal.ts` as complete inline handler — validates, resolves IDs, fetches prior signals, scores, inserts signal item, updates account/anonymous session, creates links, and evaluates queue entries
|
|
25
|
-
|
|
26
|
-
## [0.3.13] — 2026-06-09
|
|
27
|
-
- Fixed `assemble-functions.sh`: now also copies functions from `custom/apps/*/functions/` so installed app handlers (e.g. `custom_funnel-signal.ts`) are included in the assembled output — previously only `custom/functions/` was swept, causing "Signal handler not available" at runtime
|
|
28
|
-
|
|
29
|
-
## [0.3.12] — 2026-06-09
|
|
30
|
-
- Fixed `pipelines` seed upsert: replaced partial unique index (`WHERE slug IS NOT NULL`) on `(app_id, slug)` with a full unique constraint — PostgREST requires a non-partial unique index for `ON CONFLICT` resolution; `pipelines.json` seed now upserts correctly during `install-app`
|
|
31
|
-
|
|
32
|
-
## [0.3.11] — 2026-06-09
|
|
33
|
-
- Added `updateAccountFunnel` per-pipeline_slug rating storage in `custom_funnel-signal.ts` — signals now write `ratings[pipeline_slug]` alongside `ratings[stage]`, enabling per-funnel score breakdown in the UI
|
|
34
|
-
|
|
35
|
-
## [0.3.10] — 2026-06-08
|
|
36
|
-
- Updated `LICENSE.md` to full Spine Framework Internal Use License 1.0.0 (23 sections)
|
|
37
|
-
|
|
38
|
-
## [0.3.9] — 2026-06-08
|
|
39
|
-
- Added `CHANGELOG.md` to all three packages
|
|
40
|
-
- Added `CHANGELOG.md` to files copied by `npx spine-framework init`
|
|
41
|
-
|
|
42
|
-
## [0.3.8] — 2026-06-08
|
|
43
|
-
- Added `README.md` and `LICENSE.md` to files copied by `npx spine-framework init`
|
|
44
|
-
- Fixed duplicate `app_installations` table definition in `000_foundation.sql` — the incomplete first definition was winning the `CREATE TABLE IF NOT EXISTS` race, resulting in missing columns (`package_name`, `installed_version`) and no `UNIQUE` constraint; this caused `⚠️ Failed to record installation` on every `install-app` run
|
|
45
|
-
- Added `CHANGELOG.md` to all three packages
|
|
46
|
-
|
|
47
|
-
## [0.3.7] — 2026-06-08
|
|
48
|
-
- Fixed `app_installations` schema: moved full table definition before indexes/triggers/RLS that reference it
|
|
49
|
-
- Added non-partial `UNIQUE (app_slug, account_id)` constraint to `app_installations` to satisfy PostgREST `ON CONFLICT`
|
|
50
|
-
|
|
51
|
-
## [0.3.6] — 2026-06-08
|
|
52
|
-
- Updated all three READMEs to consistently use "Spine Framework" instead of "Spine"
|
|
53
|
-
- Added `publish:next` and `publish:promote` scripts to all three packages
|
|
54
|
-
- Created `.windsurf/workflows/publish.md` documenting the `next` → `latest` release workflow
|
|
55
|
-
|
|
56
|
-
## [0.3.5] — 2026-06-07
|
|
57
|
-
- Fixed `init` command to detect bare stub `package.json` (no `scripts`) and overwrite it rather than skipping
|
|
58
|
-
- Updated `bin/welcome.cjs` with dynamic version stamping and correct `init` instructions
|
|
59
|
-
|
|
60
|
-
## [0.3.4] — 2026-06-07
|
|
61
|
-
- Stamped current installed `spine-framework` version dynamically into `package-project.json` template during `init`
|
|
62
|
-
|
|
63
|
-
## [0.3.3] — 2026-06-07
|
|
64
|
-
- Fixed `init` command regression: no longer overwrites an existing full project `package.json`
|
|
65
|
-
|
|
66
|
-
## [0.3.2] — 2026-06-07
|
|
67
|
-
- Fixed `ERR_MODULE_NOT_FOUND` for `signals.ts` by adding `.framework/config/` to the `files` array
|
|
68
|
-
|
|
69
|
-
## [0.3.1] — 2026-06-07
|
|
70
|
-
- Added non-partial unique constraint on `roles(app_id, slug)` for PostgREST upsert support
|
|
71
|
-
- Added `app_installations` table to foundation migration
|