spine-framework 0.1.61 → 0.2.0

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 (246) 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 -63
  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 +0 -9
  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 +1 -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/migrations/001_schema.sql +406 -0
  14. package/.framework/migrations/002_rls_and_functions.sql +710 -0
  15. package/.framework/migrations/003_system_data.sql +520 -0
  16. package/.framework/migrations/004_enhancements.sql +43 -0
  17. package/.framework/public/_redirects +3 -0
  18. package/.framework/public/spine-logo.jpg +0 -0
  19. package/.framework/public/spine-logo.svg +3 -0
  20. package/{scripts → .framework/scripts}/assemble-frontend.sh +1 -1
  21. package/{scripts → .framework/scripts}/assemble-functions.sh +1 -1
  22. package/{scripts → .framework/scripts}/assemble.sh +2 -8
  23. package/{scripts → .framework/scripts}/check-core-integrity.sh +0 -0
  24. package/.framework/seeds/link_types/account_cli_instances.json +9 -0
  25. package/.framework/seeds/types/funnel_signal_use.json +98 -0
  26. package/.framework/seeds/types/spine_instance.json +109 -0
  27. package/.framework/src/App.tsx +6 -4
  28. package/.framework/src/components/ui/accordion.tsx +1 -1
  29. package/.framework/src/components/ui/alert-dialog.tsx +1 -1
  30. package/.framework/src/components/ui/aspect-ratio.tsx +1 -1
  31. package/.framework/src/components/ui/avatar.tsx +1 -1
  32. package/.framework/src/components/ui/badge.tsx +2 -2
  33. package/.framework/src/components/ui/breadcrumb.tsx +2 -2
  34. package/.framework/src/components/ui/button-group.tsx +2 -2
  35. package/.framework/src/components/ui/button.tsx +2 -2
  36. package/.framework/src/components/ui/chart.tsx +6 -1
  37. package/.framework/src/components/ui/checkbox.tsx +1 -1
  38. package/.framework/src/components/ui/collapsible.tsx +1 -1
  39. package/.framework/src/components/ui/context-menu.tsx +1 -1
  40. package/.framework/src/components/ui/dialog.tsx +1 -1
  41. package/.framework/src/components/ui/direction.tsx +17 -1
  42. package/.framework/src/components/ui/dropdown-menu.tsx +1 -1
  43. package/.framework/src/components/ui/hover-card.tsx +1 -1
  44. package/.framework/src/components/ui/item.tsx +2 -2
  45. package/.framework/src/components/ui/label.tsx +1 -1
  46. package/.framework/src/components/ui/menubar.tsx +1 -1
  47. package/.framework/src/components/ui/navigation-menu.tsx +1 -1
  48. package/.framework/src/components/ui/popover.tsx +1 -1
  49. package/.framework/src/components/ui/progress.tsx +1 -1
  50. package/.framework/src/components/ui/radio-group.tsx +1 -1
  51. package/.framework/src/components/ui/scroll-area.tsx +1 -1
  52. package/.framework/src/components/ui/select.tsx +1 -1
  53. package/.framework/src/components/ui/separator.tsx +1 -1
  54. package/.framework/src/components/ui/sheet.tsx +1 -1
  55. package/.framework/src/components/ui/sidebar.tsx +6 -6
  56. package/.framework/src/components/ui/slider.tsx +1 -1
  57. package/.framework/src/components/ui/switch.tsx +1 -1
  58. package/.framework/src/components/ui/tabs.tsx +1 -1
  59. package/.framework/src/components/ui/toggle-group.tsx +1 -1
  60. package/.framework/src/components/ui/toggle.tsx +1 -1
  61. package/.framework/src/components/ui/tooltip.tsx +1 -1
  62. package/.framework/src/pages/auth/LoginPage.tsx +10 -9
  63. package/LICENSE.md +193 -0
  64. package/README.md +254 -0
  65. package/custom/.devin/skills/install-app/SKILL.md +39 -0
  66. package/custom/.devin/workflows/app-install.yaml +83 -0
  67. package/custom/README.md +79 -0
  68. package/docs/APPS.md +232 -0
  69. package/docs/ARCHITECTURE.md +246 -0
  70. package/docs/INSTALL.md +155 -0
  71. package/docs/README.md +170 -0
  72. package/docs/design-schema-spec.md +1837 -0
  73. package/docs/dev-guides/01-create-an-app.md +183 -0
  74. package/docs/dev-guides/02-create-a-function.md +178 -0
  75. package/docs/dev-guides/03-create-a-component.md +178 -0
  76. package/docs/dev-guides/04-webhook-handlers.md +129 -0
  77. package/docs/dev-guides/05-testing.md +168 -0
  78. package/docs/dev-guides/README.md +40 -0
  79. package/docs/npm-packages-plan.md +288 -0
  80. package/docs/spine-core--api-reference.md +822 -0
  81. package/package.json +78 -144
  82. package/.framework/cli/bin.cjs +0 -14
  83. package/.framework/cli/commands/init.ts +0 -186
  84. package/.framework/cli/commands/install-app.ts +0 -565
  85. package/.framework/cli/commands/migrate.ts +0 -139
  86. package/.framework/cli/commands/status.ts +0 -197
  87. package/.framework/cli/commands/uninstall-app.ts +0 -166
  88. package/.framework/cli/welcome.cjs +0 -45
  89. package/.framework/docs/STABILITY.md +0 -52
  90. package/.framework/docs/examples/custom-app/README.md +0 -77
  91. package/.framework/docs/examples/custom-function/README.md +0 -27
  92. package/.framework/docs/examples/custom-function/handler.ts +0 -48
  93. package/.framework/docs/examples/custom-webhook/README.md +0 -68
  94. package/.framework/migrations/000_foundation.sql +0 -1266
  95. package/.framework/migrations/001_seed.sql +0 -163
  96. package/.framework/migrations/002_seed_constraints.sql +0 -19
  97. package/.framework/migrations/003_auth_user_trigger.sql +0 -67
  98. package/.framework/src/pages/auth/RegisterPage.tsx +0 -163
  99. package/STRUCTURE.md +0 -150
  100. package/bin/spine-framework.cjs +0 -62
  101. package/bin/welcome.cjs +0 -45
  102. package/bin/ws-shim.cjs +0 -8
  103. package/bin/ws-shim.ts +0 -10
  104. package/config/components.json +0 -25
  105. package/config/deno.lock +0 -108
  106. package/config/package-lock.json +0 -17183
  107. package/config/postcss.config.cjs +0 -10
  108. package/config/tailwind.config.cjs +0 -78
  109. package/config/tsconfig.build.json +0 -32
  110. package/config/tsconfig.cli.json +0 -18
  111. package/config/tsconfig.json +0 -41
  112. package/config/tsconfig.node.json +0 -17
  113. package/config/tsconfig.node.tsbuildinfo +0 -1
  114. package/config/tsconfig.tsbuildinfo +0 -1
  115. package/config/typedoc.json +0 -16
  116. package/config/vite.config.d.ts +0 -2
  117. package/config/vite.config.ts +0 -72
  118. package/dist/cli/commands/agents.d.ts +0 -39
  119. package/dist/cli/commands/agents.d.ts.map +0 -1
  120. package/dist/cli/commands/auth.d.ts +0 -36
  121. package/dist/cli/commands/auth.d.ts.map +0 -1
  122. package/dist/cli/commands/create-app.d.ts +0 -23
  123. package/dist/cli/commands/create-app.d.ts.map +0 -1
  124. package/dist/cli/commands/dev.d.ts +0 -24
  125. package/dist/cli/commands/dev.d.ts.map +0 -1
  126. package/dist/cli/commands/doctor.d.ts +0 -42
  127. package/dist/cli/commands/doctor.d.ts.map +0 -1
  128. package/dist/cli/commands/generate.d.ts +0 -36
  129. package/dist/cli/commands/generate.d.ts.map +0 -1
  130. package/dist/cli/commands/init.d.ts +0 -20
  131. package/dist/cli/commands/init.d.ts.map +0 -1
  132. package/dist/cli/commands/install-app.d.ts +0 -30
  133. package/dist/cli/commands/install-app.d.ts.map +0 -1
  134. package/dist/cli/commands/items.d.ts +0 -45
  135. package/dist/cli/commands/items.d.ts.map +0 -1
  136. package/dist/cli/commands/migrate.d.ts +0 -21
  137. package/dist/cli/commands/migrate.d.ts.map +0 -1
  138. package/dist/cli/commands/migrations.d.ts +0 -41
  139. package/dist/cli/commands/migrations.d.ts.map +0 -1
  140. package/dist/cli/commands/pipelines.d.ts +0 -40
  141. package/dist/cli/commands/pipelines.d.ts.map +0 -1
  142. package/dist/cli/commands/status.d.ts +0 -23
  143. package/dist/cli/commands/status.d.ts.map +0 -1
  144. package/dist/cli/commands/system.d.ts +0 -29
  145. package/dist/cli/commands/system.d.ts.map +0 -1
  146. package/dist/cli/commands/test.d.ts +0 -46
  147. package/dist/cli/commands/test.d.ts.map +0 -1
  148. package/dist/cli/commands/uninstall-app.d.ts +0 -23
  149. package/dist/cli/commands/uninstall-app.d.ts.map +0 -1
  150. package/dist/cli/context.d.ts +0 -88
  151. package/dist/cli/context.d.ts.map +0 -1
  152. package/dist/cli/env-loader.d.ts +0 -14
  153. package/dist/cli/env-loader.d.ts.map +0 -1
  154. package/dist/cli/index.d.ts +0 -41
  155. package/dist/cli/index.d.ts.map +0 -1
  156. package/dist/functions/_shared/agent-runner.d.ts +0 -156
  157. package/dist/functions/_shared/agent-runner.d.ts.map +0 -1
  158. package/dist/functions/_shared/app-manifest.d.ts +0 -68
  159. package/dist/functions/_shared/app-manifest.d.ts.map +0 -1
  160. package/dist/functions/_shared/audit.d.ts +0 -91
  161. package/dist/functions/_shared/audit.d.ts.map +0 -1
  162. package/dist/functions/_shared/db.d.ts +0 -125
  163. package/dist/functions/_shared/db.d.ts.map +0 -1
  164. package/dist/functions/_shared/index.d.ts +0 -299
  165. package/dist/functions/_shared/index.d.ts.map +0 -1
  166. package/dist/functions/_shared/middleware.d.ts +0 -315
  167. package/dist/functions/_shared/middleware.d.ts.map +0 -1
  168. package/dist/functions/_shared/permissions.d.ts +0 -626
  169. package/dist/functions/_shared/permissions.d.ts.map +0 -1
  170. package/dist/functions/_shared/pipeline-runner.d.ts +0 -124
  171. package/dist/functions/_shared/pipeline-runner.d.ts.map +0 -1
  172. package/dist/functions/_shared/principal.d.ts +0 -284
  173. package/dist/functions/_shared/principal.d.ts.map +0 -1
  174. package/dist/functions/_shared/resolve-ids.d.ts +0 -10
  175. package/dist/functions/_shared/resolve-ids.d.ts.map +0 -1
  176. package/dist/functions/_shared/schema-utils.d.ts +0 -181
  177. package/dist/functions/_shared/schema-utils.d.ts.map +0 -1
  178. package/dist/functions/_shared/testing.d.ts +0 -172
  179. package/dist/functions/_shared/testing.d.ts.map +0 -1
  180. package/dist/functions/_shared/trigger-engine.d.ts +0 -140
  181. package/dist/functions/_shared/trigger-engine.d.ts.map +0 -1
  182. package/dist/functions/_shared/webhook-registration.d.ts +0 -81
  183. package/dist/functions/_shared/webhook-registration.d.ts.map +0 -1
  184. package/dist/functions/_shared/webhook-registry.d.ts +0 -57
  185. package/dist/functions/_shared/webhook-registry.d.ts.map +0 -1
  186. package/dist/functions/account-nodes.d.ts +0 -48
  187. package/dist/functions/account-nodes.d.ts.map +0 -1
  188. package/dist/functions/admin-data.d.ts +0 -178
  189. package/dist/functions/admin-data.d.ts.map +0 -1
  190. package/dist/functions/ai-agents.d.ts +0 -125
  191. package/dist/functions/ai-agents.d.ts.map +0 -1
  192. package/dist/functions/api-keys.d.ts +0 -140
  193. package/dist/functions/api-keys.d.ts.map +0 -1
  194. package/dist/functions/apps.d.ts +0 -163
  195. package/dist/functions/apps.d.ts.map +0 -1
  196. package/dist/functions/auth.d.ts +0 -74
  197. package/dist/functions/auth.d.ts.map +0 -1
  198. package/dist/functions/debug-auth.d.ts +0 -33
  199. package/dist/functions/debug-auth.d.ts.map +0 -1
  200. package/dist/functions/embeddings.d.ts +0 -205
  201. package/dist/functions/embeddings.d.ts.map +0 -1
  202. package/dist/functions/integration-routes.d.ts +0 -45
  203. package/dist/functions/integration-routes.d.ts.map +0 -1
  204. package/dist/functions/integrations.d.ts +0 -124
  205. package/dist/functions/integrations.d.ts.map +0 -1
  206. package/dist/functions/item-progress.d.ts +0 -41
  207. package/dist/functions/item-progress.d.ts.map +0 -1
  208. package/dist/functions/logs.d.ts +0 -162
  209. package/dist/functions/logs.d.ts.map +0 -1
  210. package/dist/functions/observability.d.ts +0 -123
  211. package/dist/functions/observability.d.ts.map +0 -1
  212. package/dist/functions/pipeline-executions.d.ts +0 -190
  213. package/dist/functions/pipeline-executions.d.ts.map +0 -1
  214. package/dist/functions/pipelines.d.ts +0 -171
  215. package/dist/functions/pipelines.d.ts.map +0 -1
  216. package/dist/functions/prompt-configs.d.ts +0 -125
  217. package/dist/functions/prompt-configs.d.ts.map +0 -1
  218. package/dist/functions/roles.d.ts +0 -118
  219. package/dist/functions/roles.d.ts.map +0 -1
  220. package/dist/functions/system-cron.d.ts +0 -65
  221. package/dist/functions/system-cron.d.ts.map +0 -1
  222. package/dist/functions/system.d.ts +0 -29
  223. package/dist/functions/system.d.ts.map +0 -1
  224. package/dist/functions/tests.d.ts +0 -28
  225. package/dist/functions/tests.d.ts.map +0 -1
  226. package/dist/functions/timers.d.ts +0 -139
  227. package/dist/functions/timers.d.ts.map +0 -1
  228. package/dist/functions/triggers.d.ts +0 -203
  229. package/dist/functions/triggers.d.ts.map +0 -1
  230. package/dist/functions/types.d.ts +0 -151
  231. package/dist/functions/types.d.ts.map +0 -1
  232. package/dist/src/types/types.d.ts +0 -364
  233. package/dist/src/types/types.d.ts.map +0 -1
  234. package/index.html +0 -13
  235. package/netlify.toml +0 -36
  236. package/package-project.json +0 -64
  237. package/scripts/ingest-chunks.cjs +0 -202
  238. package/scripts/kb-chunk-parser.cjs +0 -312
  239. package/scripts/kb-chunk-parser.ts +0 -330
  240. package/scripts/load-test-app-install.ts +0 -484
  241. package/scripts/netlify-dev-wrapper.sh +0 -22
  242. package/vitest.config.ts +0 -45
  243. /package/{scripts → .framework/scripts}/app-install-cli.ts +0 -0
  244. /package/{scripts → .framework/scripts}/boundary-check.sh +0 -0
  245. /package/{scripts → .framework/scripts}/build-manifest.sh +0 -0
  246. /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,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/STRUCTURE.md DELETED
