spine-framework 0.3.145 → 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 +15 -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
|
@@ -1,64 +1,62 @@
|
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/functions/admin-funnel.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/admin-funnel.ts"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Module-level imports for the admin funnel metrics handler"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Import shared middleware and database client used by the handler"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="admin-funnel" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Dependency wiring for the admin funnel function" notable_decisions="Uses createHandler and adminDb from _shared"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stable]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="internal"]
|
|
1
10
|
|
|
2
|
-
// CIL[BEGIN chunk_id="admin-funnel_module_header_1784019432" type="module_header" identity="imports" parent="none"]
|
|
3
|
-
// CIL[DOC-MACRO purpose="Import dependencies for funnel metrics"]
|
|
4
|
-
// CIL[DOC-RESPONSIBILITY responsibility="Provide middleware and admin database access"]
|
|
5
|
-
// CIL[DOC-CONTEXT module="admin-funnel" layer="api-handler" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"\\\"]"]
|
|
6
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="imported_modules" errors="none" side_effects="none"]
|
|
7
|
-
// CIL[DOC-MICRO logic_summary="Imports required modules for funnel analytics" notable_decisions="[]"]
|
|
8
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
9
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
10
|
-
// CIL[DOC-AUDIENCE audience="developer"]
|
|
11
|
-
// CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, \."]
|
|
12
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
13
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
14
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
15
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
16
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
17
11
|
import { createHandler } from './_shared/middleware'
|
|
18
12
|
import { adminDb } from './_shared/db'
|
|
19
|
-
// CIL[
|
|
20
|
-
// CIL[
|
|
21
|
-
// CIL[DOC-
|
|
22
|
-
// CIL[DOC-
|
|
23
|
-
// CIL[DOC-CONTEXT module="admin-funnel" layer="api-handler" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
|
|
24
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="funnel_metrics_object" errors="types_not_found" side_effects="database_queries,aggregation_calculations"]
|
|
25
|
-
// CIL[DOC-MICRO logic_summary="Queries signals, sessions, instances; calculates conversion rates and stage distribution" notable_decisions="[]"]
|
|
26
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="external_symbols_unknown"]
|
|
27
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
28
|
-
// CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/functions/_shared/principal.ts, \."]
|
|
29
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
30
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
31
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
13
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Module-level imports for the admin funnel metrics handler'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
|
|
14
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
15
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
16
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
32
17
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
33
18
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
19
|
+
// CIL[END stable_id="~/.framework/functions/admin-funnel.ts:module_header:module_header"]
|
|
20
|
+
// CIL[BEGIN stable_id="~/.framework/functions/admin-funnel.ts:metrics:constant" type="constant" identity="metrics" parent="~/.framework/functions/admin-funnel.ts"]
|
|
21
|
+
// CIL[DOC-MACRO purpose="Compute admin funnel metrics for the last 30 days"]
|
|
22
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Query item type registry and items table to calculate visitor, user, install, and stage distribution metrics"]
|
|
23
|
+
// CIL[DOC-CONTEXT module="admin-funnel" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-funnel.ts"]
|
|
24
|
+
// CIL[DOC-CONTRACT inputs="ctx: RequestContext, body: request payload" outputs="anonymous_visitors, identified_users, installed_instances, conversion_rates, stage_distribution" errors="none — missing signal types degrade to zeroed metrics" side_effects="Reads from adminDb; no writes"]
|
|
25
|
+
// CIL[DOC-MICRO logic_summary="Resolve funnel_signal, anonymous_session, and spine_instance type IDs from types (kind='item'); count signals, anonymous sessions, identified accounts, and installed instances; return conversion rates and stage distribution" notable_decisions="Signal types are app-seeded, so absent types produce zeroed sections rather than errors; ignores signal items without account_id for stage counts; uses 30-day window; guards division with zero checks"]
|
|
26
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
27
|
+
// CIL[DOC-STABILITY stable]
|
|
34
28
|
export const metrics = createHandler(async (ctx, body) => {
|
|
35
|
-
const { data:
|
|
36
|
-
.from('
|
|
37
|
-
.select('id')
|
|
38
|
-
.eq('
|
|
39
|
-
.
|
|
40
|
-
|
|
41
|
-
const { data: sessionType } = await adminDb
|
|
42
|
-
.from('item_type_registry')
|
|
43
|
-
.select('id')
|
|
44
|
-
.eq('slug', 'anonymous_session')
|
|
45
|
-
.single()
|
|
46
|
-
|
|
47
|
-
const { data: instanceType } = await adminDb
|
|
48
|
-
.from('item_type_registry')
|
|
49
|
-
.select('id')
|
|
50
|
-
.eq('slug', 'spine_instance')
|
|
51
|
-
.single()
|
|
29
|
+
const { data: typeRows } = await adminDb
|
|
30
|
+
.from('types')
|
|
31
|
+
.select('id, slug')
|
|
32
|
+
.eq('kind', 'item')
|
|
33
|
+
.in('slug', ['funnel_signal', 'anonymous_session', 'spine_instance'])
|
|
52
34
|
|
|
53
|
-
|
|
54
|
-
|
|
35
|
+
const typeIdFor = (slug: string) => typeRows?.find((t: any) => t.slug === slug)?.id || null
|
|
36
|
+
const signalTypeId = typeIdFor('funnel_signal')
|
|
37
|
+
const sessionTypeId = typeIdFor('anonymous_session')
|
|
38
|
+
const instanceTypeId = typeIdFor('spine_instance')
|
|
39
|
+
|
|
40
|
+
// Signal types are seeded by installed apps — a clean framework install
|
|
41
|
+
// legitimately has none, so degrade to zeroed metrics instead of 500s.
|
|
42
|
+
if (!signalTypeId && !sessionTypeId && !instanceTypeId) {
|
|
43
|
+
return {
|
|
44
|
+
anonymous_visitors: 0,
|
|
45
|
+
identified_users: 0,
|
|
46
|
+
installed_instances: 0,
|
|
47
|
+
conversion_rates: {
|
|
48
|
+
anonymous_to_identified: 0,
|
|
49
|
+
identified_to_installed: 0
|
|
50
|
+
},
|
|
51
|
+
stage_distribution: []
|
|
52
|
+
}
|
|
55
53
|
}
|
|
56
54
|
|
|
57
|
-
const { data: stageData } = await adminDb
|
|
55
|
+
const { data: stageData } = signalTypeId ? await adminDb
|
|
58
56
|
.from('items')
|
|
59
57
|
.select('data->>stage, account_id')
|
|
60
|
-
.eq('type_id',
|
|
61
|
-
.gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString())
|
|
58
|
+
.eq('type_id', signalTypeId)
|
|
59
|
+
.gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString()) : { data: [] }
|
|
62
60
|
|
|
63
61
|
const stageCounts = stageData?.reduce((acc, item) => {
|
|
64
62
|
const stage = item.data?.stage || 'unknown'
|
|
@@ -70,27 +68,27 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
70
68
|
|
|
71
69
|
const totalStageSignals = Object.values(stageCounts).reduce((sum, count) => sum + count, 0)
|
|
72
70
|
|
|
73
|
-
const { count: anonymousSessions } = await adminDb
|
|
71
|
+
const { count: anonymousSessions } = sessionTypeId ? await adminDb
|
|
74
72
|
.from('items')
|
|
75
73
|
.select('*', { count: 'exact', head: true })
|
|
76
|
-
.eq('type_id',
|
|
74
|
+
.eq('type_id', sessionTypeId)
|
|
77
75
|
.is('data->lifecycle->>stitched_to_account_id', null)
|
|
78
|
-
.gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString())
|
|
76
|
+
.gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString()) : { count: 0 }
|
|
79
77
|
|
|
80
|
-
const { data: accountData } = await adminDb
|
|
78
|
+
const { data: accountData } = signalTypeId ? await adminDb
|
|
81
79
|
.from('items')
|
|
82
80
|
.select('account_id')
|
|
83
|
-
.eq('type_id',
|
|
81
|
+
.eq('type_id', signalTypeId)
|
|
84
82
|
.gte('created_at', new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString())
|
|
85
|
-
.not('account_id', 'is', null)
|
|
83
|
+
.not('account_id', 'is', null) : { data: [] }
|
|
86
84
|
|
|
87
85
|
const uniqueAccounts = new Set(accountData?.map(item => item.account_id)).size
|
|
88
86
|
|
|
89
|
-
const { count: installedInstances } = await adminDb
|
|
87
|
+
const { count: installedInstances } = instanceTypeId ? await adminDb
|
|
90
88
|
.from('items')
|
|
91
89
|
.select('*', { count: 'exact', head: true })
|
|
92
|
-
.eq('type_id',
|
|
93
|
-
.not('data->>claimed_by_person_id', 'is', null)
|
|
90
|
+
.eq('type_id', instanceTypeId)
|
|
91
|
+
.not('data->>claimed_by_person_id', 'is', null) : { count: 0 }
|
|
94
92
|
|
|
95
93
|
const stageDistribution = Object.entries(stageCounts).map(([stage, count]) => ({
|
|
96
94
|
stage,
|
|
@@ -112,4 +110,10 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
112
110
|
stage_distribution: stageDistribution
|
|
113
111
|
}
|
|
114
112
|
})
|
|
115
|
-
// CIL[
|
|
113
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Compute admin funnel metrics for the last 30 days'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
|
|
114
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
115
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
116
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
117
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
118
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
119
|
+
// CIL[END stable_id="~/.framework/functions/admin-funnel.ts:metrics:constant"]
|
|
@@ -1,59 +1,66 @@
|
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/functions/admin-install-funnel.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/admin-install-funnel.ts"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Netlify function entrypoint for install funnel admin metrics and export handlers"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Define admin metrics and exportData handler exports for the install-funnel function"]
|
|
4
|
+
// CIL[DOC-CONTEXT module="admin" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Imports shared middleware and database client for the install funnel admin endpoints" notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="admin-api consumer"]
|
|
1
10
|
|
|
2
11
|
|
|
3
|
-
// CIL[BEGIN chunk_id="admin-install-funnel_module_header_1784019432" type="module_header" identity="imports" parent="none"]
|
|
4
|
-
// CIL[DOC-MACRO purpose="Import dependencies for install funnel analytics"]
|
|
5
|
-
// CIL[DOC-RESPONSIBILITY responsibility="Provide middleware and admin database access"]
|
|
6
|
-
// CIL[DOC-CONTEXT module="admin-install-funnel" layer="api-handler" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/components/layout/Sidebar.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
7
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="imported_modules" errors="none" side_effects="none"]
|
|
8
|
-
// CIL[DOC-MICRO logic_summary="Imports required modules for install funnel processing" notable_decisions="[]"]
|
|
9
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
10
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
11
|
-
// CIL[DOC-AUDIENCE audience="developer"]
|
|
12
|
-
// CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/src/components/layout/Sidebar.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
13
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
14
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
15
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
16
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
17
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
18
12
|
import { createHandler } from './_shared/middleware'
|
|
19
13
|
import { adminDb } from './_shared/db'
|
|
20
|
-
// CIL[
|
|
21
|
-
// CIL[
|
|
22
|
-
// CIL[DOC-
|
|
23
|
-
// CIL[DOC-
|
|
24
|
-
// CIL[DOC-CONTEXT module="admin-install-funnel" layer="api-handler" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
|
|
25
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="install_metrics_object" errors="funnel_signal_type_not_found" side_effects="database_queries,aggregation_calculations,trend_analysis"]
|
|
26
|
-
// CIL[DOC-MICRO logic_summary="Counts downloads/installs, calculates conversion rates, analyzes versions, tracks trends" notable_decisions="[]"]
|
|
27
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="external_symbols_unknown"]
|
|
28
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
29
|
-
// CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/src/components/ui/dialog.tsx, \."]
|
|
30
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
31
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
32
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
14
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Netlify function entrypoint for install funnel admin metrics and export handlers'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
|
|
15
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
16
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
17
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
33
18
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
34
19
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
20
|
+
// CIL[END stable_id="~/.framework/functions/admin-install-funnel.ts:module_header:module_header"]
|
|
21
|
+
// CIL[BEGIN stable_id="~/.framework/functions/admin-install-funnel.ts:metrics:constant" type="constant" identity="metrics" parent="~/.framework/functions/admin-install-funnel.ts"]
|
|
22
|
+
// CIL[DOC-MACRO purpose="Serve install funnel metrics including downloads, installs, first use, claimed, trends and version breakdown"]
|
|
23
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Compute and return install funnel analytics from the item registry"]
|
|
24
|
+
// CIL[DOC-CONTEXT module="admin" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-install-funnel.ts"]
|
|
25
|
+
// CIL[DOC-CONTRACT inputs="admin request context and body" outputs="JSON metrics object with funnel counts, trends, recent installs and top versions" errors="none — missing signal types degrade to zeroed metrics" side_effects="none"]
|
|
26
|
+
// CIL[DOC-MICRO logic_summary="Resolves the funnel_signal and spine_instance types, aggregates counts, formats recent installs and computes 30-day daily trends" notable_decisions="Signal types are app-seeded, so absent types produce zeroed sections rather than errors"]
|
|
27
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
28
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
35
29
|
export const metrics = createHandler(async (ctx, body) => {
|
|
36
|
-
const { data:
|
|
37
|
-
.from('
|
|
38
|
-
.select('id')
|
|
39
|
-
.eq('
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
30
|
+
const { data: typeRows } = await adminDb
|
|
31
|
+
.from('types')
|
|
32
|
+
.select('id, slug')
|
|
33
|
+
.eq('kind', 'item')
|
|
34
|
+
.in('slug', ['funnel_signal', 'spine_instance'])
|
|
35
|
+
|
|
36
|
+
const signalTypeId = typeRows?.find((t: any) => t.slug === 'funnel_signal')?.id || null
|
|
37
|
+
const instanceTypeId = typeRows?.find((t: any) => t.slug === 'spine_instance')?.id || null
|
|
38
|
+
|
|
39
|
+
// Signal types are seeded by installed apps — a clean framework install
|
|
40
|
+
// legitimately has none, so degrade to zeroed metrics instead of 500s.
|
|
41
|
+
if (!signalTypeId) {
|
|
42
|
+
return {
|
|
43
|
+
total_downloads: 0,
|
|
44
|
+
unique_installers: 0,
|
|
45
|
+
active_instances: 0,
|
|
46
|
+
conversion_funnel: { downloads: 0, installations: 0, first_use: 0, claimed: 0 },
|
|
47
|
+
install_trends: [],
|
|
48
|
+
recent_installs: [],
|
|
49
|
+
top_versions: []
|
|
50
|
+
}
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
const { count: totalDownloads } = await adminDb
|
|
47
54
|
.from('items')
|
|
48
55
|
.select('*', { count: 'exact', head: true })
|
|
49
|
-
.eq('type_id',
|
|
56
|
+
.eq('type_id', signalTypeId)
|
|
50
57
|
.eq('data->>source', 'inst')
|
|
51
58
|
.eq('data->>action_type', 'download')
|
|
52
59
|
|
|
53
60
|
const { data: installerData } = await adminDb
|
|
54
61
|
.from('items')
|
|
55
62
|
.select('data->>serial')
|
|
56
|
-
.eq('type_id',
|
|
63
|
+
.eq('type_id', signalTypeId)
|
|
57
64
|
.eq('data->>source', 'inst')
|
|
58
65
|
.not('data->>serial', 'is', null)
|
|
59
66
|
|
|
@@ -63,7 +70,7 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
63
70
|
const { count: activeInstances } = await adminDb
|
|
64
71
|
.from('items')
|
|
65
72
|
.select('*', { count: 'exact', head: true })
|
|
66
|
-
.eq('type_id',
|
|
73
|
+
.eq('type_id', signalTypeId)
|
|
67
74
|
.eq('data->>source', 'inst')
|
|
68
75
|
.not('data->>serial', 'is', null)
|
|
69
76
|
.gte('created_at', sevenDaysAgo)
|
|
@@ -71,21 +78,21 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
71
78
|
const { count: installations } = await adminDb
|
|
72
79
|
.from('items')
|
|
73
80
|
.select('*', { count: 'exact', head: true })
|
|
74
|
-
.eq('type_id',
|
|
81
|
+
.eq('type_id', signalTypeId)
|
|
75
82
|
.eq('data->>source', 'inst')
|
|
76
83
|
.eq('data->>action_type', 'install')
|
|
77
84
|
|
|
78
85
|
const { count: firstUse } = await adminDb
|
|
79
86
|
.from('items')
|
|
80
87
|
.select('*', { count: 'exact', head: true })
|
|
81
|
-
.eq('type_id',
|
|
88
|
+
.eq('type_id', signalTypeId)
|
|
82
89
|
.eq('data->>source', 'inst')
|
|
83
90
|
.eq('data->>action_type', 'first_command')
|
|
84
91
|
|
|
85
92
|
const { count: claimed } = await adminDb
|
|
86
93
|
.from('items')
|
|
87
94
|
.select('*', { count: 'exact', head: true })
|
|
88
|
-
.eq('type_id',
|
|
95
|
+
.eq('type_id', signalTypeId)
|
|
89
96
|
.eq('data->>source', 'inst')
|
|
90
97
|
.not('data->>claimed_by_person_id', 'is', null)
|
|
91
98
|
|
|
@@ -101,10 +108,10 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
101
108
|
data->>claimed_by_person_id,
|
|
102
109
|
data->>claimed_at,
|
|
103
110
|
account_id,
|
|
104
|
-
people(email),
|
|
111
|
+
people!fk_items_created_by(email),
|
|
105
112
|
accounts(name)
|
|
106
113
|
`)
|
|
107
|
-
.eq('type_id',
|
|
114
|
+
.eq('type_id', signalTypeId)
|
|
108
115
|
.eq('data->>source', 'inst')
|
|
109
116
|
.not('data->>serial', 'is', null)
|
|
110
117
|
.order('created_at', { ascending: false })
|
|
@@ -123,10 +130,10 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
123
130
|
person_email: instance.people?.email
|
|
124
131
|
}))
|
|
125
132
|
|
|
126
|
-
const { data: versionData } = await adminDb
|
|
133
|
+
const { data: versionData } = instanceTypeId ? await adminDb
|
|
127
134
|
.from('items')
|
|
128
135
|
.select('data->>version')
|
|
129
|
-
.eq('type_id',
|
|
136
|
+
.eq('type_id', instanceTypeId) : { data: [] }
|
|
130
137
|
|
|
131
138
|
const versionCounts = versionData?.reduce((acc, item) => {
|
|
132
139
|
const version = item.data?.version || 'unknown'
|
|
@@ -156,7 +163,7 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
156
163
|
const { count: dailyDownloads } = await adminDb
|
|
157
164
|
.from('items')
|
|
158
165
|
.select('*', { count: 'exact', head: true })
|
|
159
|
-
.eq('type_id',
|
|
166
|
+
.eq('type_id', signalTypeId)
|
|
160
167
|
.eq('data->>source', 'inst')
|
|
161
168
|
.eq('data->>action_type', 'download')
|
|
162
169
|
.gte('created_at', dateStr)
|
|
@@ -165,7 +172,7 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
165
172
|
const { count: dailyInstalls } = await adminDb
|
|
166
173
|
.from('items')
|
|
167
174
|
.select('*', { count: 'exact', head: true })
|
|
168
|
-
.eq('type_id',
|
|
175
|
+
.eq('type_id', signalTypeId)
|
|
169
176
|
.eq('data->>source', 'inst')
|
|
170
177
|
.eq('data->>action_type', 'install')
|
|
171
178
|
.gte('created_at', dateStr)
|
|
@@ -193,30 +200,35 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
193
200
|
top_versions: topVersions
|
|
194
201
|
}
|
|
195
202
|
})
|
|
196
|
-
// CIL[
|
|
197
|
-
// CIL[
|
|
198
|
-
// CIL[DOC-
|
|
199
|
-
// CIL[DOC-
|
|
200
|
-
// CIL[DOC-CONTEXT module="admin-install-funnel" layer="api-handler" related_files="[\".framework/functions/_shared/schema-utils.ts\",\".framework/src/components/layout/Sidebar.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
|
|
201
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="export_data_object" errors="funnel_signal_type_not_found" side_effects="database_query,data_export"]
|
|
202
|
-
// CIL[DOC-MICRO logic_summary="Queries all install instances with full details and metadata" notable_decisions="[]"]
|
|
203
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
204
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
205
|
-
// CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: .framework/functions/_shared/schema-utils.ts, .framework/src/components/layout/Sidebar.tsx, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/principal.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
|
|
206
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
207
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
208
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
203
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Serve install funnel metrics including downloads, installs, first use, claimed, trends and version breakdown'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
|
|
204
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
205
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
206
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
209
207
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
210
208
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
209
|
+
// CIL[END stable_id="~/.framework/functions/admin-install-funnel.ts:metrics:constant"]
|
|
210
|
+
// CIL[BEGIN stable_id="~/.framework/functions/admin-install-funnel.ts:exportData:constant" type="constant" identity="exportData" parent="~/.framework/functions/admin-install-funnel.ts"]
|
|
211
|
+
// CIL[DOC-MACRO purpose="Export raw install funnel instance records with contact and account details"]
|
|
212
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Return all funnel_signal instances with source 'inst' and a non-null serial"]
|
|
213
|
+
// CIL[DOC-CONTEXT module="admin" layer="function" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-install-funnel.ts"]
|
|
214
|
+
// CIL[DOC-CONTRACT inputs="admin request context and body" outputs="JSON object with instances array, exported_at and total_count" errors="none" side_effects="none"]
|
|
215
|
+
// CIL[DOC-MICRO logic_summary="Selects instances with joined people and accounts, ordered by created_at descending" notable_decisions="[]"]
|
|
216
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
217
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
211
218
|
export const exportData = createHandler(async (ctx, body) => {
|
|
212
219
|
const { data: signalType } = await adminDb
|
|
213
|
-
.from('
|
|
220
|
+
.from('types')
|
|
214
221
|
.select('id')
|
|
222
|
+
.eq('kind', 'item')
|
|
215
223
|
.eq('slug', 'funnel_signal')
|
|
216
|
-
.
|
|
224
|
+
.maybeSingle()
|
|
217
225
|
|
|
218
226
|
if (!signalType) {
|
|
219
|
-
|
|
227
|
+
return {
|
|
228
|
+
instances: [],
|
|
229
|
+
exported_at: new Date().toISOString(),
|
|
230
|
+
total_count: 0
|
|
231
|
+
}
|
|
220
232
|
}
|
|
221
233
|
|
|
222
234
|
const { data: instances } = await adminDb
|
|
@@ -227,7 +239,7 @@ export const exportData = createHandler(async (ctx, body) => {
|
|
|
227
239
|
updated_at,
|
|
228
240
|
data,
|
|
229
241
|
account_id,
|
|
230
|
-
people(email),
|
|
242
|
+
people!fk_items_created_by(email),
|
|
231
243
|
accounts(name)
|
|
232
244
|
`)
|
|
233
245
|
.eq('type_id', signalType.id)
|
|
@@ -241,4 +253,10 @@ export const exportData = createHandler(async (ctx, body) => {
|
|
|
241
253
|
total_count: instances?.length || 0
|
|
242
254
|
}
|
|
243
255
|
})
|
|
244
|
-
// CIL[
|
|
256
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Export raw install funnel instance records with contact and account details'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
|
|
257
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
258
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
259
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
260
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
261
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
262
|
+
// CIL[END stable_id="~/.framework/functions/admin-install-funnel.ts:exportData:constant"]
|
|
@@ -1,50 +1,54 @@
|
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/functions/admin-signals.ts:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/functions/admin-signals.ts"]
|
|
2
|
+
// CIL[DOC-MACRO purpose="Declares the admin-signals function module and its imports"]
|
|
3
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Set up module context and shared dependencies"]
|
|
4
|
+
// CIL[DOC-CONTEXT module=".framework/functions/admin-signals.ts" layer="functions" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts"]
|
|
5
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="module scope" errors="none" side_effects="none"]
|
|
6
|
+
// CIL[DOC-MICRO logic_summary="Module header that imports shared middleware and database client for admin signal handlers." notable_decisions="[]"]
|
|
7
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
8
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
9
|
+
// CIL[DOC-AUDIENCE audience="system-admin, developer"]
|
|
1
10
|
|
|
2
11
|
|
|
3
|
-
// CIL[BEGIN chunk_id="admin-signals_module_header_1784019432" type="module_header" identity="imports" parent="none"]
|
|
4
|
-
// CIL[DOC-MACRO purpose="Import dependencies for signal analytics"]
|
|
5
|
-
// CIL[DOC-RESPONSIBILITY responsibility="Provide middleware and admin database access"]
|
|
6
|
-
// CIL[DOC-CONTEXT module="admin-signals" layer="api-handler" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\",\"\\\"]"]
|
|
7
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="imported_modules" errors="none" side_effects="none"]
|
|
8
|
-
// CIL[DOC-MICRO logic_summary="Imports required modules for signal processing" notable_decisions="[]"]
|
|
9
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
10
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
11
|
-
// CIL[DOC-AUDIENCE audience="developer"]
|
|
12
|
-
// CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx, \."]
|
|
13
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
14
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
15
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
16
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
17
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
18
12
|
import { createHandler } from './_shared/middleware'
|
|
19
13
|
import { adminDb } from './_shared/db'
|
|
20
|
-
// CIL[
|
|
21
|
-
// CIL[
|
|
22
|
-
// CIL[DOC-
|
|
23
|
-
// CIL[DOC-
|
|
24
|
-
// CIL[DOC-CONTEXT module="admin-signals" layer="api-handler" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
|
|
25
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="signal_metrics_object" errors="funnel_signal_type_not_found" side_effects="database_queries,aggregation_calculations"]
|
|
26
|
-
// CIL[DOC-MICRO logic_summary="Counts signals by time periods, calculates sources, formats recent signals, computes conversion rates" notable_decisions="[]"]
|
|
27
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="external_symbols_unknown"]
|
|
28
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
29
|
-
// CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/functions/_shared/principal.ts, \."]
|
|
30
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
31
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
32
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
14
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Declares the admin-signals function module and its imports'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
|
|
15
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
16
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
17
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
33
18
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
34
19
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
20
|
+
// CIL[END stable_id="~/.framework/functions/admin-signals.ts:module_header:module_header"]
|
|
21
|
+
// CIL[BEGIN stable_id="~/.framework/functions/admin-signals.ts:metrics:constant" type="constant" identity="metrics" parent="~/.framework/functions/admin-signals.ts"]
|
|
22
|
+
// CIL[DOC-MACRO purpose="Aggregate funnel signal metrics for the admin dashboard"]
|
|
23
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Compute and return totals, daily and weekly counts, conversion rate, top sources, and recent signals"]
|
|
24
|
+
// CIL[DOC-CONTEXT module=".framework/functions/admin-signals.ts" layer="functions" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-signals.ts"]
|
|
25
|
+
// CIL[DOC-CONTRACT inputs="ctx, body" outputs="JSON metrics object" errors="none — missing signal types degrade to zeroed metrics" side_effects="Queries adminDb"]
|
|
26
|
+
// CIL[DOC-MICRO logic_summary="Resolves funnel_signal item type, runs count and select queries over items, aggregates source distribution over the past week, computes conversion rate, and formats the most recent signals." notable_decisions="[]"]
|
|
27
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
28
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
35
29
|
export const metrics = createHandler(async (ctx, body) => {
|
|
36
30
|
const now = new Date()
|
|
37
31
|
const today = now.toISOString().split('T')[0]
|
|
38
32
|
const weekAgo = new Date(now.getTime() - 7 * 24 * 60 * 60 * 1000).toISOString()
|
|
39
33
|
|
|
40
34
|
const { data: signalType } = await adminDb
|
|
41
|
-
.from('
|
|
35
|
+
.from('types')
|
|
42
36
|
.select('id')
|
|
37
|
+
.eq('kind', 'item')
|
|
43
38
|
.eq('slug', 'funnel_signal')
|
|
44
|
-
.
|
|
45
|
-
|
|
39
|
+
.maybeSingle()
|
|
40
|
+
|
|
41
|
+
// Signal types are seeded by installed apps — a clean framework install
|
|
42
|
+
// legitimately has none, so degrade to zeroed metrics instead of 500s.
|
|
46
43
|
if (!signalType) {
|
|
47
|
-
|
|
44
|
+
return {
|
|
45
|
+
total_signals: 0,
|
|
46
|
+
signals_today: 0,
|
|
47
|
+
signals_this_week: 0,
|
|
48
|
+
conversion_rate: 0,
|
|
49
|
+
top_sources: [],
|
|
50
|
+
recent_signals: []
|
|
51
|
+
}
|
|
48
52
|
}
|
|
49
53
|
|
|
50
54
|
const { count: totalSignals } = await adminDb
|
|
@@ -125,21 +129,21 @@ export const metrics = createHandler(async (ctx, body) => {
|
|
|
125
129
|
recent_signals: formattedSignals || []
|
|
126
130
|
}
|
|
127
131
|
})
|
|
128
|
-
// CIL[
|
|
129
|
-
// CIL[
|
|
130
|
-
// CIL[DOC-
|
|
131
|
-
// CIL[DOC-
|
|
132
|
-
// CIL[DOC-CONTEXT module="admin-signals" layer="api-handler" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/functions/_shared/db.ts\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
|
|
133
|
-
// CIL[DOC-CONTRACT inputs="none" outputs="paginated_signals_or_export_data" errors="funnel_signal_type_not_found" side_effects="database_queries,data_formatting"]
|
|
134
|
-
// CIL[DOC-MICRO logic_summary="Builds filtered query, applies pagination, formats signal data for audit/export" notable_decisions="[]"]
|
|
135
|
-
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="external_symbols_unknown"]
|
|
136
|
-
// CIL[DOC-STABILITY stability="stable"]
|
|
137
|
-
// CIL[DOC-VECTOR type="context" content="Layer: api-handler. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/functions/_shared/db.ts, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/schema-utils.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
|
|
138
|
-
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
139
|
-
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
140
|
-
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
132
|
+
// CIL[DOC-VECTOR type="context" content="purpose='Aggregate funnel signal metrics for the admin dashboard'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
|
|
133
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
134
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
135
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
141
136
|
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
142
137
|
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
138
|
+
// CIL[END stable_id="~/.framework/functions/admin-signals.ts:metrics:constant"]
|
|
139
|
+
// CIL[BEGIN stable_id="~/.framework/functions/admin-signals.ts:audit:constant" type="constant" identity="audit" parent="~/.framework/functions/admin-signals.ts"]
|
|
140
|
+
// CIL[DOC-MACRO purpose="List and optionally export funnel signal audit records"]
|
|
141
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Fetch paginated signal records, apply query filters, and support CSV-like export"]
|
|
142
|
+
// CIL[DOC-CONTEXT module=".framework/functions/admin-signals.ts" layer="functions" related_files=".framework/functions/_shared/db.ts,.framework/functions/_shared/middleware.ts,.framework/functions/admin-signals.ts"]
|
|
143
|
+
// CIL[DOC-CONTRACT inputs="ctx, body and ctx.query filter parameters" outputs="Object with signals array, total, page, limit or formatted array for export" errors="query failure throws; missing signal type degrades to an empty page" side_effects="Queries adminDb"]
|
|
144
|
+
// CIL[DOC-MICRO logic_summary="Resolves funnel_signal item type, builds a filtered query over items including related accounts and people, optionally paginates, returns full data for export, and formats each row." notable_decisions="[]"]
|
|
145
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.90" flags="none"]
|
|
146
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
143
147
|
export const audit = createHandler(async (ctx, body) => {
|
|
144
148
|
const {
|
|
145
149
|
page = '1',
|
|
@@ -156,13 +160,21 @@ export const audit = createHandler(async (ctx, body) => {
|
|
|
156
160
|
} = ctx.query || {}
|
|
157
161
|
|
|
158
162
|
const { data: signalType } = await adminDb
|
|
159
|
-
.from('
|
|
163
|
+
.from('types')
|
|
160
164
|
.select('id')
|
|
165
|
+
.eq('kind', 'item')
|
|
161
166
|
.eq('slug', 'funnel_signal')
|
|
162
|
-
.
|
|
163
|
-
|
|
167
|
+
.maybeSingle()
|
|
168
|
+
|
|
169
|
+
// Signal types are seeded by installed apps — degrade to an empty page.
|
|
164
170
|
if (!signalType) {
|
|
165
|
-
|
|
171
|
+
if (exportData) return []
|
|
172
|
+
return {
|
|
173
|
+
signals: [],
|
|
174
|
+
total: 0,
|
|
175
|
+
page: parseInt(page),
|
|
176
|
+
limit: parseInt(limit)
|
|
177
|
+
}
|
|
166
178
|
}
|
|
167
179
|
|
|
168
180
|
let query = adminDb
|
|
@@ -183,7 +195,7 @@ export const audit = createHandler(async (ctx, body) => {
|
|
|
183
195
|
data->attribution->>utm_medium,
|
|
184
196
|
data->attribution->>utm_campaign,
|
|
185
197
|
account_id,
|
|
186
|
-
people(email),
|
|
198
|
+
people!fk_items_created_by(email),
|
|
187
199
|
accounts(name)
|
|
188
200
|
`, { count: 'exact' })
|
|
189
201
|
.eq('type_id', signalType.id)
|
|
@@ -256,4 +268,10 @@ export const audit = createHandler(async (ctx, body) => {
|
|
|
256
268
|
limit: parseInt(limit)
|
|
257
269
|
}
|
|
258
270
|
})
|
|
259
|
-
// CIL[
|
|
271
|
+
// CIL[DOC-VECTOR type="context" content="purpose='List and optionally export funnel signal audit records'; No verified external callers; imports: .framework/functions/_shared/middleware.ts,.framework/functions/_shared/db.ts"]
|
|
272
|
+
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
273
|
+
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
274
|
+
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
275
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
276
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
277
|
+
// CIL[END stable_id="~/.framework/functions/admin-signals.ts:audit:constant"]
|