spine-framework 0.3.144 → 0.4.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.
- package/.env.example +76 -0
- package/.framework/.spine-manifest.json +19 -0
- package/.framework/cli/commands/agents.ts +61 -33
- package/.framework/cli/commands/auth.ts +60 -28
- package/.framework/cli/commands/create-app.ts +212 -80
- package/.framework/cli/commands/dev.ts +184 -68
- package/.framework/cli/commands/doctor.ts +324 -152
- package/.framework/cli/commands/generate.ts +119 -68
- package/.framework/cli/commands/init.ts +141 -242
- package/.framework/cli/commands/install-app.ts +1336 -314
- package/.framework/cli/commands/items.ts +31 -29
- package/.framework/cli/commands/migrate.ts +299 -156
- package/.framework/cli/commands/migrations.ts +62 -30
- package/.framework/cli/commands/pipelines.ts +31 -29
- package/.framework/cli/commands/status.ts +105 -45
- package/.framework/cli/commands/system.ts +47 -42
- package/.framework/cli/commands/test.ts +161 -102
- package/.framework/cli/commands/upgrade.ts +260 -0
- package/.framework/cli/commands/validate-app.ts +517 -161
- package/.framework/cli/context.ts +117 -85
- package/.framework/cli/env-loader.ts +74 -43
- package/.framework/cli/index.ts +70 -46
- package/.framework/cli/lib/project-files.ts +404 -0
- package/.framework/docs/guides/testing-guide.md +1 -1
- package/.framework/docs/runtime-types.md +72 -72
- package/.framework/functions/_shared/access.ts +84 -0
- package/.framework/functions/_shared/agent-runner.ts +5051 -1026
- package/.framework/functions/_shared/app-manifest.ts +214 -94
- package/.framework/functions/_shared/ast.ts +214 -0
- package/.framework/functions/_shared/audit.ts +91 -55
- package/.framework/functions/_shared/cil.ts +368 -127
- package/.framework/functions/_shared/db.ts +337 -68
- package/.framework/functions/_shared/funnel.ts +228 -0
- package/.framework/functions/_shared/geo.ts +105 -0
- package/.framework/functions/_shared/hash-api-key.ts +94 -17
- package/.framework/functions/_shared/index.ts +22 -224
- package/.framework/functions/_shared/kb.ts +832 -58
- package/.framework/functions/_shared/llm.ts +118 -18
- package/.framework/functions/_shared/logging.ts +317 -19
- package/.framework/functions/_shared/middleware.ts +701 -131
- package/.framework/functions/_shared/notify.ts +70 -0
- package/.framework/functions/_shared/outcomes.ts +34 -19
- package/.framework/functions/_shared/permissions.ts +501 -315
- package/.framework/functions/_shared/pipeline-runner.ts +704 -155
- package/.framework/functions/_shared/principal.ts +436 -263
- package/.framework/functions/_shared/rate-limit.ts +233 -0
- package/.framework/functions/_shared/resolve-credentials.ts +86 -19
- package/.framework/functions/_shared/resolve-ids.ts +203 -139
- package/.framework/functions/_shared/retry-deliveries.ts +51 -16
- package/.framework/functions/_shared/schema-utils.ts +602 -521
- package/.framework/functions/_shared/security.ts +345 -0
- package/.framework/functions/_shared/testing.ts +197 -172
- package/.framework/functions/_shared/tracing.ts +351 -21
- package/.framework/functions/_shared/trigger-engine.ts +425 -136
- package/.framework/functions/_shared/webhook-registration.ts +71 -70
- package/.framework/functions/_shared/webhook-registry.ts +126 -83
- package/.framework/functions/account-nodes.ts +30 -30
- package/.framework/functions/adapters/generic-webhook-inbound.ts +49 -16
- package/.framework/functions/adapters/generic-webhook-outbound.ts +17 -17
- package/.framework/functions/adapters/openai-outbound.ts +15 -16
- package/.framework/functions/admin-data.ts +596 -173
- package/.framework/functions/admin-funnel.ts +64 -60
- package/.framework/functions/admin-install-funnel.ts +84 -66
- package/.framework/functions/admin-signals.ts +69 -51
- package/.framework/functions/ai-agents.ts +431 -106
- package/.framework/functions/ai-interactions.ts +186 -112
- package/.framework/functions/api-keys.ts +107 -107
- package/.framework/functions/apps.ts +154 -136
- package/.framework/functions/auth.ts +83 -65
- package/.framework/functions/cil-agent-ingest.ts +189 -232
- package/.framework/functions/cil-agent.ts +433 -177
- package/.framework/functions/cil-callmap.ts +642 -430
- package/.framework/functions/cil-config.ts +139 -135
- package/.framework/functions/cil-context.ts +214 -127
- package/.framework/functions/cil-doc.ts +587 -458
- package/.framework/functions/cil-embeddings.ts +453 -364
- package/.framework/functions/cil-graph.ts +427 -142
- package/.framework/functions/cil-ingest.ts +1418 -1154
- package/.framework/functions/cil-pipeline.ts +276 -21
- package/.framework/functions/cil-project.ts +659 -132
- package/.framework/functions/cil-validate.ts +198 -164
- package/.framework/functions/debug-auth.ts +57 -55
- package/.framework/functions/deliveries.ts +80 -21
- package/.framework/functions/embeddings.ts +1023 -318
- package/.framework/functions/eval-harness.ts +146 -108
- package/.framework/functions/integration-outbound.ts +205 -75
- package/.framework/functions/integration-routes.ts +128 -23
- package/.framework/functions/integrations.ts +125 -100
- package/.framework/functions/invites.ts +1095 -460
- package/.framework/functions/item-progress.ts +158 -102
- package/.framework/functions/kb.ts +34 -10
- package/.framework/functions/logs.ts +133 -133
- package/.framework/functions/observability.ts +152 -122
- package/.framework/functions/pipeline-executions.ts +147 -132
- package/.framework/functions/pipelines.ts +134 -119
- package/.framework/functions/prompt-configs.ts +96 -80
- package/.framework/functions/roles.ts +112 -82
- package/.framework/functions/security.ts +450 -0
- package/.framework/functions/system-cron.ts +117 -80
- package/.framework/functions/system.ts +158 -98
- package/.framework/functions/tests.ts +29 -29
- package/.framework/functions/timers.ts +94 -95
- package/.framework/functions/trigger-scheduler.ts +10 -0
- package/.framework/functions/triggers.ts +179 -149
- package/.framework/functions/types.ts +137 -125
- package/.framework/mcp/index.ts +133 -0
- package/.framework/mcp/load-env.ts +60 -0
- package/.framework/mcp/shared/app-manifest.ts +275 -0
- package/.framework/mcp/shared/db.ts +477 -0
- package/.framework/mcp/shared/kb.ts +118 -0
- package/.framework/mcp/tools/architect.ts +431 -0
- package/.framework/mcp/tools/cil/context.ts +345 -0
- package/.framework/mcp/tools/cil/graph.ts +242 -0
- package/.framework/mcp/tools/cil/ingest.ts +1217 -0
- package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +693 -0
- package/.framework/mcp/tools/cil/pipeline.ts +767 -0
- package/.framework/mcp/tools/cil/project.ts +791 -0
- package/.framework/mcp/tools/cil/retrieval.ts +336 -0
- package/.framework/mcp/tools/cil/search-core.ts +454 -0
- package/.framework/mcp/tools/cil/search.ts +97 -0
- package/.framework/mcp/tools/cil/suggest.ts +186 -0
- package/.framework/mcp/tools/cil/validate.ts +1369 -0
- package/.framework/mcp/tools/kb/delete.ts +139 -0
- package/.framework/mcp/tools/kb/index.ts +52 -0
- package/.framework/mcp/tools/kb/ingest.ts +84 -0
- package/.framework/mcp/tools/kb/list-types.ts +102 -0
- package/.framework/mcp/tools/kb/publish.ts +100 -0
- package/.framework/mcp/tools/kb/reindex.ts +86 -0
- package/.framework/mcp/tools/kb/revoke.ts +85 -0
- package/.framework/mcp/tools/kb/search.ts +101 -0
- package/.framework/mcp/tools/kb/upsert.ts +125 -0
- package/.framework/mcp/tools/observability.ts +510 -0
- package/.framework/migrations/001_core_schema.sql +15 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +15 -0
- package/.framework/migrations/003_core_system_data.sql +16 -1
- package/.framework/migrations/004_core_rpc_and_broker.sql +17 -1
- package/.framework/migrations/005_core_observability.sql +17 -1
- package/.framework/migrations/006_security_hardening_rls.sql +15 -0
- package/.framework/migrations/007_kb_article_list.sql +17 -1
- package/.framework/migrations/008_items_target.sql +15 -0
- package/.framework/migrations/009_roles_slug_unique.sql +15 -0
- package/.framework/migrations/010_auth_user_trigger.sql +15 -0
- package/.framework/migrations/011_spine_system_account.sql +16 -0
- package/.framework/migrations/012_service_role_grants.sql +16 -0
- package/.framework/migrations/013_get_account_apps_role_filter.sql +15 -0
- package/.framework/migrations/014_apps_required_roles.sql +16 -0
- package/.framework/migrations/015_types_kind_slug_unique.sql +20 -0
- package/.framework/migrations/016_cil_types.sql +281 -0
- package/.framework/migrations/017_cil_stable_ids.sql +37 -0
- package/.framework/migrations/018_runtime_tables.sql +129 -0
- package/.framework/migrations/019_agent_prompt_columns.sql +56 -0
- package/.framework/migrations/020_schema_reconciliation.sql +67 -0
- package/.framework/migrations/021_kb_embedding_lifecycle.sql +31 -0
- package/.framework/migrations/032_cil_status_migration.sql +73 -0
- package/.framework/migrations/033_cil_versioning.sql +73 -0
- package/.framework/migrations/034_match_embeddings_knn.sql +115 -0
- package/.framework/migrations/035_rate_limits.sql +55 -0
- package/.framework/migrations/036_demo_record_flags.sql +72 -0
- package/.framework/migrations/037_kb_types_canonical.sql +244 -0
- package/.framework/migrations/038_drop_demo_record_flags.sql +38 -0
- package/.framework/migrations/042_registration_hierarchy.sql +309 -0
- package/.framework/migrations/043_policy_actor_cleanup.sql +39 -0
- package/.framework/migrations/044_match_embeddings_filtered_knn.sql +151 -0
- package/.framework/migrations/045_security_critical_rls.sql +139 -0
- package/.framework/migrations/046_security_missing_rls.sql +79 -0
- package/.framework/migrations/047_people_updated_by.sql +27 -0
- package/.framework/migrations/048_watcher_last_seen_at.sql +24 -0
- package/.framework/migrations/049_security_blocklist.sql +148 -0
- package/.framework/migrations/050_notifications.sql +49 -0
- package/.framework/migrations/051_message_agent_fields.sql +74 -0
- package/.framework/migrations/052_registration_security.sql +421 -0
- package/.framework/migrations/053_builtin_action_seeds.sql +66 -0
- package/.framework/migrations/054_kb_ingest_lease.sql +157 -0
- package/.framework/migrations/055_type_id_drift_reconciliation.sql +33 -0
- package/.framework/migrations/056_slug_column_reconciliation.sql +38 -0
- package/.framework/migrations/057_pipelines_slug_identity.sql +14 -0
- package/.framework/migrations/058_account_data_field_declarations.sql +53 -0
- package/.framework/migrations/059_registration_placement_fixes.sql +269 -0
- package/.framework/migrations/060_account_person_record_permissions.sql +38 -0
- package/.framework/migrations/061_fk_dedup.sql +32 -0
- package/.framework/public/spine-logo.svg +10 -3
- package/.framework/scripts/app-install-cli.ts +190 -93
- package/.framework/scripts/assemble-frontend.sh +127 -44
- package/.framework/scripts/assemble-functions.sh +128 -30
- package/.framework/scripts/boundary-check.sh +6 -2
- package/.framework/scripts/build-manifest.sh +24 -68
- package/.framework/scripts/check-core-integrity.sh +15 -76
- package/.framework/scripts/checksum-manifest.mts +343 -0
- package/.framework/scripts/cil-migrate-markers.ts +403 -0
- package/.framework/scripts/fix-cil-markers.mjs +176 -0
- package/.framework/scripts/verify-integrity.sh +21 -57
- package/.framework/scripts/verify-manifest.mts +305 -0
- package/.framework/seeds/types/funnel_signal_use.json +74 -21
- package/.framework/seeds/types/spine_instance.json +73 -21
- package/.framework/src/App.tsx +118 -72
- package/.framework/src/apps/admin/index.tsx +855 -58
- package/.framework/src/components/AppWrapper.tsx +43 -45
- package/.framework/src/components/CustomAppLoader.tsx +160 -116
- package/.framework/src/components/admin/AdminListPage.tsx +46 -44
- package/.framework/src/components/admin/AdminSidebar.tsx +57 -47
- package/.framework/src/components/admin/AdminStatsCard.tsx +46 -44
- package/.framework/src/components/admin/PageInstructions.tsx +98 -2
- package/.framework/src/components/admin/SortableTableHeader.tsx +44 -45
- package/.framework/src/components/app-shell/GenericAppShell.tsx +64 -65
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +44 -47
- package/.framework/src/components/app-shell/GenericListPage.tsx +45 -49
- package/.framework/src/components/app-sidebar.tsx +42 -45
- package/.framework/src/components/auth/ProtectedRoute.tsx +48 -41
- package/.framework/src/components/auth/TurnstileWidget.tsx +27 -0
- package/.framework/src/components/kb/KBArticleEditor.tsx +231 -22
- package/.framework/src/components/kb/KBArticleList.tsx +251 -10
- package/.framework/src/components/layout/AppShell.tsx +51 -45
- package/.framework/src/components/layout/Header.tsx +42 -43
- package/.framework/src/components/layout/Layout.tsx +46 -46
- package/.framework/src/components/layout/Sidebar.tsx +196 -96
- package/.framework/src/components/runtime/DataDetailHeader.tsx +55 -30
- package/.framework/src/components/runtime/DataDetailPage.tsx +31 -269
- package/.framework/src/components/runtime/DataFilters.tsx +49 -74
- package/.framework/src/components/runtime/DataHeader.tsx +53 -32
- package/.framework/src/components/runtime/DataListPage.tsx +51 -155
- package/.framework/src/components/runtime/DataStats.tsx +66 -44
- package/.framework/src/components/runtime/DataTable.tsx +49 -149
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +45 -75
- package/.framework/src/components/runtime/index.ts +119 -16
- package/.framework/src/components/search-form.tsx +46 -29
- package/.framework/src/components/shared/AgentView.tsx +65 -48
- package/.framework/src/components/shared/FieldRenderer.tsx +144 -50
- package/.framework/src/components/shared/InviteManager.tsx +207 -97
- package/.framework/src/components/shared/MemberList.tsx +97 -0
- package/.framework/src/components/shared/SchemaFields.tsx +107 -86
- package/.framework/src/components/ui/DataTable.tsx +80 -68
- package/.framework/src/components/ui/Form.tsx +157 -146
- package/.framework/src/components/ui/ItemCard.tsx +74 -67
- package/.framework/src/components/ui/ItemListView.tsx +73 -68
- package/.framework/src/components/ui/LoadingSpinner.tsx +43 -48
- package/.framework/src/components/ui/Modal.tsx +78 -68
- package/.framework/src/components/ui/RichTextEditor.tsx +89 -69
- package/.framework/src/components/ui/accordion.tsx +85 -86
- package/.framework/src/components/ui/alert-dialog.tsx +197 -184
- package/.framework/src/components/ui/alert.tsx +105 -94
- package/.framework/src/components/ui/aspect-ratio.tsx +57 -43
- package/.framework/src/components/ui/avatar.tsx +122 -107
- package/.framework/src/components/ui/badge.tsx +60 -55
- package/.framework/src/components/ui/breadcrumb.tsx +127 -128
- package/.framework/src/components/ui/button-group.tsx +86 -72
- package/.framework/src/components/ui/button.tsx +71 -50
- package/.framework/src/components/ui/calendar.tsx +72 -57
- package/.framework/src/components/ui/card.tsx +136 -129
- package/.framework/src/components/ui/carousel.tsx +226 -107
- package/.framework/src/components/ui/chart.tsx +252 -147
- package/.framework/src/components/ui/checkbox.tsx +43 -44
- package/.framework/src/components/ui/collapsible.tsx +86 -71
- package/.framework/src/components/ui/combobox.tsx +282 -249
- package/.framework/src/components/ui/command.tsx +158 -146
- package/.framework/src/components/ui/context-menu.tsx +239 -240
- package/.framework/src/components/ui/dialog.tsx +174 -157
- package/.framework/src/components/ui/direction.tsx +72 -56
- package/.framework/src/components/ui/drawer.tsx +168 -169
- package/.framework/src/components/ui/dropdown-menu.tsx +254 -223
- package/.framework/src/components/ui/empty.tsx +131 -120
- package/.framework/src/components/ui/field.tsx +205 -173
- package/.framework/src/components/ui/hover-card.tsx +71 -72
- package/.framework/src/components/ui/input-group.tsx +148 -133
- package/.framework/src/components/ui/input-otp.tsx +99 -86
- package/.framework/src/components/ui/input.tsx +43 -41
- package/.framework/src/components/ui/item.tsx +207 -185
- package/.framework/src/components/ui/kbd.tsx +57 -56
- package/.framework/src/components/ui/label.tsx +45 -41
- package/.framework/src/components/ui/menubar.tsx +268 -236
- package/.framework/src/components/ui/native-select.tsx +85 -86
- package/.framework/src/components/ui/navigation-menu.tsx +166 -156
- package/.framework/src/components/ui/pagination.tsx +131 -141
- package/.framework/src/components/ui/popover.tsx +125 -128
- package/.framework/src/components/ui/progress.tsx +47 -44
- package/.framework/src/components/ui/radio-group.tsx +60 -55
- package/.framework/src/components/ui/resizable.tsx +85 -72
- package/.framework/src/components/ui/scroll-area.tsx +57 -58
- package/.framework/src/components/ui/select.tsx +182 -169
- package/.framework/src/components/ui/separator.tsx +42 -43
- package/.framework/src/components/ui/sheet.tsx +170 -159
- package/.framework/src/components/ui/sidebar.tsx +395 -398
- package/.framework/src/components/ui/skeleton.tsx +42 -43
- package/.framework/src/components/ui/slider.tsx +61 -44
- package/.framework/src/components/ui/sonner.tsx +44 -44
- package/.framework/src/components/ui/spinner.tsx +47 -42
- package/.framework/src/components/ui/switch.tsx +56 -42
- package/.framework/src/components/ui/table-primitives.tsx +272 -132
- package/.framework/src/components/ui/table.tsx +140 -142
- package/.framework/src/components/ui/tabs.tsx +110 -93
- package/.framework/src/components/ui/textarea.tsx +43 -44
- package/.framework/src/components/ui/toggle-group.tsx +87 -71
- package/.framework/src/components/ui/toggle.tsx +56 -56
- package/.framework/src/components/ui/tooltip.tsx +99 -85
- package/.framework/src/contexts/AppContext.tsx +166 -114
- package/.framework/src/contexts/AuthContext.tsx +232 -137
- package/.framework/src/hooks/use-mobile.ts +43 -44
- package/.framework/src/hooks/useApi.ts +185 -172
- package/.framework/src/hooks/useAppPath.ts +31 -29
- package/.framework/src/hooks/useApps.ts +77 -42
- package/.framework/src/hooks/useEntityList.ts +66 -29
- package/.framework/src/hooks/useEntityRecord.ts +76 -32
- package/.framework/src/hooks/useForm.ts +62 -30
- package/.framework/src/hooks/useListSchema.ts +60 -43
- package/.framework/src/hooks/useSchemaRecord.ts +115 -95
- package/.framework/src/lib/api.ts +258 -134
- package/.framework/src/lib/registration.ts +181 -0
- package/.framework/src/lib/supabase.ts +118 -81
- package/.framework/src/lib/utils.ts +266 -266
- package/.framework/src/main.tsx +43 -44
- package/.framework/src/pages/DashboardPage.tsx +44 -43
- package/.framework/src/pages/NoAppPage.tsx +50 -0
- package/.framework/src/pages/NotFoundPage.tsx +32 -29
- package/.framework/src/pages/SetupPage.tsx +34 -33
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +69 -58
- package/.framework/src/pages/admin/AIAgentsPage.tsx +43 -40
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +63 -55
- package/.framework/src/pages/admin/APIKeysPage.tsx +44 -42
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +117 -94
- package/.framework/src/pages/admin/AppDetailPage.tsx +48 -42
- package/.framework/src/pages/admin/AppsPage.tsx +45 -42
- package/.framework/src/pages/admin/DeliveriesPage.tsx +49 -17
- package/.framework/src/pages/admin/DesignedPage.tsx +31 -30
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +58 -0
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +49 -0
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +46 -29
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -29
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +68 -55
- package/.framework/src/pages/admin/IntegrationsPage.tsx +45 -42
- package/.framework/src/pages/admin/InvitesPage.tsx +60 -44
- package/.framework/src/pages/admin/LogsPage.tsx +87 -137
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +31 -29
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +150 -89
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +77 -104
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +44 -43
- package/.framework/src/pages/admin/PipelinesPage.tsx +59 -145
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +53 -42
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +47 -117
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +31 -44
- package/.framework/src/pages/admin/RoleDetailPage.tsx +49 -92
- package/.framework/src/pages/admin/RolesPage.tsx +47 -164
- package/.framework/src/pages/admin/SecurityPage.tsx +310 -0
- package/.framework/src/pages/admin/SelectTestPage.tsx +30 -32
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +37 -44
- package/.framework/src/pages/admin/SimpleDashboard.tsx +32 -44
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +97 -44
- package/.framework/src/pages/admin/TestingDashboard.tsx +126 -71
- package/.framework/src/pages/admin/TimerDetailPage.tsx +67 -55
- package/.framework/src/pages/admin/TimersPage.tsx +44 -42
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +47 -42
- package/.framework/src/pages/admin/TriggersPage.tsx +58 -57
- package/.framework/src/pages/admin/TypeDetailPage.tsx +91 -55
- package/.framework/src/pages/admin/TypesPage.tsx +45 -42
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +258 -128
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +127 -123
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +308 -235
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +159 -110
- package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +432 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +200 -178
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +286 -239
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +211 -90
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +156 -143
- package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +379 -0
- package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +337 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +219 -214
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +135 -65
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +39 -31
- package/.framework/src/pages/auth/LoginPage.tsx +38 -32
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -28
- package/.framework/src/pages/auth/RegisterPage.tsx +429 -155
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -30
- package/.framework/src/pages/spine-framework/CLIPage.tsx +32 -30
- package/.framework/src/types/auth.ts +101 -93
- package/.framework/src/types/types.ts +283 -262
- package/.framework/templates/project.json +87 -0
- package/.framework/templates/spine.config.neutral.json +7 -0
- package/.framework/tests/api/api-surface.test.ts +381 -0
- package/.framework/tests/fixtures/seed.ts +427 -0
- package/.framework/tests/fixtures/teardown.ts +228 -0
- package/.framework/tests/reporter.ts +351 -0
- package/.framework/tests/setup.ts +135 -0
- package/.framework/tests/ui/ui-sweep.ts +278 -0
- package/.framework/tests/unit/admin-data-logger.test.ts +310 -0
- package/.framework/tests/unit/agent-runner.test.ts +2389 -0
- package/.framework/tests/unit/ai-interactions.test.ts +81 -0
- package/.framework/tests/unit/app-manifest.test.ts +359 -0
- package/.framework/tests/unit/assembly-scripts.test.ts +172 -0
- package/.framework/tests/unit/cil-determinism.test.ts +85 -0
- package/.framework/tests/unit/core-isolation.test.ts +153 -0
- package/.framework/tests/unit/funnel-signals.test.ts +135 -0
- package/.framework/tests/unit/install-app.test.ts +1759 -0
- package/.framework/tests/unit/invites-security.test.ts +572 -0
- package/.framework/tests/unit/kb-ingest-lease.test.ts +287 -0
- package/.framework/tests/unit/kb-search.test.ts +119 -0
- package/.framework/tests/unit/migrate.test.ts +509 -0
- package/.framework/tests/unit/notify.test.ts +136 -0
- package/.framework/tests/unit/permissions.test.ts +269 -0
- package/.framework/tests/unit/pipeline-runner.test.ts +755 -0
- package/.framework/tests/unit/principal-cache.test.ts +138 -0
- package/.framework/tests/unit/retrieval-golden.test.ts +520 -0
- package/.framework/tests/unit/runtime-isolation.test.ts +642 -0
- package/.framework/tests/unit/schema-utils.test.ts +225 -0
- package/.framework/tests/unit/trigger-engine.test.ts +513 -0
- package/.framework/tests/unit/validate-app.test.ts +527 -0
- package/README.md +34 -3
- package/bin/spine-framework.cjs +1 -0
- package/config/tailwind.config.cjs +7 -0
- package/config/tsconfig.functions.json +42 -0
- package/config/tsconfig.json +37 -9
- package/config/vite.config.ts +31 -2
- package/netlify.toml +31 -3
- package/package.json +46 -29
- package/scripts/assemble-frontend.sh +127 -44
- package/scripts/assemble-functions.sh +127 -29
- package/scripts/boundary-check.sh +6 -2
- package/scripts/build-manifest.sh +24 -68
- package/scripts/checksum-manifest.mts +345 -0
- package/scripts/dev-clean.sh +86 -0
- package/scripts/dev-netlify.sh +49 -0
- package/scripts/netlify-dev-wrapper.sh +2 -0
- package/scripts/verify-install.ts +358 -0
- package/scripts/verify-integrity.sh +21 -57
- package/scripts/verify-manifest.mts +305 -0
- package/templates/project/gitignore +45 -0
- package/{config → templates/project}/package-lock.json +22335 -9366
- package/vitest.config.ts +46 -0
- package/.framework/public/spine.config.json +0 -91
- package/config/deno.lock +0 -108
- package/config/tsconfig.node.tsbuildinfo +0 -1
- package/config/tsconfig.tsbuildinfo +0 -1
- package/config/vite.config.d.ts +0 -2
- package/custom/.devin/AGENT.md +0 -357
- package/custom/.devin/skills/install-app/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +0 -39
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +0 -36
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +0 -46
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +0 -28
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +0 -38
- package/custom/.devin/workflows/app-install.yaml +0 -83
- package/custom/README.md +0 -79
- package/docs/README.md +0 -15
- package/scripts/app-install-cli.ts +0 -286
- package/scripts/check-core-integrity.sh +0 -82
- 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/kb-ingest-docs.ts +0 -203
- package/scripts/load-test-app-install.ts +0 -484
- package/scripts/test-login.js +0 -33
- package/spine.config.json +0 -91
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
-- CIL[BEGIN stable_id="~/.framework/migrations/035_rate_limits.sql:rate_limits:file" type="file" identity="rate_limits" parent="~/.framework/migrations/035_rate_limits.sql"]
|
|
2
|
+
-- CIL[DOC-MACRO purpose="DB-backed fixed-window rate limiting primitives"]
|
|
3
|
+
-- CIL[DOC-RESPONSIBILITY responsibility="Provide a rate_limits counter table and an atomic rate_limit_hit RPC used by _shared/rate-limit.ts"]
|
|
4
|
+
-- CIL[DOC-CONTEXT module="migrations" layer="data" related_files=".framework/functions/_shared/rate-limit.ts"]
|
|
5
|
+
-- CIL[DOC-CONTRACT inputs="none" outputs="public.rate_limits table, public.rate_limit_hit function" errors="none" side_effects="Creates table, index, grants"]
|
|
6
|
+
-- CIL[DOC-MICRO logic_summary="Create rate_limits(key, window_start, count) with composite PK; rate_limit_hit upserts and increments the counter atomically inside one statement" notable_decisions="Atomic increment via INSERT ON CONFLICT so concurrent serverless invocations cannot double-spend a window"]
|
|
7
|
+
-- CIL[DOC-STABILITY stability="stable"]
|
|
8
|
+
|
|
9
|
+
-- Rate-limit counters are infrastructure state, not domain records — a plain
|
|
10
|
+
-- table, service-role only. Never readable by tenant principals.
|
|
11
|
+
CREATE TABLE IF NOT EXISTS public.rate_limits (
|
|
12
|
+
key text NOT NULL,
|
|
13
|
+
window_start timestamptz NOT NULL,
|
|
14
|
+
count integer NOT NULL DEFAULT 0,
|
|
15
|
+
updated_at timestamptz NOT NULL DEFAULT now(),
|
|
16
|
+
PRIMARY KEY (key, window_start)
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
ALTER TABLE public.rate_limits ENABLE ROW LEVEL SECURITY;
|
|
20
|
+
|
|
21
|
+
-- No policies: tenant principals get no access. All access is via the
|
|
22
|
+
-- SECURITY DEFINER function below or the service role.
|
|
23
|
+
|
|
24
|
+
-- Atomic hit: inserts or increments the counter for (key, window_start) and
|
|
25
|
+
-- returns the new count. One round-trip, safe under concurrency.
|
|
26
|
+
CREATE OR REPLACE FUNCTION public.rate_limit_hit(p_key text, p_window_start timestamptz)
|
|
27
|
+
RETURNS integer
|
|
28
|
+
LANGUAGE plpgsql
|
|
29
|
+
SECURITY DEFINER
|
|
30
|
+
SET search_path = public
|
|
31
|
+
AS $$
|
|
32
|
+
DECLARE
|
|
33
|
+
v_count integer;
|
|
34
|
+
BEGIN
|
|
35
|
+
INSERT INTO public.rate_limits (key, window_start, count)
|
|
36
|
+
VALUES (p_key, p_window_start, 1)
|
|
37
|
+
ON CONFLICT (key, window_start)
|
|
38
|
+
DO UPDATE SET count = public.rate_limits.count + 1,
|
|
39
|
+
updated_at = now()
|
|
40
|
+
RETURNING count INTO v_count;
|
|
41
|
+
RETURN v_count;
|
|
42
|
+
END;
|
|
43
|
+
$$;
|
|
44
|
+
|
|
45
|
+
REVOKE ALL ON FUNCTION public.rate_limit_hit(text, timestamptz) FROM PUBLIC;
|
|
46
|
+
REVOKE ALL ON FUNCTION public.rate_limit_hit(text, timestamptz) FROM anon;
|
|
47
|
+
REVOKE ALL ON FUNCTION public.rate_limit_hit(text, timestamptz) FROM authenticated;
|
|
48
|
+
GRANT EXECUTE ON FUNCTION public.rate_limit_hit(text, timestamptz) TO service_role;
|
|
49
|
+
-- CIL[DOC-VECTOR type="context" content="purpose='DB-backed fixed-window rate limiting primitives'; No verified external callers; imports: none"]
|
|
50
|
+
-- CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
51
|
+
-- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
52
|
+
-- CIL[DOC-VECTOR type="constraint" content="Table is RLS-enabled with no tenant policies; only the SECURITY DEFINER RPC or service role may touch it"]
|
|
53
|
+
-- CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
54
|
+
-- CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
55
|
+
-- CIL[END stable_id="~/.framework/migrations/035_rate_limits.sql:rate_limits:file"]
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
-- CIL[BEGIN stable_id="~/.framework/migrations/036_demo_record_flags.sql:demo_record_flags:file" type="file" identity="demo_record_flags" parent="~/.framework/migrations/036_demo_record_flags.sql"]
|
|
2
|
+
-- CIL[DOC-MACRO purpose="Auto-stamp data.is_demo / data.demo_run_id on runtime records created under demo accounts"]
|
|
3
|
+
-- CIL[DOC-RESPONSIBILITY responsibility="Provide apply_demo_flag() trigger function and attach it to runtime tables so every write path (admin-data, adminDb, seeds) flags demo-owned records"]
|
|
4
|
+
-- CIL[DOC-CONTEXT module="migrations" layer="data" related_files=".framework/functions/_shared/funnel.ts,.framework/functions/admin-data.ts"]
|
|
5
|
+
-- CIL[DOC-CONTRACT inputs="accounts.data.is_demo + accounts.data.demo_run_id on the row's account" outputs="NEW.data with reserved keys is_demo/demo_run_id set or stripped" errors="none — missing account defaults to non-demo" side_effects="Mutates NEW.data on INSERT/UPDATE"]
|
|
6
|
+
-- CIL[DOC-MICRO logic_summary="BEFORE INSERT OR UPDATE: look up NEW.account_id's account flag; demo accounts get is_demo=true + demo_run_id merged into data, non-demo accounts get the reserved keys stripped so clients cannot forge them" notable_decisions="DB trigger chosen over admin-data stamping so agent-runner/support-triage adminDb writes are flagged identically; strip on non-demo makes the flag unforgeable"]
|
|
7
|
+
-- CIL[DOC-STABILITY stability="stable"]
|
|
8
|
+
|
|
9
|
+
CREATE OR REPLACE FUNCTION public.apply_demo_flag()
|
|
10
|
+
RETURNS trigger
|
|
11
|
+
LANGUAGE plpgsql
|
|
12
|
+
SECURITY DEFINER
|
|
13
|
+
SET search_path = public
|
|
14
|
+
AS $$
|
|
15
|
+
DECLARE
|
|
16
|
+
v_is_demo boolean;
|
|
17
|
+
v_run_id text;
|
|
18
|
+
BEGIN
|
|
19
|
+
-- accounts has no account_id; nothing to derive from.
|
|
20
|
+
IF NEW.account_id IS NULL THEN
|
|
21
|
+
RETURN NEW;
|
|
22
|
+
END IF;
|
|
23
|
+
|
|
24
|
+
SELECT (a.data->>'is_demo')::boolean, a.data->>'demo_run_id'
|
|
25
|
+
INTO v_is_demo, v_run_id
|
|
26
|
+
FROM public.accounts a
|
|
27
|
+
WHERE a.id = NEW.account_id;
|
|
28
|
+
|
|
29
|
+
IF COALESCE(v_is_demo, false) THEN
|
|
30
|
+
NEW.data := COALESCE(NEW.data, '{}'::jsonb)
|
|
31
|
+
|| jsonb_build_object('is_demo', true);
|
|
32
|
+
IF v_run_id IS NOT NULL THEN
|
|
33
|
+
NEW.data := NEW.data || jsonb_build_object('demo_run_id', v_run_id);
|
|
34
|
+
END IF;
|
|
35
|
+
ELSE
|
|
36
|
+
-- Reserved keys are server-owned; strip any client-supplied values.
|
|
37
|
+
NEW.data := COALESCE(NEW.data, '{}'::jsonb) - 'is_demo' - 'demo_run_id';
|
|
38
|
+
END IF;
|
|
39
|
+
|
|
40
|
+
RETURN NEW;
|
|
41
|
+
END;
|
|
42
|
+
$$;
|
|
43
|
+
|
|
44
|
+
-- Attach to every runtime entity that carries an account_id + data payload.
|
|
45
|
+
DO $$
|
|
46
|
+
DECLARE
|
|
47
|
+
t text;
|
|
48
|
+
BEGIN
|
|
49
|
+
FOREACH t IN ARRAY ARRAY['items', 'threads', 'messages', 'links', 'attachments', 'watchers', 'people']
|
|
50
|
+
LOOP
|
|
51
|
+
EXECUTE format('DROP TRIGGER IF EXISTS trg_demo_flag ON public.%I', t);
|
|
52
|
+
EXECUTE format(
|
|
53
|
+
'CREATE TRIGGER trg_demo_flag BEFORE INSERT OR UPDATE ON public.%I FOR EACH ROW EXECUTE FUNCTION public.apply_demo_flag()',
|
|
54
|
+
t
|
|
55
|
+
);
|
|
56
|
+
END LOOP;
|
|
57
|
+
END $$;
|
|
58
|
+
|
|
59
|
+
-- Backfill: flag existing rows belonging to demo accounts that predate the trigger.
|
|
60
|
+
UPDATE public.items i
|
|
61
|
+
SET data = i.data || jsonb_build_object('is_demo', true)
|
|
62
|
+
FROM public.accounts a
|
|
63
|
+
WHERE i.account_id = a.id
|
|
64
|
+
AND (a.data->>'is_demo')::boolean IS TRUE
|
|
65
|
+
AND COALESCE(i.data->>'is_demo', 'false') <> 'true';
|
|
66
|
+
-- CIL[DOC-VECTOR type="context" content="purpose='Auto-stamp data.is_demo / data.demo_run_id on runtime records created under demo accounts'; No verified external callers; imports: none"]
|
|
67
|
+
-- CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
68
|
+
-- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
69
|
+
-- CIL[DOC-VECTOR type="constraint" content="Reserved keys is_demo/demo_run_id are server-owned on all runtime tables; clients cannot set or clear them"]
|
|
70
|
+
-- CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
71
|
+
-- CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
72
|
+
-- CIL[END stable_id="~/.framework/migrations/036_demo_record_flags.sql:demo_record_flags:file"]
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
-- 037_kb_types_canonical.sql
|
|
2
|
+
-- Canonical knowledge-base item types. kb-account and kb-spine-public were
|
|
3
|
+
-- previously created only by the archived 046_kb_types.sql consolidation, so
|
|
4
|
+
-- fresh installs never received them even though 007_kb_article_list.sql
|
|
5
|
+
-- references both slugs. This migration:
|
|
6
|
+
-- 1. Inserts the types when missing (idempotent).
|
|
7
|
+
-- 2. Merges demo-flag fields (is_demo, demo_run_id) and the member_admin
|
|
8
|
+
-- grant into existing design_schema rows without clobbering them.
|
|
9
|
+
-- 3. Adds source_ticket_id to kb-account for ticket→article candidate links.
|
|
10
|
+
|
|
11
|
+
-- ─── INSERT: kb-account (fresh installs) ────────────────────────────────────
|
|
12
|
+
|
|
13
|
+
INSERT INTO public.types (app_id, kind, slug, name, description, icon, color, design_schema, validation_schema, ownership, is_active)
|
|
14
|
+
VALUES (
|
|
15
|
+
NULL,
|
|
16
|
+
'item',
|
|
17
|
+
'kb-account',
|
|
18
|
+
'KB Account',
|
|
19
|
+
'Account-specific knowledge base articles',
|
|
20
|
+
'briefcase',
|
|
21
|
+
'#3B82F6',
|
|
22
|
+
$DS$
|
|
23
|
+
{
|
|
24
|
+
"scope": "account",
|
|
25
|
+
"fields": {
|
|
26
|
+
"title": { "data_type": "text", "label": "Title", "required": true, "system": true },
|
|
27
|
+
"description": { "data_type": "textarea", "label": "Description", "required": false, "system": true },
|
|
28
|
+
"status": { "data_type": "select", "label": "Status", "required": true, "system": true, "options": ["draft", "published", "archived"] },
|
|
29
|
+
"content": { "data_type": "textarea", "label": "Content", "required": true },
|
|
30
|
+
"tags": { "data_type": "multiselect", "label": "Tags", "required": false, "options": ["support", "how-to", "faq", "tutorial"] },
|
|
31
|
+
"category": { "data_type": "multiselect", "label": "Category", "required": false, "options": ["how-to", "runbook", "policy", "faq", "tutorial"] },
|
|
32
|
+
"product": { "data_type": "multiselect", "label": "Product", "required": false, "options": ["spine-framework", "cortex", "workbench", "portal"] },
|
|
33
|
+
"version": { "data_type": "text", "label": "Version", "required": false },
|
|
34
|
+
"last_reviewed_at": { "data_type": "datetime", "label": "Last Reviewed", "required": false },
|
|
35
|
+
"reviewer_id": { "data_type": "text", "label": "Reviewer ID", "required": false },
|
|
36
|
+
"is_ai_generated": { "data_type": "boolean", "label": "AI Generated", "required": false },
|
|
37
|
+
"customer_segment": { "data_type": "multiselect", "label": "Customer Segment", "required": false, "options": ["enterprise", "startup", "all"] },
|
|
38
|
+
"feature_flag": { "data_type": "text", "label": "Feature Flag", "required": false },
|
|
39
|
+
"work_ticket_id": { "data_type": "text", "label": "Work Ticket ID", "required": false },
|
|
40
|
+
"source_ticket_id": { "data_type": "text", "label": "Source Ticket ID", "required": false },
|
|
41
|
+
"source_file": { "data_type": "text", "label": "Source File Path", "required": false },
|
|
42
|
+
"source_function": { "data_type": "text", "label": "Source Function", "required": false },
|
|
43
|
+
"is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
|
|
44
|
+
"demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false }
|
|
45
|
+
},
|
|
46
|
+
"views": {
|
|
47
|
+
"default_list": {
|
|
48
|
+
"type": "list",
|
|
49
|
+
"display": "table",
|
|
50
|
+
"label": "Account Articles",
|
|
51
|
+
"fields": {
|
|
52
|
+
"title": { "sortable": true, "display_type": "text" },
|
|
53
|
+
"status": { "sortable": true, "display_type": "badge" },
|
|
54
|
+
"product": { "sortable": true, "display_type": "text" },
|
|
55
|
+
"created_at": { "sortable": true, "display_type": "timestamp" }
|
|
56
|
+
},
|
|
57
|
+
"default_sort": { "field": "created_at", "direction": "desc" }
|
|
58
|
+
},
|
|
59
|
+
"default_detail": {
|
|
60
|
+
"type": "detail",
|
|
61
|
+
"label": "Article",
|
|
62
|
+
"sections": [
|
|
63
|
+
{ "title": "Core", "fields": { "title": { "display_type": "input" }, "status": { "display_type": "select" }, "description": { "display_type": "textarea" }, "content": { "display_type": "textarea" } } },
|
|
64
|
+
{ "title": "Categorization", "fields": { "tags": { "display_type": "multiselect" }, "category": { "display_type": "multiselect" }, "product": { "display_type": "multiselect" }, "version": { "display_type": "text" } } },
|
|
65
|
+
{ "title": "Review", "fields": { "last_reviewed_at": { "display_type": "timestamp" }, "reviewer_id": { "display_type": "text" }, "is_ai_generated": { "display_type": "checkbox" } } },
|
|
66
|
+
{ "title": "Context", "fields": { "work_ticket_id": { "display_type": "text" }, "source_ticket_id": { "display_type": "text" }, "source_file": { "display_type": "text" }, "source_function": { "display_type": "text" } } }
|
|
67
|
+
]
|
|
68
|
+
}
|
|
69
|
+
},
|
|
70
|
+
"record_permissions": {
|
|
71
|
+
"system_admin": ["create", "read", "update", "delete"],
|
|
72
|
+
"support": ["create", "read", "update"],
|
|
73
|
+
"support_admin": ["create", "read", "update", "delete"],
|
|
74
|
+
"engineering_admin": ["create", "read", "update"],
|
|
75
|
+
"engineering": ["create", "read", "update"],
|
|
76
|
+
"devops": ["create", "read", "update"],
|
|
77
|
+
"incident_commander": ["create", "read", "update"],
|
|
78
|
+
"member": ["create", "read", "update"],
|
|
79
|
+
"member_admin": ["create", "read", "update", "delete"]
|
|
80
|
+
},
|
|
81
|
+
"functionality": {
|
|
82
|
+
"kb": {
|
|
83
|
+
"vector_fields": ["title", "description", "content", "tags"],
|
|
84
|
+
"chunk_field": "content",
|
|
85
|
+
"chunk_size": 800,
|
|
86
|
+
"chunk_overlap": 100
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
$DS$::jsonb,
|
|
91
|
+
'{}'::jsonb,
|
|
92
|
+
'system',
|
|
93
|
+
true
|
|
94
|
+
)
|
|
95
|
+
ON CONFLICT (kind, slug) DO NOTHING;
|
|
96
|
+
|
|
97
|
+
-- ─── INSERT: kb-spine-public (fresh installs) ───────────────────────────────
|
|
98
|
+
-- Minimal canonical definition; deployed databases already carry the full
|
|
99
|
+
-- schema from 046 and take the UPDATE path below instead.
|
|
100
|
+
|
|
101
|
+
INSERT INTO public.types (app_id, kind, slug, name, description, icon, color, design_schema, validation_schema, ownership, is_active)
|
|
102
|
+
VALUES (
|
|
103
|
+
NULL,
|
|
104
|
+
'item',
|
|
105
|
+
'kb-spine-public',
|
|
106
|
+
'Spine KB Public',
|
|
107
|
+
'Public Spine knowledge base articles readable by all accounts',
|
|
108
|
+
'book-open',
|
|
109
|
+
'#10B981',
|
|
110
|
+
$DS$
|
|
111
|
+
{
|
|
112
|
+
"scope": "platform",
|
|
113
|
+
"fields": {
|
|
114
|
+
"title": { "data_type": "text", "label": "Title", "required": true, "system": true },
|
|
115
|
+
"description": { "data_type": "textarea", "label": "Description", "required": false, "system": true },
|
|
116
|
+
"status": { "data_type": "select", "label": "Status", "required": true, "system": true, "options": ["draft", "published", "archived"] },
|
|
117
|
+
"content": { "data_type": "textarea", "label": "Content", "required": true },
|
|
118
|
+
"tags": { "data_type": "multiselect", "label": "Tags", "required": false, "options": ["support", "how-to", "faq", "tutorial"] },
|
|
119
|
+
"category": { "data_type": "multiselect", "label": "Category", "required": false, "options": ["how-to", "runbook", "policy", "faq", "tutorial"] },
|
|
120
|
+
"product": { "data_type": "multiselect", "label": "Product", "required": false, "options": ["spine-framework", "cortex", "workbench", "portal"] },
|
|
121
|
+
"version": { "data_type": "text", "label": "Version", "required": false },
|
|
122
|
+
"is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
|
|
123
|
+
"demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false }
|
|
124
|
+
},
|
|
125
|
+
"views": {
|
|
126
|
+
"default_list": {
|
|
127
|
+
"type": "list",
|
|
128
|
+
"display": "table",
|
|
129
|
+
"label": "Public Articles",
|
|
130
|
+
"fields": {
|
|
131
|
+
"title": { "sortable": true, "display_type": "text" },
|
|
132
|
+
"status": { "sortable": true, "display_type": "badge" },
|
|
133
|
+
"created_at": { "sortable": true, "display_type": "timestamp" }
|
|
134
|
+
},
|
|
135
|
+
"default_sort": { "field": "created_at", "direction": "desc" }
|
|
136
|
+
},
|
|
137
|
+
"default_detail": {
|
|
138
|
+
"type": "detail",
|
|
139
|
+
"label": "Article",
|
|
140
|
+
"sections": [
|
|
141
|
+
{ "title": "Core", "fields": { "title": { "display_type": "input" }, "status": { "display_type": "select" }, "description": { "display_type": "textarea" }, "content": { "display_type": "textarea" } } }
|
|
142
|
+
]
|
|
143
|
+
}
|
|
144
|
+
},
|
|
145
|
+
"record_permissions": {
|
|
146
|
+
"system_admin": ["create", "read", "update", "delete"],
|
|
147
|
+
"support": ["create", "read", "update"],
|
|
148
|
+
"support_admin": ["create", "read", "update", "delete"],
|
|
149
|
+
"engineering_admin": ["create", "read", "update"],
|
|
150
|
+
"engineering": ["create", "read", "update"],
|
|
151
|
+
"devops": ["create", "read", "update"],
|
|
152
|
+
"incident_commander": ["create", "read", "update"],
|
|
153
|
+
"member": ["read"],
|
|
154
|
+
"member_admin": ["read"]
|
|
155
|
+
},
|
|
156
|
+
"functionality": {
|
|
157
|
+
"kb": {
|
|
158
|
+
"vector_fields": ["title", "description", "content", "tags"],
|
|
159
|
+
"chunk_field": "content",
|
|
160
|
+
"chunk_size": 800,
|
|
161
|
+
"chunk_overlap": 100
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
$DS$::jsonb,
|
|
166
|
+
'{}'::jsonb,
|
|
167
|
+
'system',
|
|
168
|
+
true
|
|
169
|
+
)
|
|
170
|
+
ON CONFLICT (kind, slug) DO NOTHING;
|
|
171
|
+
|
|
172
|
+
-- ─── UPDATE: converge existing rows ─────────────────────────────────────────
|
|
173
|
+
-- Merge demo-flag + linkage fields and the member_admin grant into existing
|
|
174
|
+
-- design_schema JSON without replacing fields added since 046.
|
|
175
|
+
|
|
176
|
+
UPDATE public.types
|
|
177
|
+
SET design_schema = jsonb_set(
|
|
178
|
+
jsonb_set(
|
|
179
|
+
design_schema,
|
|
180
|
+
'{fields}',
|
|
181
|
+
(design_schema->'fields') || $F${
|
|
182
|
+
"is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
|
|
183
|
+
"demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false },
|
|
184
|
+
"source_ticket_id": { "data_type": "text", "label": "Source Ticket ID", "required": false }
|
|
185
|
+
}$F$::jsonb,
|
|
186
|
+
true
|
|
187
|
+
),
|
|
188
|
+
'{record_permissions}',
|
|
189
|
+
(design_schema->'record_permissions') || $P${
|
|
190
|
+
"member_admin": ["create", "read", "update", "delete"],
|
|
191
|
+
"member": ["create", "read", "update"]
|
|
192
|
+
}$P$::jsonb,
|
|
193
|
+
true
|
|
194
|
+
)
|
|
195
|
+
WHERE slug = 'kb-account' AND kind = 'item';
|
|
196
|
+
|
|
197
|
+
UPDATE public.types
|
|
198
|
+
SET design_schema = jsonb_set(
|
|
199
|
+
jsonb_set(
|
|
200
|
+
design_schema,
|
|
201
|
+
'{fields}',
|
|
202
|
+
(design_schema->'fields') || $F${
|
|
203
|
+
"is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
|
|
204
|
+
"demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false }
|
|
205
|
+
}$F$::jsonb,
|
|
206
|
+
true
|
|
207
|
+
),
|
|
208
|
+
'{record_permissions}',
|
|
209
|
+
(design_schema->'record_permissions') || $P${
|
|
210
|
+
"member_admin": ["read"],
|
|
211
|
+
"member": ["read"]
|
|
212
|
+
}$P$::jsonb,
|
|
213
|
+
true
|
|
214
|
+
)
|
|
215
|
+
WHERE slug = 'kb-spine-public' AND kind = 'item';
|
|
216
|
+
|
|
217
|
+
-- Merge the same flag fields into the Portal-owned support types so the demo
|
|
218
|
+
-- flag survives sanitizeRecordData on reads. These UPDATEs are no-ops on
|
|
219
|
+
-- databases where the seed has not installed the slugs yet — the portal seed
|
|
220
|
+
-- types.json now carries the fields for fresh installs.
|
|
221
|
+
UPDATE public.types
|
|
222
|
+
SET design_schema = jsonb_set(
|
|
223
|
+
design_schema,
|
|
224
|
+
'{fields}',
|
|
225
|
+
(design_schema->'fields') || $F${
|
|
226
|
+
"is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
|
|
227
|
+
"demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false }
|
|
228
|
+
}$F$::jsonb,
|
|
229
|
+
true
|
|
230
|
+
)
|
|
231
|
+
WHERE (kind, slug) IN (('item', 'support_ticket'), ('thread', 'support_thread'));
|
|
232
|
+
|
|
233
|
+
UPDATE public.types
|
|
234
|
+
SET design_schema = jsonb_set(
|
|
235
|
+
design_schema,
|
|
236
|
+
'{fields}',
|
|
237
|
+
(design_schema->'fields') || $F${
|
|
238
|
+
"is_demo": { "data_type": "boolean", "label": "Is Demo", "required": false },
|
|
239
|
+
"demo_run_id": { "data_type": "text", "label": "Demo Run ID", "required": false },
|
|
240
|
+
"escalation_notice": { "data_type": "boolean", "label": "Escalation Notice", "required": false }
|
|
241
|
+
}$F$::jsonb,
|
|
242
|
+
true
|
|
243
|
+
)
|
|
244
|
+
WHERE kind = 'message' AND slug = 'support_reply';
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
-- CIL[BEGIN stable_id="~/.framework/migrations/038_drop_demo_record_flags.sql:drop_demo_record_flags:file" type="file" identity="drop_demo_record_flags" parent="~/.framework/migrations/038_drop_demo_record_flags.sql"]
|
|
2
|
+
-- CIL[DOC-MACRO purpose="Remove record-level is_demo flagging in favor of demo-specific types for content isolation"]
|
|
3
|
+
-- CIL[DOC-RESPONSIBILITY responsibility="Drop trg_demo_flag triggers and apply_demo_flag() (migration 036); strip is_demo/demo_run_id from existing runtime records. Record visibility is now isolated by demo_* types; accounts.data.is_demo remains a lifecycle-only marker (expiry, rate-limit policy, funnel tagging)"]
|
|
4
|
+
-- CIL[DOC-CONTEXT module="migrations" layer="data" related_files="custom/apps/demo/seed/types.json,custom/apps/demo/functions/custom_demo-journey.ts,custom/apps/portal/functions/custom_support-triage.ts"]
|
|
5
|
+
-- CIL[DOC-CONTRACT inputs="trg_demo_flag triggers + apply_demo_flag() from migration 036" outputs="triggers/function dropped; records unflagged" errors="none" side_effects="Runtime records can no longer be marked is_demo; accounts.data.is_demo is managed solely by demo provision"]
|
|
6
|
+
-- CIL[DOC-MICRO logic_summary="Demo content isolation moved to type-based scoping (demo_support_ticket, demo_support_thread). Accounts and people are never demo-flagged — they are real leads for Cortex." notable_decisions="Type isolation chosen over record flags so demo play can run inside shared accounts without hiding real records"]
|
|
7
|
+
-- CIL[DOC-STABILITY stability="stable"]
|
|
8
|
+
|
|
9
|
+
DO $$
|
|
10
|
+
DECLARE
|
|
11
|
+
t text;
|
|
12
|
+
BEGIN
|
|
13
|
+
FOREACH t IN ARRAY ARRAY['items', 'threads', 'messages', 'links', 'attachments', 'watchers', 'people']
|
|
14
|
+
LOOP
|
|
15
|
+
EXECUTE format('DROP TRIGGER IF EXISTS trg_demo_flag ON public.%I', t);
|
|
16
|
+
END LOOP;
|
|
17
|
+
END $$;
|
|
18
|
+
|
|
19
|
+
DROP FUNCTION IF EXISTS public.apply_demo_flag();
|
|
20
|
+
|
|
21
|
+
-- Unflag any runtime records that were stamped while the trigger was active.
|
|
22
|
+
DO $$
|
|
23
|
+
DECLARE
|
|
24
|
+
t text;
|
|
25
|
+
BEGIN
|
|
26
|
+
FOREACH t IN ARRAY ARRAY['items', 'threads', 'messages', 'links', 'attachments', 'watchers', 'people']
|
|
27
|
+
LOOP
|
|
28
|
+
EXECUTE format(
|
|
29
|
+
'UPDATE public.%I SET data = data - ''is_demo'' - ''demo_run_id'' WHERE data ? ''is_demo'' OR data ? ''demo_run_id''',
|
|
30
|
+
t
|
|
31
|
+
);
|
|
32
|
+
END LOOP;
|
|
33
|
+
END $$;
|
|
34
|
+
-- CIL[DOC-VECTOR type="context" content="purpose='Remove record-level is_demo flagging in favor of demo-specific types'; No verified external callers; imports: none" status="ready"]
|
|
35
|
+
-- CIL[DOC-VECTOR type="blast_radius" content="admin-data demo_only/exclude_demo params become no-ops; demo visibility now enforced by type_slug scoping" status="ready"]
|
|
36
|
+
-- CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified" status="ready"]
|
|
37
|
+
-- CIL[DOC-VECTOR type="constraint" content="accounts.data.is_demo is still written by demo provision for lifecycle (expiry/rate-limits); it is no longer propagated to records" status="ready"]
|
|
38
|
+
-- CIL[END stable_id="~/.framework/migrations/038_drop_demo_record_flags.sql:drop_demo_record_flags:file"]
|