@@ -1,150 +0,0 @@
1
- # Spine Enterprise Directory Structure
2
-
3
- This document explains the directory layout for the Spine framework.
4
-
5
- ## Overview
6
-
7
- ```
8
- my-app/
9
- ├── .framework/ # 🔒 CLI-managed framework code (read-only)
10
- ├── custom/ # ✏️ Developer workspace (your code)
11
- ├── .assembled/ # 🏗️ Build output (gitignored)
12
- ├── config/ # ⚙️ Build tool configuration
13
- ├── scripts/ # 🔧 Build automation
14
- ├── archive/ # 📦 Historical artifacts
15
- ├── docs/ # 📚 Documentation
16
- ├── netlify.toml # 🌐 Netlify configuration (must be at root)
17
- ├── package.json # Root package manifest
18
- └── STRUCTURE.md # This file
19
- ```
20
-
21
- ## Directory Details
22
-
23
- ### `.framework/` — Framework Core (Hidden)
24
- **Managed by:** Spine CLI (read-only)
25
- **Contains:**
26
- - `functions/` — Core Netlify function handlers
27
- - `src/` — Core React components (Admin shell, app router)
28
- - `migrations/` — Base database schema
29
- - `cli/` — Framework CLI tools
30
- - `tests/` — Core test suites
31
-
32
- **You should not edit files here.** The CLI manages updates to this directory.
33
-
34
- ### `custom/` — Developer Workspace
35
- **Managed by:** You
36
- **Contains:**
37
- - `functions/` — Your custom Netlify function handlers
38
- - `apps/` — Your applications (one folder per app)
39
- - `components/` — Shared UI components across your apps
40
- - `migrations/` — Your database schema changes
41
- - `tests/` — Your test suites
42
-
43
- **This is where you build your product.** Everything here is yours.
44
-
45
- ### `.assembled/` — Build Output (Hidden, Gitignored)
46
- **Generated by:** Assembly scripts
47
- **Contains:**
48
- - `netlify/functions/` — Merged: `.framework/functions` + `custom/functions`
49
- - `src/` — Merged: `.framework/src` + `custom/apps/*`
50
-
51
- **Never edit files here.** This is rebuilt on every `netlify dev` or deployment.
52
-
53
- ### `config/` — Build Tool Configuration
54
- **Contains:**
55
- - `vite.config.ts` — Vite build configuration
56
- - `tsconfig.json` — TypeScript configuration
57
- - `tailwind.config.ts` — Styling configuration
58
- - `postcss.config.js` — CSS processing
59
-
60
- ### `netlify.toml` — Netlify Configuration (Root)
61
- **Must be at project root** (Netlify CLI requirement)
62
- - Functions path: `.assembled/netlify/functions/`
63
- - Dev server settings: port 3001 (Vite) → 8888 (Netlify proxy)
64
-
65
- ### `scripts/` — Build Automation
66
- **Contains:**
67
- - Assembly scripts that merge `.framework/` + `custom/` → `.assembled/`
68
- - Verification scripts for integrity checking
69
-
70
- ### `archive/` — Historical Artifacts
71
- **Contains:**
72
- - Old audit documents
73
- - Completed project reports
74
- - Test artifacts
75
-
76
- ## Assembly Flow
77
-
78
- ```bash
79
- Development:
80
- .framework/ + custom/ ──► scripts/assemble.sh ──► .assembled/
81
- ──► netlify dev
82
-
83
- Production:
84
- .framework/ + custom/ ──► scripts/assemble.sh ──► .assembled/
85
- ──► Netlify deploy
86
- ```
87
-
88
- ## Path Aliases
89
-
90
- After assembly, code uses these aliases:
91
- - `@core` → `.framework/src/`
92
- - `@custom` → `custom/apps/`
93
-
94
- ## Adding New Code
95
-
96
- ### New App
97
- ```bash
98
- mkdir custom/apps/my-app
99
- cd custom/apps/my-app
100
- # Create src/, components/, pages/
101
- ```
102
-
103
- ### New Function
104
- ```bash
105
- touch custom/functions/my-handler.ts
106
- # Edit with your logic
107
- ```
108
-
109
- ### New Migration
110
- ```bash
111
- touch custom/migrations/101_my_change.sql
112
- # Write ALTER TABLE statements
113
- ```
114
-
115
- ## Updating Framework
116
-
117
- ```bash
118
- spine-framework update
119
- # CLI updates .framework/ to latest version
120
- # Your custom/ code is untouched
121
- ```
122
-
123
- ## Important Rules
124
-
125
- 1. **Never edit `.framework/`** — use `custom/` instead
126
- 2. **Never commit `.assembled/`** — it's in `.gitignore`
127
- 3. **Always use assembly** — don't manually copy to `.assembled/`
128
- 4. **Test after update** — run `netlify dev` after `spine-framework update`
129
-
130
- ## Troubleshooting
131
-
132
- ### "Where do I put X?"
133
- - Framework extension → `.framework/` (via CLI or PR)
134
- - Custom business logic → `custom/`
135
- - App-specific code → `custom/apps/{app-name}/`
136
-
137
- ### "Assembly failed"
138
- 1. Check both `.framework/` and `custom/` exist
139
- 2. Verify no duplicate function names
140
- 3. Run `scripts/assemble.sh` manually for error details
141
-
142
- ### "Functions not found"
143
- 1. Check `.assembled/netlify/functions/` exists
144
- 2. Verify `netlify.toml` (in project root) points to correct path
145
- 3. Ensure assembly ran without errors
146
-
147
- ### "Netlify dev can't connect"
148
- 1. Check Vite is running on port 3001
149
- 2. Verify `netlify.toml` is in project root (not config/)
150
- 3. Check `targetPort = 3001` in netlify.toml [dev] section