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.
Files changed (269) hide show
  1. package/.framework/cli/commands/create-app.ts +1 -1
  2. package/.framework/cli/commands/dev.ts +215 -33
  3. package/.framework/cli/index.ts +37 -75
  4. package/.framework/functions/_shared/app-manifest.ts +8 -15
  5. package/.framework/functions/_shared/db.ts +11 -15
  6. package/.framework/functions/_shared/index.ts +7 -16
  7. package/.framework/functions/_shared/principal.ts +4 -62
  8. package/.framework/functions/_shared/resolve-ids.ts +6 -6
  9. package/.framework/functions/_shared/webhook-registry.ts +43 -1
  10. package/.framework/functions/admin-funnel.ts +104 -0
  11. package/.framework/functions/admin-install-funnel.ts +225 -0
  12. package/.framework/functions/admin-signals.ts +241 -0
  13. package/.framework/functions/integration-routes.ts +4 -8
  14. package/.framework/migrations/001_schema.sql +406 -0
  15. package/.framework/migrations/002_rls_and_functions.sql +710 -0
  16. package/.framework/migrations/003_system_data.sql +520 -0
  17. package/.framework/migrations/004_enhancements.sql +43 -0
  18. package/.framework/public/_redirects +3 -0
  19. package/.framework/public/spine-logo.jpg +0 -0
  20. package/.framework/public/spine-logo.svg +3 -0
  21. package/{scripts → .framework/scripts}/assemble-frontend.sh +8 -5
  22. package/{scripts → .framework/scripts}/assemble-functions.sh +4 -47
  23. package/{scripts → .framework/scripts}/assemble.sh +2 -8
  24. package/{scripts → .framework/scripts}/boundary-check.sh +5 -9
  25. package/{scripts → .framework/scripts}/check-core-integrity.sh +0 -0
  26. package/.framework/seeds/link_types/account_cli_instances.json +9 -0
  27. package/.framework/seeds/types/funnel_signal_use.json +98 -0
  28. package/.framework/seeds/types/spine_instance.json +109 -0
  29. package/.framework/src/App.tsx +11 -21
  30. package/.framework/src/components/CustomAppLoader.tsx +2 -19
  31. package/.framework/src/components/ui/accordion.tsx +1 -1
  32. package/.framework/src/components/ui/alert-dialog.tsx +1 -1
  33. package/.framework/src/components/ui/aspect-ratio.tsx +1 -1
  34. package/.framework/src/components/ui/avatar.tsx +1 -1
  35. package/.framework/src/components/ui/badge.tsx +2 -2
  36. package/.framework/src/components/ui/breadcrumb.tsx +2 -2
  37. package/.framework/src/components/ui/button-group.tsx +2 -2
  38. package/.framework/src/components/ui/button.tsx +2 -2
  39. package/.framework/src/components/ui/chart.tsx +6 -1
  40. package/.framework/src/components/ui/checkbox.tsx +1 -1
  41. package/.framework/src/components/ui/collapsible.tsx +1 -1
  42. package/.framework/src/components/ui/context-menu.tsx +1 -1
  43. package/.framework/src/components/ui/dialog.tsx +1 -1
  44. package/.framework/src/components/ui/direction.tsx +17 -1
  45. package/.framework/src/components/ui/dropdown-menu.tsx +1 -1
  46. package/.framework/src/components/ui/hover-card.tsx +1 -1
  47. package/.framework/src/components/ui/item.tsx +2 -2
  48. package/.framework/src/components/ui/label.tsx +1 -1
  49. package/.framework/src/components/ui/menubar.tsx +1 -1
  50. package/.framework/src/components/ui/navigation-menu.tsx +1 -1
  51. package/.framework/src/components/ui/popover.tsx +1 -1
  52. package/.framework/src/components/ui/progress.tsx +1 -1
  53. package/.framework/src/components/ui/radio-group.tsx +1 -1
  54. package/.framework/src/components/ui/scroll-area.tsx +1 -1
  55. package/.framework/src/components/ui/select.tsx +1 -1
  56. package/.framework/src/components/ui/separator.tsx +1 -1
  57. package/.framework/src/components/ui/sheet.tsx +1 -1
  58. package/.framework/src/components/ui/sidebar.tsx +6 -6
  59. package/.framework/src/components/ui/slider.tsx +1 -1
  60. package/.framework/src/components/ui/switch.tsx +1 -1
  61. package/.framework/src/components/ui/tabs.tsx +1 -1
  62. package/.framework/src/components/ui/toggle-group.tsx +1 -1
  63. package/.framework/src/components/ui/toggle.tsx +1 -1
  64. package/.framework/src/components/ui/tooltip.tsx +1 -1
  65. package/.framework/src/pages/auth/LoginPage.tsx +10 -9
  66. package/LICENSE.md +63 -93
  67. package/README.md +254 -129
  68. package/custom/.devin/skills/install-app/SKILL.md +39 -0
  69. package/custom/.devin/workflows/app-install.yaml +83 -0
  70. package/custom/README.md +79 -0
  71. package/docs/APPS.md +232 -0
  72. package/docs/ARCHITECTURE.md +246 -0
  73. package/docs/INSTALL.md +155 -0
  74. package/docs/README.md +170 -0
  75. package/docs/design-schema-spec.md +1837 -0
  76. package/docs/dev-guides/01-create-an-app.md +183 -0
  77. package/docs/dev-guides/02-create-a-function.md +178 -0
  78. package/docs/dev-guides/03-create-a-component.md +178 -0
  79. package/docs/dev-guides/04-webhook-handlers.md +129 -0
  80. package/docs/dev-guides/05-testing.md +168 -0
  81. package/docs/dev-guides/README.md +40 -0
  82. package/docs/npm-packages-plan.md +288 -0
  83. package/docs/spine-core--api-reference.md +822 -0
  84. package/package.json +78 -150
  85. package/.framework/cli/bin.cjs +0 -14
  86. package/.framework/cli/commands/claim.ts +0 -430
  87. package/.framework/cli/commands/init.ts +0 -219
  88. package/.framework/cli/commands/install-app.ts +0 -685
  89. package/.framework/cli/commands/migrate.ts +0 -178
  90. package/.framework/cli/commands/publish.ts +0 -191
  91. package/.framework/cli/commands/status.ts +0 -268
  92. package/.framework/cli/commands/uninstall-app.ts +0 -166
  93. package/.framework/cli/commands/update-app.ts +0 -397
  94. package/.framework/cli/welcome.cjs +0 -45
  95. package/.framework/config/signal-client.ts +0 -147
  96. package/.framework/config/signals.ts +0 -70
  97. package/.framework/docs/STABILITY.md +0 -52
  98. package/.framework/docs/examples/custom-app/README.md +0 -77
  99. package/.framework/docs/examples/custom-function/README.md +0 -27
  100. package/.framework/docs/examples/custom-function/handler.ts +0 -48
  101. package/.framework/docs/examples/custom-webhook/README.md +0 -68
  102. package/.framework/functions/handler-registry.ts +0 -22
  103. package/.framework/functions/signal.ts +0 -168
  104. package/.framework/migrations/000_foundation.sql +0 -1302
  105. package/.framework/migrations/001_seed.sql +0 -163
  106. package/.framework/migrations/002_seed_constraints.sql +0 -19
  107. package/.framework/migrations/003_auth_user_trigger.sql +0 -67
  108. package/.framework/migrations/004_app_version_tracking.sql +0 -8
  109. package/.framework/migrations/005_pipelines_slug_stages.sql +0 -21
  110. package/.framework/src/pages/auth/RegisterPage.tsx +0 -163
  111. package/CHANGELOG.md +0 -71
  112. package/STRUCTURE.md +0 -150
  113. package/bin/spine-framework.cjs +0 -62
  114. package/bin/welcome.cjs +0 -58
  115. package/bin/ws-shim.ts +0 -10
  116. package/config/components.json +0 -25
  117. package/config/deno.lock +0 -108
  118. package/config/package-lock.json +0 -17183
  119. package/config/postcss.config.cjs +0 -10
  120. package/config/tailwind.config.cjs +0 -78
  121. package/config/tsconfig.build.json +0 -32
  122. package/config/tsconfig.cli.json +0 -18
  123. package/config/tsconfig.json +0 -41
  124. package/config/tsconfig.node.json +0 -17
  125. package/config/tsconfig.node.tsbuildinfo +0 -1
  126. package/config/tsconfig.tsbuildinfo +0 -1
  127. package/config/typedoc.json +0 -16
  128. package/config/vite.config.d.ts +0 -2
  129. package/config/vite.config.ts +0 -71
  130. package/dist/cli/commands/agents.d.ts +0 -39
  131. package/dist/cli/commands/agents.d.ts.map +0 -1
  132. package/dist/cli/commands/auth.d.ts +0 -36
  133. package/dist/cli/commands/auth.d.ts.map +0 -1
  134. package/dist/cli/commands/claim.d.ts +0 -38
  135. package/dist/cli/commands/claim.d.ts.map +0 -1
  136. package/dist/cli/commands/create-app.d.ts +0 -23
  137. package/dist/cli/commands/create-app.d.ts.map +0 -1
  138. package/dist/cli/commands/dev.d.ts +0 -24
  139. package/dist/cli/commands/dev.d.ts.map +0 -1
  140. package/dist/cli/commands/doctor.d.ts +0 -42
  141. package/dist/cli/commands/doctor.d.ts.map +0 -1
  142. package/dist/cli/commands/generate.d.ts +0 -36
  143. package/dist/cli/commands/generate.d.ts.map +0 -1
  144. package/dist/cli/commands/init.d.ts +0 -20
  145. package/dist/cli/commands/init.d.ts.map +0 -1
  146. package/dist/cli/commands/install-app.d.ts +0 -30
  147. package/dist/cli/commands/install-app.d.ts.map +0 -1
  148. package/dist/cli/commands/items.d.ts +0 -45
  149. package/dist/cli/commands/items.d.ts.map +0 -1
  150. package/dist/cli/commands/migrate.d.ts +0 -21
  151. package/dist/cli/commands/migrate.d.ts.map +0 -1
  152. package/dist/cli/commands/migrations.d.ts +0 -41
  153. package/dist/cli/commands/migrations.d.ts.map +0 -1
  154. package/dist/cli/commands/pipelines.d.ts +0 -40
  155. package/dist/cli/commands/pipelines.d.ts.map +0 -1
  156. package/dist/cli/commands/publish.d.ts +0 -23
  157. package/dist/cli/commands/publish.d.ts.map +0 -1
  158. package/dist/cli/commands/status.d.ts +0 -23
  159. package/dist/cli/commands/status.d.ts.map +0 -1
  160. package/dist/cli/commands/system.d.ts +0 -29
  161. package/dist/cli/commands/system.d.ts.map +0 -1
  162. package/dist/cli/commands/test.d.ts +0 -46
  163. package/dist/cli/commands/test.d.ts.map +0 -1
  164. package/dist/cli/commands/uninstall-app.d.ts +0 -23
  165. package/dist/cli/commands/uninstall-app.d.ts.map +0 -1
  166. package/dist/cli/commands/update-app.d.ts +0 -24
  167. package/dist/cli/commands/update-app.d.ts.map +0 -1
  168. package/dist/cli/context.d.ts +0 -88
  169. package/dist/cli/context.d.ts.map +0 -1
  170. package/dist/cli/env-loader.d.ts +0 -14
  171. package/dist/cli/env-loader.d.ts.map +0 -1
  172. package/dist/cli/index.d.ts +0 -44
  173. package/dist/cli/index.d.ts.map +0 -1
  174. package/dist/config/signals.d.ts +0 -82
  175. package/dist/config/signals.d.ts.map +0 -1
  176. package/dist/functions/_shared/agent-runner.d.ts +0 -156
  177. package/dist/functions/_shared/agent-runner.d.ts.map +0 -1
  178. package/dist/functions/_shared/app-manifest.d.ts +0 -68
  179. package/dist/functions/_shared/app-manifest.d.ts.map +0 -1
  180. package/dist/functions/_shared/audit.d.ts +0 -91
  181. package/dist/functions/_shared/audit.d.ts.map +0 -1
  182. package/dist/functions/_shared/db.d.ts +0 -125
  183. package/dist/functions/_shared/db.d.ts.map +0 -1
  184. package/dist/functions/_shared/index.d.ts +0 -299
  185. package/dist/functions/_shared/index.d.ts.map +0 -1
  186. package/dist/functions/_shared/middleware.d.ts +0 -315
  187. package/dist/functions/_shared/middleware.d.ts.map +0 -1
  188. package/dist/functions/_shared/permissions.d.ts +0 -626
  189. package/dist/functions/_shared/permissions.d.ts.map +0 -1
  190. package/dist/functions/_shared/pipeline-runner.d.ts +0 -124
  191. package/dist/functions/_shared/pipeline-runner.d.ts.map +0 -1
  192. package/dist/functions/_shared/principal.d.ts +0 -284
  193. package/dist/functions/_shared/principal.d.ts.map +0 -1
  194. package/dist/functions/_shared/resolve-ids.d.ts +0 -10
  195. package/dist/functions/_shared/resolve-ids.d.ts.map +0 -1
  196. package/dist/functions/_shared/schema-utils.d.ts +0 -181
  197. package/dist/functions/_shared/schema-utils.d.ts.map +0 -1
  198. package/dist/functions/_shared/testing.d.ts +0 -172
  199. package/dist/functions/_shared/testing.d.ts.map +0 -1
  200. package/dist/functions/_shared/trigger-engine.d.ts +0 -140
  201. package/dist/functions/_shared/trigger-engine.d.ts.map +0 -1
  202. package/dist/functions/_shared/webhook-registration.d.ts +0 -81
  203. package/dist/functions/_shared/webhook-registration.d.ts.map +0 -1
  204. package/dist/functions/_shared/webhook-registry.d.ts +0 -41
  205. package/dist/functions/_shared/webhook-registry.d.ts.map +0 -1
  206. package/dist/functions/account-nodes.d.ts +0 -48
  207. package/dist/functions/account-nodes.d.ts.map +0 -1
  208. package/dist/functions/admin-data.d.ts +0 -178
  209. package/dist/functions/admin-data.d.ts.map +0 -1
  210. package/dist/functions/ai-agents.d.ts +0 -125
  211. package/dist/functions/ai-agents.d.ts.map +0 -1
  212. package/dist/functions/api-keys.d.ts +0 -140
  213. package/dist/functions/api-keys.d.ts.map +0 -1
  214. package/dist/functions/apps.d.ts +0 -163
  215. package/dist/functions/apps.d.ts.map +0 -1
  216. package/dist/functions/auth.d.ts +0 -74
  217. package/dist/functions/auth.d.ts.map +0 -1
  218. package/dist/functions/debug-auth.d.ts +0 -33
  219. package/dist/functions/debug-auth.d.ts.map +0 -1
  220. package/dist/functions/embeddings.d.ts +0 -205
  221. package/dist/functions/embeddings.d.ts.map +0 -1
  222. package/dist/functions/handler-registry.d.ts +0 -22
  223. package/dist/functions/handler-registry.d.ts.map +0 -1
  224. package/dist/functions/integration-routes.d.ts +0 -45
  225. package/dist/functions/integration-routes.d.ts.map +0 -1
  226. package/dist/functions/integrations.d.ts +0 -124
  227. package/dist/functions/integrations.d.ts.map +0 -1
  228. package/dist/functions/item-progress.d.ts +0 -41
  229. package/dist/functions/item-progress.d.ts.map +0 -1
  230. package/dist/functions/logs.d.ts +0 -162
  231. package/dist/functions/logs.d.ts.map +0 -1
  232. package/dist/functions/observability.d.ts +0 -123
  233. package/dist/functions/observability.d.ts.map +0 -1
  234. package/dist/functions/pipeline-executions.d.ts +0 -190
  235. package/dist/functions/pipeline-executions.d.ts.map +0 -1
  236. package/dist/functions/pipelines.d.ts +0 -171
  237. package/dist/functions/pipelines.d.ts.map +0 -1
  238. package/dist/functions/prompt-configs.d.ts +0 -125
  239. package/dist/functions/prompt-configs.d.ts.map +0 -1
  240. package/dist/functions/roles.d.ts +0 -118
  241. package/dist/functions/roles.d.ts.map +0 -1
  242. package/dist/functions/signal.d.ts +0 -73
  243. package/dist/functions/signal.d.ts.map +0 -1
  244. package/dist/functions/system-cron.d.ts +0 -65
  245. package/dist/functions/system-cron.d.ts.map +0 -1
  246. package/dist/functions/system.d.ts +0 -29
  247. package/dist/functions/system.d.ts.map +0 -1
  248. package/dist/functions/tests.d.ts +0 -28
  249. package/dist/functions/tests.d.ts.map +0 -1
  250. package/dist/functions/timers.d.ts +0 -139
  251. package/dist/functions/timers.d.ts.map +0 -1
  252. package/dist/functions/triggers.d.ts +0 -203
  253. package/dist/functions/triggers.d.ts.map +0 -1
  254. package/dist/functions/types.d.ts +0 -151
  255. package/dist/functions/types.d.ts.map +0 -1
  256. package/dist/src/types/types.d.ts +0 -364
  257. package/dist/src/types/types.d.ts.map +0 -1
  258. package/index.html +0 -13
  259. package/netlify.toml +0 -36
  260. package/package-project.json +0 -71
  261. package/scripts/ingest-chunks.cjs +0 -202
  262. package/scripts/kb-chunk-parser.cjs +0 -312
  263. package/scripts/kb-chunk-parser.ts +0 -330
  264. package/scripts/load-test-app-install.ts +0 -484
  265. package/scripts/netlify-dev-wrapper.sh +0 -22
  266. package/vitest.config.ts +0 -45
  267. /package/{scripts → .framework/scripts}/app-install-cli.ts +0 -0
  268. /package/{scripts → .framework/scripts}/build-manifest.sh +0 -0
  269. /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