spine-framework 0.3.17 → 0.3.19
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.framework/cli/bin.mjs +16 -0
- package/.framework/cli/commands/create-app.ts +1 -1
- package/.framework/cli/commands/dev.ts +215 -33
- package/.framework/cli/index.ts +37 -75
- package/.framework/functions/_shared/app-manifest.ts +8 -15
- package/.framework/functions/_shared/db.ts +11 -15
- package/.framework/functions/_shared/index.ts +7 -16
- package/.framework/functions/_shared/principal.ts +4 -62
- package/.framework/functions/_shared/resolve-ids.ts +6 -6
- package/.framework/functions/_shared/webhook-registry.ts +43 -1
- package/.framework/functions/admin-funnel.ts +104 -0
- package/.framework/functions/admin-install-funnel.ts +225 -0
- package/.framework/functions/admin-signals.ts +241 -0
- package/.framework/functions/integration-routes.ts +4 -8
- package/.framework/migrations/001_schema.sql +406 -0
- package/.framework/migrations/002_rls_and_functions.sql +710 -0
- package/.framework/migrations/003_system_data.sql +520 -0
- package/.framework/migrations/004_enhancements.sql +43 -0
- package/.framework/public/_redirects +3 -0
- package/.framework/public/spine-logo.jpg +0 -0
- package/.framework/public/spine-logo.svg +3 -0
- package/{scripts → .framework/scripts}/assemble-frontend.sh +8 -5
- package/{scripts → .framework/scripts}/assemble-functions.sh +4 -47
- package/{scripts → .framework/scripts}/assemble.sh +2 -8
- package/{scripts → .framework/scripts}/boundary-check.sh +5 -9
- package/{scripts → .framework/scripts}/check-core-integrity.sh +0 -0
- package/.framework/seeds/link_types/account_cli_instances.json +9 -0
- package/.framework/seeds/types/funnel_signal_use.json +98 -0
- package/.framework/seeds/types/spine_instance.json +109 -0
- package/.framework/src/App.tsx +11 -21
- package/.framework/src/components/CustomAppLoader.tsx +2 -19
- package/.framework/src/components/ui/accordion.tsx +1 -1
- package/.framework/src/components/ui/alert-dialog.tsx +1 -1
- package/.framework/src/components/ui/aspect-ratio.tsx +1 -1
- package/.framework/src/components/ui/avatar.tsx +1 -1
- package/.framework/src/components/ui/badge.tsx +2 -2
- package/.framework/src/components/ui/breadcrumb.tsx +2 -2
- package/.framework/src/components/ui/button-group.tsx +2 -2
- package/.framework/src/components/ui/button.tsx +2 -2
- package/.framework/src/components/ui/chart.tsx +6 -1
- package/.framework/src/components/ui/checkbox.tsx +1 -1
- package/.framework/src/components/ui/collapsible.tsx +1 -1
- package/.framework/src/components/ui/context-menu.tsx +1 -1
- package/.framework/src/components/ui/dialog.tsx +1 -1
- package/.framework/src/components/ui/direction.tsx +17 -1
- package/.framework/src/components/ui/dropdown-menu.tsx +1 -1
- package/.framework/src/components/ui/hover-card.tsx +1 -1
- package/.framework/src/components/ui/item.tsx +2 -2
- package/.framework/src/components/ui/label.tsx +1 -1
- package/.framework/src/components/ui/menubar.tsx +1 -1
- package/.framework/src/components/ui/navigation-menu.tsx +1 -1
- package/.framework/src/components/ui/popover.tsx +1 -1
- package/.framework/src/components/ui/progress.tsx +1 -1
- package/.framework/src/components/ui/radio-group.tsx +1 -1
- package/.framework/src/components/ui/scroll-area.tsx +1 -1
- package/.framework/src/components/ui/select.tsx +1 -1
- package/.framework/src/components/ui/separator.tsx +1 -1
- package/.framework/src/components/ui/sheet.tsx +1 -1
- package/.framework/src/components/ui/sidebar.tsx +6 -6
- package/.framework/src/components/ui/slider.tsx +1 -1
- package/.framework/src/components/ui/switch.tsx +1 -1
- package/.framework/src/components/ui/tabs.tsx +1 -1
- package/.framework/src/components/ui/toggle-group.tsx +1 -1
- package/.framework/src/components/ui/toggle.tsx +1 -1
- package/.framework/src/components/ui/tooltip.tsx +1 -1
- package/.framework/src/pages/auth/LoginPage.tsx +10 -9
- package/LICENSE.md +63 -93
- package/README.md +254 -129
- package/custom/.devin/skills/install-app/SKILL.md +39 -0
- package/custom/.devin/workflows/app-install.yaml +83 -0
- package/custom/README.md +79 -0
- package/docs/APPS.md +232 -0
- package/docs/ARCHITECTURE.md +246 -0
- package/docs/INSTALL.md +155 -0
- package/docs/README.md +170 -0
- package/docs/design-schema-spec.md +1837 -0
- package/docs/dev-guides/01-create-an-app.md +183 -0
- package/docs/dev-guides/02-create-a-function.md +178 -0
- package/docs/dev-guides/03-create-a-component.md +178 -0
- package/docs/dev-guides/04-webhook-handlers.md +129 -0
- package/docs/dev-guides/05-testing.md +168 -0
- package/docs/dev-guides/README.md +40 -0
- package/docs/npm-packages-plan.md +288 -0
- package/docs/spine-core--api-reference.md +822 -0
- package/package.json +79 -150
- package/.framework/cli/bin.cjs +0 -14
- package/.framework/cli/commands/claim.ts +0 -430
- package/.framework/cli/commands/init.ts +0 -219
- package/.framework/cli/commands/install-app.ts +0 -685
- package/.framework/cli/commands/migrate.ts +0 -178
- package/.framework/cli/commands/publish.ts +0 -191
- package/.framework/cli/commands/status.ts +0 -268
- package/.framework/cli/commands/uninstall-app.ts +0 -166
- package/.framework/cli/commands/update-app.ts +0 -397
- package/.framework/cli/welcome.cjs +0 -45
- package/.framework/config/signal-client.ts +0 -147
- package/.framework/config/signals.ts +0 -70
- package/.framework/docs/STABILITY.md +0 -52
- package/.framework/docs/examples/custom-app/README.md +0 -77
- package/.framework/docs/examples/custom-function/README.md +0 -27
- package/.framework/docs/examples/custom-function/handler.ts +0 -48
- package/.framework/docs/examples/custom-webhook/README.md +0 -68
- package/.framework/functions/handler-registry.ts +0 -22
- package/.framework/functions/signal.ts +0 -168
- package/.framework/migrations/000_foundation.sql +0 -1302
- package/.framework/migrations/001_seed.sql +0 -163
- package/.framework/migrations/002_seed_constraints.sql +0 -19
- package/.framework/migrations/003_auth_user_trigger.sql +0 -67
- package/.framework/migrations/004_app_version_tracking.sql +0 -8
- package/.framework/migrations/005_pipelines_slug_stages.sql +0 -21
- package/.framework/src/pages/auth/RegisterPage.tsx +0 -163
- package/CHANGELOG.md +0 -71
- package/STRUCTURE.md +0 -150
- package/bin/spine-framework.cjs +0 -62
- package/bin/welcome.cjs +0 -58
- package/bin/ws-shim.ts +0 -10
- package/config/components.json +0 -25
- package/config/deno.lock +0 -108
- package/config/package-lock.json +0 -17183
- package/config/postcss.config.cjs +0 -10
- package/config/tailwind.config.cjs +0 -78
- package/config/tsconfig.build.json +0 -32
- package/config/tsconfig.cli.json +0 -18
- package/config/tsconfig.json +0 -41
- package/config/tsconfig.node.json +0 -17
- package/config/tsconfig.node.tsbuildinfo +0 -1
- package/config/tsconfig.tsbuildinfo +0 -1
- package/config/typedoc.json +0 -16
- package/config/vite.config.d.ts +0 -2
- package/config/vite.config.ts +0 -71
- package/dist/cli/commands/agents.d.ts +0 -39
- package/dist/cli/commands/agents.d.ts.map +0 -1
- package/dist/cli/commands/auth.d.ts +0 -36
- package/dist/cli/commands/auth.d.ts.map +0 -1
- package/dist/cli/commands/claim.d.ts +0 -38
- package/dist/cli/commands/claim.d.ts.map +0 -1
- package/dist/cli/commands/create-app.d.ts +0 -23
- package/dist/cli/commands/create-app.d.ts.map +0 -1
- package/dist/cli/commands/dev.d.ts +0 -24
- package/dist/cli/commands/dev.d.ts.map +0 -1
- package/dist/cli/commands/doctor.d.ts +0 -42
- package/dist/cli/commands/doctor.d.ts.map +0 -1
- package/dist/cli/commands/generate.d.ts +0 -36
- package/dist/cli/commands/generate.d.ts.map +0 -1
- package/dist/cli/commands/init.d.ts +0 -20
- package/dist/cli/commands/init.d.ts.map +0 -1
- package/dist/cli/commands/install-app.d.ts +0 -30
- package/dist/cli/commands/install-app.d.ts.map +0 -1
- package/dist/cli/commands/items.d.ts +0 -45
- package/dist/cli/commands/items.d.ts.map +0 -1
- package/dist/cli/commands/migrate.d.ts +0 -21
- package/dist/cli/commands/migrate.d.ts.map +0 -1
- package/dist/cli/commands/migrations.d.ts +0 -41
- package/dist/cli/commands/migrations.d.ts.map +0 -1
- package/dist/cli/commands/pipelines.d.ts +0 -40
- package/dist/cli/commands/pipelines.d.ts.map +0 -1
- package/dist/cli/commands/publish.d.ts +0 -23
- package/dist/cli/commands/publish.d.ts.map +0 -1
- package/dist/cli/commands/status.d.ts +0 -23
- package/dist/cli/commands/status.d.ts.map +0 -1
- package/dist/cli/commands/system.d.ts +0 -29
- package/dist/cli/commands/system.d.ts.map +0 -1
- package/dist/cli/commands/test.d.ts +0 -46
- package/dist/cli/commands/test.d.ts.map +0 -1
- package/dist/cli/commands/uninstall-app.d.ts +0 -23
- package/dist/cli/commands/uninstall-app.d.ts.map +0 -1
- package/dist/cli/commands/update-app.d.ts +0 -24
- package/dist/cli/commands/update-app.d.ts.map +0 -1
- package/dist/cli/context.d.ts +0 -88
- package/dist/cli/context.d.ts.map +0 -1
- package/dist/cli/env-loader.d.ts +0 -14
- package/dist/cli/env-loader.d.ts.map +0 -1
- package/dist/cli/index.d.ts +0 -44
- package/dist/cli/index.d.ts.map +0 -1
- package/dist/config/signals.d.ts +0 -82
- package/dist/config/signals.d.ts.map +0 -1
- package/dist/functions/_shared/agent-runner.d.ts +0 -156
- package/dist/functions/_shared/agent-runner.d.ts.map +0 -1
- package/dist/functions/_shared/app-manifest.d.ts +0 -68
- package/dist/functions/_shared/app-manifest.d.ts.map +0 -1
- package/dist/functions/_shared/audit.d.ts +0 -91
- package/dist/functions/_shared/audit.d.ts.map +0 -1
- package/dist/functions/_shared/db.d.ts +0 -125
- package/dist/functions/_shared/db.d.ts.map +0 -1
- package/dist/functions/_shared/index.d.ts +0 -299
- package/dist/functions/_shared/index.d.ts.map +0 -1
- package/dist/functions/_shared/middleware.d.ts +0 -315
- package/dist/functions/_shared/middleware.d.ts.map +0 -1
- package/dist/functions/_shared/permissions.d.ts +0 -626
- package/dist/functions/_shared/permissions.d.ts.map +0 -1
- package/dist/functions/_shared/pipeline-runner.d.ts +0 -124
- package/dist/functions/_shared/pipeline-runner.d.ts.map +0 -1
- package/dist/functions/_shared/principal.d.ts +0 -284
- package/dist/functions/_shared/principal.d.ts.map +0 -1
- package/dist/functions/_shared/resolve-ids.d.ts +0 -10
- package/dist/functions/_shared/resolve-ids.d.ts.map +0 -1
- package/dist/functions/_shared/schema-utils.d.ts +0 -181
- package/dist/functions/_shared/schema-utils.d.ts.map +0 -1
- package/dist/functions/_shared/testing.d.ts +0 -172
- package/dist/functions/_shared/testing.d.ts.map +0 -1
- package/dist/functions/_shared/trigger-engine.d.ts +0 -140
- package/dist/functions/_shared/trigger-engine.d.ts.map +0 -1
- package/dist/functions/_shared/webhook-registration.d.ts +0 -81
- package/dist/functions/_shared/webhook-registration.d.ts.map +0 -1
- package/dist/functions/_shared/webhook-registry.d.ts +0 -41
- package/dist/functions/_shared/webhook-registry.d.ts.map +0 -1
- package/dist/functions/account-nodes.d.ts +0 -48
- package/dist/functions/account-nodes.d.ts.map +0 -1
- package/dist/functions/admin-data.d.ts +0 -178
- package/dist/functions/admin-data.d.ts.map +0 -1
- package/dist/functions/ai-agents.d.ts +0 -125
- package/dist/functions/ai-agents.d.ts.map +0 -1
- package/dist/functions/api-keys.d.ts +0 -140
- package/dist/functions/api-keys.d.ts.map +0 -1
- package/dist/functions/apps.d.ts +0 -163
- package/dist/functions/apps.d.ts.map +0 -1
- package/dist/functions/auth.d.ts +0 -74
- package/dist/functions/auth.d.ts.map +0 -1
- package/dist/functions/debug-auth.d.ts +0 -33
- package/dist/functions/debug-auth.d.ts.map +0 -1
- package/dist/functions/embeddings.d.ts +0 -205
- package/dist/functions/embeddings.d.ts.map +0 -1
- package/dist/functions/handler-registry.d.ts +0 -22
- package/dist/functions/handler-registry.d.ts.map +0 -1
- package/dist/functions/integration-routes.d.ts +0 -45
- package/dist/functions/integration-routes.d.ts.map +0 -1
- package/dist/functions/integrations.d.ts +0 -124
- package/dist/functions/integrations.d.ts.map +0 -1
- package/dist/functions/item-progress.d.ts +0 -41
- package/dist/functions/item-progress.d.ts.map +0 -1
- package/dist/functions/logs.d.ts +0 -162
- package/dist/functions/logs.d.ts.map +0 -1
- package/dist/functions/observability.d.ts +0 -123
- package/dist/functions/observability.d.ts.map +0 -1
- package/dist/functions/pipeline-executions.d.ts +0 -190
- package/dist/functions/pipeline-executions.d.ts.map +0 -1
- package/dist/functions/pipelines.d.ts +0 -171
- package/dist/functions/pipelines.d.ts.map +0 -1
- package/dist/functions/prompt-configs.d.ts +0 -125
- package/dist/functions/prompt-configs.d.ts.map +0 -1
- package/dist/functions/roles.d.ts +0 -118
- package/dist/functions/roles.d.ts.map +0 -1
- package/dist/functions/signal.d.ts +0 -73
- package/dist/functions/signal.d.ts.map +0 -1
- package/dist/functions/system-cron.d.ts +0 -65
- package/dist/functions/system-cron.d.ts.map +0 -1
- package/dist/functions/system.d.ts +0 -29
- package/dist/functions/system.d.ts.map +0 -1
- package/dist/functions/tests.d.ts +0 -28
- package/dist/functions/tests.d.ts.map +0 -1
- package/dist/functions/timers.d.ts +0 -139
- package/dist/functions/timers.d.ts.map +0 -1
- package/dist/functions/triggers.d.ts +0 -203
- package/dist/functions/triggers.d.ts.map +0 -1
- package/dist/functions/types.d.ts +0 -151
- package/dist/functions/types.d.ts.map +0 -1
- package/dist/src/types/types.d.ts +0 -364
- package/dist/src/types/types.d.ts.map +0 -1
- package/index.html +0 -13
- package/netlify.toml +0 -36
- package/package-project.json +0 -71
- package/scripts/ingest-chunks.cjs +0 -202
- package/scripts/kb-chunk-parser.cjs +0 -312
- package/scripts/kb-chunk-parser.ts +0 -330
- package/scripts/load-test-app-install.ts +0 -484
- package/scripts/netlify-dev-wrapper.sh +0 -22
- package/vitest.config.ts +0 -45
- /package/{scripts → .framework/scripts}/app-install-cli.ts +0 -0
- /package/{scripts → .framework/scripts}/build-manifest.sh +0 -0
- /package/{scripts → .framework/scripts}/verify-integrity.sh +0 -0
package/docs/APPS.md
ADDED
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
# Spine Framework App Development
|
|
2
|
+
|
|
3
|
+
Apps are the primary way to extend Spine Framework functionality. This guide covers creating, installing, and managing apps.
|
|
4
|
+
|
|
5
|
+
## What is an App?
|
|
6
|
+
|
|
7
|
+
An app in Spine Framework is:
|
|
8
|
+
- A self-contained feature module
|
|
9
|
+
- Has its own types, roles, and permissions
|
|
10
|
+
- Can define pages, components, and API endpoints
|
|
11
|
+
- Installs into `custom/apps/<app-slug>/`
|
|
12
|
+
|
|
13
|
+
## App Structure
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
custom/apps/my-app/
|
|
17
|
+
├── index.tsx # Entry point & routes
|
|
18
|
+
├── manifest.json # App configuration
|
|
19
|
+
├── seed/
|
|
20
|
+
│ ├── types.json # Custom types
|
|
21
|
+
│ ├── roles.json # Custom roles
|
|
22
|
+
│ └── link-types.json # Link definitions
|
|
23
|
+
├── pages/
|
|
24
|
+
│ ├── Dashboard.tsx
|
|
25
|
+
│ └── Settings.tsx
|
|
26
|
+
├── components/
|
|
27
|
+
│ └── MyComponent.tsx
|
|
28
|
+
├── api/
|
|
29
|
+
│ └── handlers.ts
|
|
30
|
+
├── hooks/
|
|
31
|
+
│ └── useMyData.ts
|
|
32
|
+
└── README.md
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## manifest.json
|
|
36
|
+
|
|
37
|
+
The manifest defines your app's metadata and configuration:
|
|
38
|
+
|
|
39
|
+
```json
|
|
40
|
+
{
|
|
41
|
+
"slug": "my-app",
|
|
42
|
+
"name": "My App",
|
|
43
|
+
"description": "What this app does",
|
|
44
|
+
"version": "1.0.0",
|
|
45
|
+
"icon": "app-icon",
|
|
46
|
+
"color": "#3B82F6",
|
|
47
|
+
"route_prefix": "/my-app",
|
|
48
|
+
"renderer": "generic",
|
|
49
|
+
"min_role": "member",
|
|
50
|
+
"nav_items": [
|
|
51
|
+
{
|
|
52
|
+
"label": "Dashboard",
|
|
53
|
+
"path": "/my-app",
|
|
54
|
+
"icon": "layout-dashboard"
|
|
55
|
+
}
|
|
56
|
+
]
|
|
57
|
+
}
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Renderer Types
|
|
61
|
+
|
|
62
|
+
- `generic` - Uses framework's generic app shell
|
|
63
|
+
- `custom` - Full custom rendering (you control everything)
|
|
64
|
+
- `none` - No UI (backend-only app)
|
|
65
|
+
|
|
66
|
+
## Creating an App
|
|
67
|
+
|
|
68
|
+
### 1. Scaffold the App
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx spine-cli app:create my-app
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### 2. Define Types
|
|
75
|
+
|
|
76
|
+
Edit `seed/types.json`:
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
[
|
|
80
|
+
{
|
|
81
|
+
"kind": "item",
|
|
82
|
+
"slug": "my_entity",
|
|
83
|
+
"name": "My Entity",
|
|
84
|
+
"description": "Custom entity for my app",
|
|
85
|
+
"icon": "box",
|
|
86
|
+
"color": "#3B82F6",
|
|
87
|
+
"ownership": "tenant",
|
|
88
|
+
"is_active": true,
|
|
89
|
+
"design_schema": {
|
|
90
|
+
"scope": "account",
|
|
91
|
+
"fields": {
|
|
92
|
+
"title": {
|
|
93
|
+
"label": "Title",
|
|
94
|
+
"required": true,
|
|
95
|
+
"data_type": "text",
|
|
96
|
+
"permissions": {
|
|
97
|
+
"system_admin": ["read", "write"],
|
|
98
|
+
"member": ["read"]
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
},
|
|
102
|
+
"record_permissions": {
|
|
103
|
+
"member": ["read"],
|
|
104
|
+
"system_admin": ["create", "read", "update", "delete"]
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 3. Create Pages
|
|
112
|
+
|
|
113
|
+
```tsx
|
|
114
|
+
// pages/Dashboard.tsx
|
|
115
|
+
import { useItems } from '../../../.framework/src/hooks/useItems'
|
|
116
|
+
|
|
117
|
+
export function Dashboard() {
|
|
118
|
+
const { items, loading } = useItems('my_entity')
|
|
119
|
+
|
|
120
|
+
if (loading) return <div>Loading...</div>
|
|
121
|
+
|
|
122
|
+
return (
|
|
123
|
+
<div>
|
|
124
|
+
<h1>My Entities</h1>
|
|
125
|
+
{items.map(item => (
|
|
126
|
+
<div key={item.id}>{item.data.title}</div>
|
|
127
|
+
))}
|
|
128
|
+
</div>
|
|
129
|
+
)
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 4. Wire Up Routes
|
|
134
|
+
|
|
135
|
+
```tsx
|
|
136
|
+
// index.tsx
|
|
137
|
+
import { Routes, Route } from 'react-router-dom'
|
|
138
|
+
import { Dashboard } from './pages/Dashboard'
|
|
139
|
+
|
|
140
|
+
export default function MyApp() {
|
|
141
|
+
return (
|
|
142
|
+
<Routes>
|
|
143
|
+
<Route path="/" element={<Dashboard />} />
|
|
144
|
+
</Routes>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### 5. Install & Test
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
# The CLI automatically installs to custom/apps/
|
|
153
|
+
npx spine-cli app:install ./my-app
|
|
154
|
+
|
|
155
|
+
# Apply seed data
|
|
156
|
+
npx spine-cli seed --app=my-app
|
|
157
|
+
|
|
158
|
+
# Restart dev server
|
|
159
|
+
npm run dev
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Publishing Apps
|
|
163
|
+
|
|
164
|
+
### Prepare for npm
|
|
165
|
+
|
|
166
|
+
1. Update `package.json`:
|
|
167
|
+
|
|
168
|
+
```json
|
|
169
|
+
{
|
|
170
|
+
"name": "spine-framework-my-app",
|
|
171
|
+
"version": "1.0.0",
|
|
172
|
+
"files": [
|
|
173
|
+
"index.tsx",
|
|
174
|
+
"manifest.json",
|
|
175
|
+
"seed/",
|
|
176
|
+
"pages/",
|
|
177
|
+
"components/"
|
|
178
|
+
],
|
|
179
|
+
"peerDependencies": {
|
|
180
|
+
"spine-framework": ">=0.1.0"
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
2. Build and test:
|
|
186
|
+
|
|
187
|
+
```bash
|
|
188
|
+
npm run build
|
|
189
|
+
npm run test
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
3. Publish:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
npm publish --tag next
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## App Installation API
|
|
199
|
+
|
|
200
|
+
Programmatically install apps:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { installApp } from 'spine-framework/cli'
|
|
204
|
+
|
|
205
|
+
await installApp({
|
|
206
|
+
source: 'npm', // or 'local', 'git'
|
|
207
|
+
name: 'spine-framework-portal',
|
|
208
|
+
targetDir: './custom/apps/portal'
|
|
209
|
+
})
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Best Practices
|
|
213
|
+
|
|
214
|
+
### Do:
|
|
215
|
+
- Keep apps self-contained
|
|
216
|
+
- Use semantic versioning
|
|
217
|
+
- Document your types and roles
|
|
218
|
+
- Provide sensible defaults
|
|
219
|
+
|
|
220
|
+
### Don't:
|
|
221
|
+
- Modify framework core tables
|
|
222
|
+
- Hardcode IDs or slugs that might conflict
|
|
223
|
+
- Skip the manifest.json
|
|
224
|
+
- Forget to handle errors gracefully
|
|
225
|
+
|
|
226
|
+
## Example Apps
|
|
227
|
+
|
|
228
|
+
- **portal** - Customer portal with courses, community, support
|
|
229
|
+
- **cortex** - AI-powered CRM, support, knowledge base
|
|
230
|
+
- **marketplace** - Extension marketplace for apps
|
|
231
|
+
|
|
232
|
+
See `custom/apps/` for reference implementations.
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Spine Framework Architecture
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Spine Framework is a modular, multi-tenant application platform built on:
|
|
6
|
+
- **Frontend**: React + TypeScript + Tailwind CSS
|
|
7
|
+
- **Backend**: Supabase (PostgreSQL + Auth + Realtime)
|
|
8
|
+
- **Edge**: Netlify/Vercel Edge Functions
|
|
9
|
+
- **Extension**: Custom workspace pattern
|
|
10
|
+
|
|
11
|
+
## Core Principles
|
|
12
|
+
|
|
13
|
+
1. **Framework-Agnostic Core** - Base platform knows nothing of specific apps
|
|
14
|
+
2. **App-Defined Data** - Types, roles, and schemas are defined by apps
|
|
15
|
+
3. **Custom Workspace** - Extensions live in `custom/` without modifying core
|
|
16
|
+
4. **RLS-First Security** - Row Level Security enforces all permissions
|
|
17
|
+
|
|
18
|
+
## System Layers
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
┌─────────────────────────────────────────────────────────────┐
|
|
22
|
+
│ CUSTOM WORKSPACE │
|
|
23
|
+
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
|
|
24
|
+
│ │ Apps │ │Components│ │Functions │ │Migrations│ │
|
|
25
|
+
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
|
|
26
|
+
│ (Your code - safe to modify) │
|
|
27
|
+
├─────────────────────────────────────────────────────────────┤
|
|
28
|
+
│ SPINE FRAMEWORK │
|
|
29
|
+
│ ┌─────────────────────────────────────────────────────┐ │
|
|
30
|
+
│ │ React + React Router │ │
|
|
31
|
+
│ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │
|
|
32
|
+
│ │ │ App Router │ │ Auth │ │ API │ │ │
|
|
33
|
+
│ │ └────────────┘ └────────────┘ └────────────┘ │ │
|
|
34
|
+
│ └─────────────────────────────────────────────────────┘ │
|
|
35
|
+
│ (Read-only - never modify) │
|
|
36
|
+
├─────────────────────────────────────────────────────────────┤
|
|
37
|
+
│ SUPABASE PLATFORM │
|
|
38
|
+
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
|
|
39
|
+
│ │ PostgreSQL │ │ Auth │ │ Realtime │ │
|
|
40
|
+
│ └────────────┘ └────────────┘ └────────────┘ │
|
|
41
|
+
│ (RLS policies enforce security) │
|
|
42
|
+
└─────────────────────────────────────────────────────────────┘
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Database Schema
|
|
46
|
+
|
|
47
|
+
### Core Entities (spine-core)
|
|
48
|
+
|
|
49
|
+
| Entity | Purpose | Scope |
|
|
50
|
+
|--------|---------|-------|
|
|
51
|
+
| `accounts` | Multi-tenant organizations | platform |
|
|
52
|
+
| `people` | Users across accounts | platform |
|
|
53
|
+
| `items` | Typed records (deals, tickets, posts) | account |
|
|
54
|
+
| `threads` | Conversation threads | account |
|
|
55
|
+
| `messages` | Individual messages | account |
|
|
56
|
+
| `links` | Relationships between items | account |
|
|
57
|
+
| `attachments` | File attachments | account |
|
|
58
|
+
| `watchers` | Subscription/notification | account |
|
|
59
|
+
|
|
60
|
+
### Metadata Entities
|
|
61
|
+
|
|
62
|
+
| Entity | Purpose |
|
|
63
|
+
|--------|---------|
|
|
64
|
+
| `types` | Type definitions (item, account, link) |
|
|
65
|
+
| `apps` | Installed apps registry |
|
|
66
|
+
| `roles` | Role definitions and permissions |
|
|
67
|
+
| `app_installations` | Per-account app instances |
|
|
68
|
+
|
|
69
|
+
## Runtime Type System
|
|
70
|
+
|
|
71
|
+
Types are stored in `types` table with JSON design schemas:
|
|
72
|
+
|
|
73
|
+
```typescript
|
|
74
|
+
interface Type {
|
|
75
|
+
slug: string // Unique identifier
|
|
76
|
+
kind: 'item' | 'account' | 'link'
|
|
77
|
+
ownership: 'system' | 'tenant' | 'platform'
|
|
78
|
+
design_schema: {
|
|
79
|
+
scope: 'account' | 'platform' | 'system'
|
|
80
|
+
fields: Record<string, FieldDef>
|
|
81
|
+
record_permissions: Record<Role, Permission[]>
|
|
82
|
+
views: Record<string, ViewConfig>
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Fields are defined with:
|
|
88
|
+
- Data type (text, number, boolean, select, date, datetime, json, textarea)
|
|
89
|
+
- Validation rules
|
|
90
|
+
- Permissions per role
|
|
91
|
+
- UI configuration
|
|
92
|
+
|
|
93
|
+
## App System
|
|
94
|
+
|
|
95
|
+
Apps are runtime-loaded modules:
|
|
96
|
+
|
|
97
|
+
### Registration
|
|
98
|
+
1. App manifest stored in `apps` table
|
|
99
|
+
2. Seed data in `custom/apps/<slug>/seed/`
|
|
100
|
+
3. Code in `custom/apps/<slug>/` (pages, components, hooks)
|
|
101
|
+
|
|
102
|
+
### Loading
|
|
103
|
+
1. Framework queries `apps` table on boot
|
|
104
|
+
2. Dynamic imports for `renderer='custom'` apps
|
|
105
|
+
3. Generic shell for `renderer='generic'` apps
|
|
106
|
+
|
|
107
|
+
### Routing
|
|
108
|
+
- Apps define `route_prefix` in manifest
|
|
109
|
+
- Framework's AppRouter generates routes dynamically
|
|
110
|
+
- First app becomes default redirect (`/` → first app)
|
|
111
|
+
|
|
112
|
+
## Security Model
|
|
113
|
+
|
|
114
|
+
### RLS (Row Level Security)
|
|
115
|
+
|
|
116
|
+
Every table has RLS policies checking:
|
|
117
|
+
|
|
118
|
+
```sql
|
|
119
|
+
-- Example: items table
|
|
120
|
+
CREATE POLICY item_access ON items
|
|
121
|
+
FOR ALL USING (
|
|
122
|
+
-- System admin: full access
|
|
123
|
+
auth.role() = 'system_admin'
|
|
124
|
+
OR
|
|
125
|
+
-- Account member: account-scoped access
|
|
126
|
+
(account_id IN (
|
|
127
|
+
SELECT account_id FROM public.memberships
|
|
128
|
+
WHERE person_id = auth.uid()
|
|
129
|
+
))
|
|
130
|
+
);
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Permission Hierarchy
|
|
134
|
+
|
|
135
|
+
```
|
|
136
|
+
system_admin → Full system access
|
|
137
|
+
↓
|
|
138
|
+
support → Cross-account support role
|
|
139
|
+
↓
|
|
140
|
+
member → Standard user (account-scoped)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Field-Level Permissions
|
|
144
|
+
|
|
145
|
+
```json
|
|
146
|
+
{
|
|
147
|
+
"sensitive_field": {
|
|
148
|
+
"permissions": {
|
|
149
|
+
"system_admin": ["read", "write"],
|
|
150
|
+
"support": ["read"],
|
|
151
|
+
"member": []
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
## Extension Points
|
|
158
|
+
|
|
159
|
+
### Custom Apps
|
|
160
|
+
Add to `custom/apps/<name>/`:
|
|
161
|
+
- `index.tsx` - Entry point
|
|
162
|
+
- `manifest.json` - Configuration
|
|
163
|
+
- `seed/` - Types, roles, link-types
|
|
164
|
+
- `pages/`, `components/`, `hooks/`
|
|
165
|
+
|
|
166
|
+
### Custom Functions
|
|
167
|
+
Add to `custom/functions/`:
|
|
168
|
+
- Edge functions for API endpoints
|
|
169
|
+
- Webhook handlers
|
|
170
|
+
- Background jobs
|
|
171
|
+
|
|
172
|
+
### Custom Migrations
|
|
173
|
+
Add to `custom/migrations/`:
|
|
174
|
+
- Database schema changes
|
|
175
|
+
- Migration numbers continue from framework
|
|
176
|
+
|
|
177
|
+
## Data Flow
|
|
178
|
+
|
|
179
|
+
### Write Path
|
|
180
|
+
1. UI calls `apiFetch()` with item data
|
|
181
|
+
2. Edge function validates against type schema
|
|
182
|
+
3. Supabase inserts with RLS check
|
|
183
|
+
4. Realtime broadcasts change
|
|
184
|
+
5. UI updates via subscription
|
|
185
|
+
|
|
186
|
+
### Read Path
|
|
187
|
+
1. UI calls `useItems(type)` hook
|
|
188
|
+
2. Hook subscribes to realtime changes
|
|
189
|
+
3. Initial fetch with account_id filter
|
|
190
|
+
4. RLS ensures only accessible items returned
|
|
191
|
+
|
|
192
|
+
## Build System
|
|
193
|
+
|
|
194
|
+
### Assembly Process
|
|
195
|
+
```
|
|
196
|
+
1. Copy .framework/ → build/
|
|
197
|
+
2. Copy custom/ → build/
|
|
198
|
+
3. Merge app routes
|
|
199
|
+
4. Generate type definitions
|
|
200
|
+
5. Bundle with Vite
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### Why Two-Level .devin?
|
|
204
|
+
|
|
205
|
+
- **Root `.devin/`** - Framework usage (CLI, setup, troubleshooting)
|
|
206
|
+
- **Custom `.devin/`** - Extension workflows (app install, custom functions)
|
|
207
|
+
|
|
208
|
+
This separation keeps framework concerns distinct from extension concerns.
|
|
209
|
+
|
|
210
|
+
## Deployment
|
|
211
|
+
|
|
212
|
+
### Framework Package (npm)
|
|
213
|
+
- `.framework/` - Core code
|
|
214
|
+
- `docs/` - Documentation
|
|
215
|
+
- `README.md` - Getting started
|
|
216
|
+
|
|
217
|
+
### App Packages (npm)
|
|
218
|
+
- `seed/` - Configuration data
|
|
219
|
+
- `index.tsx` - Entry point
|
|
220
|
+
- `manifest.json` - Metadata
|
|
221
|
+
|
|
222
|
+
### Custom Workspace (project)
|
|
223
|
+
- `custom/` - Project-specific code
|
|
224
|
+
- `.env` - Environment config
|
|
225
|
+
- `supabase/` - Database config
|
|
226
|
+
|
|
227
|
+
## Performance
|
|
228
|
+
|
|
229
|
+
### Optimizations
|
|
230
|
+
- Lazy-loaded app bundles
|
|
231
|
+
- Realtime subscriptions (no polling)
|
|
232
|
+
- Pre-computed aggregations in `item_aggregations`
|
|
233
|
+
- Funnel intelligence with materialized views
|
|
234
|
+
|
|
235
|
+
### Scaling Considerations
|
|
236
|
+
- Tenant-scoped queries use account_id indexes
|
|
237
|
+
- RLS policies add ~5% query overhead
|
|
238
|
+
- Edge functions cache auth tokens
|
|
239
|
+
- Connection pooling via Supabase
|
|
240
|
+
|
|
241
|
+
## Further Reading
|
|
242
|
+
|
|
243
|
+
- [Installation Guide](INSTALL.md)
|
|
244
|
+
- [App Development](APPS.md)
|
|
245
|
+
- [API Reference](spine-core--api-reference.md)
|
|
246
|
+
- [Developer Guides](dev-guides/)
|
package/docs/INSTALL.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Spine Framework Installation Guide
|
|
2
|
+
|
|
3
|
+
## Quick Start
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
# 1. Create a new project directory
|
|
7
|
+
mkdir my-spine-app && cd my-spine-app
|
|
8
|
+
|
|
9
|
+
# 2. Install the framework
|
|
10
|
+
npm install spine-framework@next
|
|
11
|
+
|
|
12
|
+
# 3. Initialize the project
|
|
13
|
+
npx spine-cli init
|
|
14
|
+
|
|
15
|
+
# 4. Start development
|
|
16
|
+
npm run dev
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Prerequisites
|
|
20
|
+
|
|
21
|
+
- Node.js 18+ and npm
|
|
22
|
+
- PostgreSQL 14+ (local or hosted)
|
|
23
|
+
- Supabase account (for hosted database/auth)
|
|
24
|
+
|
|
25
|
+
## Installation Methods
|
|
26
|
+
|
|
27
|
+
### Method 1: npm init (Recommended)
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm init spine-framework@next
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This interactive wizard will:
|
|
34
|
+
- Set up the project structure
|
|
35
|
+
- Configure environment variables
|
|
36
|
+
- Install default apps (optional)
|
|
37
|
+
|
|
38
|
+
### Method 2: Manual Setup
|
|
39
|
+
|
|
40
|
+
1. **Install the framework package:**
|
|
41
|
+
```bash
|
|
42
|
+
npm install spine-framework@next
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
2. **Copy framework files:**
|
|
46
|
+
```bash
|
|
47
|
+
cp -r node_modules/spine-framework/.framework ./.framework
|
|
48
|
+
cp -r node_modules/spine-framework/custom ./custom
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
3. **Configure environment:**
|
|
52
|
+
```bash
|
|
53
|
+
cp .framework/.env.example .env
|
|
54
|
+
# Edit .env with your Supabase credentials
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
4. **Apply database migrations:**
|
|
58
|
+
```bash
|
|
59
|
+
npx spine-cli db:migrate
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
5. **Start development:**
|
|
63
|
+
```bash
|
|
64
|
+
npm run dev
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Installing Apps
|
|
68
|
+
|
|
69
|
+
### Install from npm
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm install spine-framework-portal@next
|
|
73
|
+
npx spine-cli app:install portal
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Install from local package
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
npx spine-cli app:install ./custom/npm/my-app
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Configuration
|
|
83
|
+
|
|
84
|
+
### Environment Variables
|
|
85
|
+
|
|
86
|
+
| Variable | Description | Required |
|
|
87
|
+
|----------|-------------|----------|
|
|
88
|
+
| `VITE_SUPABASE_URL` | Supabase project URL | Yes |
|
|
89
|
+
| `VITE_SUPABASE_ANON_KEY` | Supabase anon key | Yes |
|
|
90
|
+
| `VITE_SUPABASE_SERVICE_ROLE_KEY` | Service role key | For admin ops |
|
|
91
|
+
| `VITE_API_BASE_URL` | Edge functions URL | Yes |
|
|
92
|
+
|
|
93
|
+
### Database Setup
|
|
94
|
+
|
|
95
|
+
1. Create a Supabase project
|
|
96
|
+
2. Run migrations: `npx spine-cli db:migrate`
|
|
97
|
+
3. Apply seed data: `npx spine-cli db:seed`
|
|
98
|
+
|
|
99
|
+
## Project Structure
|
|
100
|
+
|
|
101
|
+
```
|
|
102
|
+
my-spine-app/
|
|
103
|
+
├── .framework/ # Framework code (read-only)
|
|
104
|
+
│ ├── src/
|
|
105
|
+
│ ├── migrations/
|
|
106
|
+
│ └── scripts/
|
|
107
|
+
├── custom/ # Your custom code
|
|
108
|
+
│ ├── apps/
|
|
109
|
+
│ ├── components/
|
|
110
|
+
│ ├── functions/
|
|
111
|
+
│ └── migrations/
|
|
112
|
+
├── docs/ # Documentation
|
|
113
|
+
├── supabase/ # Supabase config
|
|
114
|
+
├── .env # Environment variables
|
|
115
|
+
└── package.json
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Verification
|
|
119
|
+
|
|
120
|
+
After installation, verify everything works:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Check CLI
|
|
124
|
+
npx spine-cli --version
|
|
125
|
+
|
|
126
|
+
# Check database connection
|
|
127
|
+
npx spine-cli db:status
|
|
128
|
+
|
|
129
|
+
# Run health check
|
|
130
|
+
npm run health-check
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Troubleshooting
|
|
134
|
+
|
|
135
|
+
### Database Connection Issues
|
|
136
|
+
|
|
137
|
+
- Verify `VITE_SUPABASE_URL` is correct
|
|
138
|
+
- Check that migrations have been applied
|
|
139
|
+
- Ensure RLS policies are enabled
|
|
140
|
+
|
|
141
|
+
### Build Errors
|
|
142
|
+
|
|
143
|
+
- Clear `node_modules` and reinstall
|
|
144
|
+
- Run `npm run build:clean` to reset build cache
|
|
145
|
+
|
|
146
|
+
### App Installation Failures
|
|
147
|
+
|
|
148
|
+
- Check that the app package is compatible
|
|
149
|
+
- Verify no conflicting route prefixes exist
|
|
150
|
+
|
|
151
|
+
## Next Steps
|
|
152
|
+
|
|
153
|
+
- [Create your first app](dev-guides/01-create-an-app.md)
|
|
154
|
+
- [Read the architecture overview](ARCHITECTURE.md)
|
|
155
|
+
- [Explore the API reference](spine-core--api-reference.md)
|