spine-framework 0.3.124 → 0.3.126
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.framework/cli/commands/agents.ts +35 -37
- package/.framework/cli/commands/auth.ts +35 -34
- package/.framework/cli/commands/create-app.ts +104 -40
- package/.framework/cli/commands/dev.ts +104 -69
- package/.framework/cli/commands/doctor.ts +179 -69
- package/.framework/cli/commands/generate.ts +83 -143
- package/.framework/cli/commands/init.ts +72 -34
- package/.framework/cli/commands/install-app.ts +260 -125
- package/.framework/cli/commands/items.ts +33 -44
- package/.framework/cli/commands/migrate.ts +122 -40
- package/.framework/cli/commands/migrations.ts +33 -40
- package/.framework/cli/commands/pipelines.ts +31 -39
- package/.framework/cli/commands/status.ts +47 -23
- package/.framework/cli/commands/system.ts +47 -37
- package/.framework/cli/commands/test.ts +112 -68
- package/.framework/cli/commands/validate-app.ts +215 -121
- package/.framework/cli/context.ts +112 -130
- package/.framework/cli/env-loader.ts +47 -18
- package/.framework/cli/index.ts +81 -42
- package/.framework/docs/runtime-types.md +1024 -0
- package/.framework/functions/_shared/agent-runner.ts +1296 -961
- package/.framework/functions/_shared/app-manifest.ts +82 -68
- package/.framework/functions/_shared/audit.ts +135 -83
- package/.framework/functions/_shared/{cil-state.ts → cil.ts} +158 -56
- package/.framework/functions/_shared/db.ts +80 -126
- package/.framework/functions/_shared/hash-api-key.ts +63 -0
- package/.framework/functions/_shared/index.ts +224 -335
- package/.framework/functions/_shared/kb.ts +319 -0
- package/.framework/functions/_shared/llm.ts +92 -0
- package/.framework/functions/_shared/logging.ts +288 -0
- package/.framework/functions/_shared/middleware.ts +329 -365
- package/.framework/functions/_shared/outcomes.ts +36 -0
- package/.framework/functions/_shared/permissions.ts +359 -643
- package/.framework/functions/_shared/pipeline-runner.ts +243 -316
- package/.framework/functions/_shared/principal.ts +376 -468
- package/.framework/functions/_shared/resolve-credentials.ts +102 -0
- package/.framework/functions/_shared/resolve-ids.ts +188 -16
- package/.framework/functions/_shared/retry-deliveries.ts +104 -0
- package/.framework/functions/_shared/schema-utils.ts +611 -373
- package/.framework/functions/_shared/testing.ts +207 -137
- package/.framework/functions/_shared/tracing.ts +276 -0
- package/.framework/functions/_shared/trigger-engine.ts +159 -211
- package/.framework/functions/_shared/webhook-registration.ts +95 -81
- package/.framework/functions/_shared/webhook-registry.ts +153 -75
- package/.framework/functions/account-nodes.ts +31 -53
- package/.framework/functions/adapters/generic-webhook-inbound.ts +56 -0
- package/.framework/functions/adapters/generic-webhook-outbound.ts +43 -0
- package/.framework/functions/adapters/openai-outbound.ts +40 -0
- package/.framework/functions/admin-data.ts +685 -537
- package/.framework/functions/admin-funnel.ts +31 -20
- package/.framework/functions/admin-install-funnel.ts +47 -28
- package/.framework/functions/admin-signals.ts +47 -29
- package/.framework/functions/ai-agents.ts +122 -147
- package/.framework/functions/ai-interactions.ts +180 -90
- package/.framework/functions/api-keys.ts +250 -192
- package/.framework/functions/apps.ts +203 -197
- package/.framework/functions/auth.ts +98 -91
- package/.framework/functions/cil-agent-ingest.ts +773 -0
- package/.framework/functions/cil-agent.ts +592 -0
- package/.framework/functions/cil-callmap.ts +1227 -0
- package/.framework/functions/cil-config.ts +583 -0
- package/.framework/functions/cil-context.ts +445 -0
- package/.framework/functions/cil-doc.ts +1752 -0
- package/.framework/functions/cil-embeddings.ts +1202 -0
- package/.framework/functions/cil-graph.ts +585 -0
- package/.framework/functions/cil-ingest.ts +2416 -0
- package/.framework/functions/cil-pipeline.ts +318 -0
- package/.framework/functions/cil-project.ts +499 -0
- package/.framework/functions/cil-validate.ts +469 -0
- package/.framework/functions/debug-auth.ts +73 -53
- package/.framework/functions/deliveries.ts +117 -0
- package/.framework/functions/embeddings.ts +528 -516
- package/.framework/functions/eval-harness.ts +158 -106
- package/.framework/functions/integration-outbound.ts +311 -0
- package/.framework/functions/integration-routes.ts +240 -466
- package/.framework/functions/integrations.ts +132 -140
- package/.framework/functions/invites.ts +401 -201
- package/.framework/functions/item-progress.ts +113 -53
- package/.framework/functions/kb.ts +28 -0
- package/.framework/functions/logs.ts +239 -222
- package/.framework/functions/observability.ts +308 -259
- package/.framework/functions/pipeline-executions.ts +179 -235
- package/.framework/functions/pipelines.ts +163 -205
- package/.framework/functions/prompt-configs.ts +109 -156
- package/.framework/functions/roles.ts +97 -147
- package/.framework/functions/system-cron.ts +132 -218
- package/.framework/functions/system.ts +112 -52
- package/.framework/functions/tests.ts +32 -28
- package/.framework/functions/timers.ts +162 -210
- package/.framework/functions/triggers.ts +282 -346
- package/.framework/functions/types.ts +283 -400
- package/.framework/migrations/001_core_schema.sql +630 -0
- package/.framework/migrations/002_core_rls_and_functions.sql +532 -0
- package/.framework/migrations/{003_system_data.sql → 003_core_system_data.sql} +26 -153
- package/.framework/migrations/004_core_rpc_and_broker.sql +421 -0
- package/.framework/migrations/005_core_observability.sql +598 -0
- package/.framework/migrations/006_security_hardening_rls.sql +97 -0
- package/.framework/migrations/007_kb_article_list.sql +237 -0
- package/.framework/migrations/008_items_target.sql +8 -0
- package/.framework/migrations/009_roles_slug_unique.sql +11 -0
- package/.framework/public/spine.config.json +91 -0
- package/.framework/scripts/app-install-cli.ts +112 -98
- package/.framework/src/App.tsx +67 -20
- package/.framework/src/apps/admin/index.tsx +97 -27
- package/.framework/src/components/AppWrapper.tsx +50 -11
- package/.framework/src/components/CustomAppLoader.tsx +131 -22
- package/.framework/src/components/admin/AdminListPage.tsx +75 -8
- package/.framework/src/components/admin/AdminSidebar.tsx +148 -36
- package/.framework/src/components/admin/AdminStatsCard.tsx +48 -29
- package/.framework/src/components/admin/PageInstructions.tsx +49 -0
- package/.framework/src/components/admin/SortableTableHeader.tsx +49 -2
- package/.framework/src/components/app-shell/GenericAppShell.tsx +69 -11
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +55 -10
- package/.framework/src/components/app-shell/GenericListPage.tsx +76 -9
- package/.framework/src/components/app-sidebar.tsx +50 -3
- package/.framework/src/components/auth/ProtectedRoute.tsx +53 -45
- package/.framework/src/components/kb/KBArticleEditor.tsx +409 -0
- package/.framework/src/components/kb/KBArticleList.tsx +557 -0
- package/.framework/src/components/layout/AppShell.tsx +54 -16
- package/.framework/src/components/layout/Header.tsx +50 -38
- package/.framework/src/components/layout/Layout.tsx +48 -32
- package/.framework/src/components/layout/Sidebar.tsx +167 -16
- package/.framework/src/components/runtime/DataDetailHeader.tsx +33 -1
- package/.framework/src/components/runtime/DataDetailPage.tsx +289 -4
- package/.framework/src/components/runtime/DataFilters.tsx +78 -1
- package/.framework/src/components/runtime/DataHeader.tsx +32 -29
- package/.framework/src/components/runtime/DataListPage.tsx +161 -2
- package/.framework/src/components/runtime/DataStats.tsx +48 -1
- package/.framework/src/components/runtime/DataTable.tsx +153 -1
- package/.framework/src/components/runtime/SchemaDetailForm.tsx +77 -46
- package/.framework/src/components/runtime/index.ts +16 -9
- package/.framework/src/components/search-form.tsx +33 -1
- package/.framework/src/components/shared/AgentView.tsx +48 -51
- package/.framework/src/components/shared/FieldRenderer.tsx +84 -67
- package/.framework/src/components/shared/InviteManager.tsx +113 -52
- package/.framework/src/components/shared/MemberList.tsx +182 -0
- package/.framework/src/components/shared/SchemaFields.tsx +96 -78
- package/.framework/src/components/ui/DataTable.tsx +86 -56
- package/.framework/src/components/ui/Form.tsx +188 -109
- package/.framework/src/components/ui/ItemCard.tsx +86 -58
- package/.framework/src/components/ui/ItemListView.tsx +88 -61
- package/.framework/src/components/ui/LoadingSpinner.tsx +52 -27
- package/.framework/src/components/ui/Modal.tsx +81 -4
- package/.framework/src/components/ui/RichTextEditor.tsx +101 -9
- package/.framework/src/components/ui/accordion.tsx +97 -5
- package/.framework/src/components/ui/alert-dialog.tsx +225 -13
- package/.framework/src/components/ui/alert.tsx +113 -6
- package/.framework/src/components/ui/aspect-ratio.tsx +49 -2
- package/.framework/src/components/ui/avatar.tsx +129 -7
- package/.framework/src/components/ui/badge.tsx +65 -3
- package/.framework/src/components/ui/breadcrumb.tsx +145 -8
- package/.framework/src/components/ui/button-group.tsx +81 -4
- package/.framework/src/components/ui/button.tsx +49 -2
- package/.framework/src/components/ui/calendar.tsx +65 -3
- package/.framework/src/components/ui/card.tsx +145 -8
- package/.framework/src/components/ui/carousel.tsx +129 -7
- package/.framework/src/components/ui/chart.tsx +161 -10
- package/.framework/src/components/ui/checkbox.tsx +49 -2
- package/.framework/src/components/ui/collapsible.tsx +81 -5
- package/.framework/src/components/ui/combobox.tsx +305 -20
- package/.framework/src/components/ui/command.tsx +177 -11
- package/.framework/src/components/ui/context-menu.tsx +273 -17
- package/.framework/src/components/ui/dialog.tsx +209 -27
- package/.framework/src/components/ui/direction.tsx +64 -4
- package/.framework/src/components/ui/drawer.tsx +193 -12
- package/.framework/src/components/ui/dropdown-menu.tsx +273 -18
- package/.framework/src/components/ui/empty.tsx +145 -9
- package/.framework/src/components/ui/field.tsx +209 -14
- package/.framework/src/components/ui/hover-card.tsx +81 -4
- package/.framework/src/components/ui/input-group.tsx +162 -10
- package/.framework/src/components/ui/input-otp.tsx +98 -5
- package/.framework/src/components/ui/input.tsx +49 -2
- package/.framework/src/components/ui/item.tsx +225 -13
- package/.framework/src/components/ui/kbd.tsx +65 -3
- package/.framework/src/components/ui/label.tsx +49 -2
- package/.framework/src/components/ui/menubar.tsx +289 -17
- package/.framework/src/components/ui/native-select.tsx +97 -5
- package/.framework/src/components/ui/navigation-menu.tsx +177 -10
- package/.framework/src/components/ui/pagination.tsx +161 -9
- package/.framework/src/components/ui/popover.tsx +145 -8
- package/.framework/src/components/ui/progress.tsx +49 -2
- package/.framework/src/components/ui/radio-group.tsx +65 -3
- package/.framework/src/components/ui/resizable.tsx +82 -4
- package/.framework/src/components/ui/scroll-area.tsx +65 -3
- package/.framework/src/components/ui/select.tsx +193 -11
- package/.framework/src/components/ui/separator.tsx +49 -2
- package/.framework/src/components/ui/sheet.tsx +193 -11
- package/.framework/src/components/ui/sidebar.tsx +481 -38
- package/.framework/src/components/ui/skeleton.tsx +49 -2
- package/.framework/src/components/ui/slider.tsx +49 -2
- package/.framework/src/components/ui/sonner.tsx +49 -2
- package/.framework/src/components/ui/spinner.tsx +49 -2
- package/.framework/src/components/ui/switch.tsx +49 -2
- package/.framework/src/components/ui/table-primitives.tsx +160 -33
- package/.framework/src/components/ui/table.tsx +161 -9
- package/.framework/src/components/ui/tabs.tsx +113 -6
- package/.framework/src/components/ui/textarea.tsx +49 -2
- package/.framework/src/components/ui/toggle-group.tsx +81 -4
- package/.framework/src/components/ui/toggle.tsx +65 -3
- package/.framework/src/components/ui/tooltip.tsx +97 -5
- package/.framework/src/contexts/AppContext.tsx +129 -45
- package/.framework/src/contexts/AuthContext.tsx +187 -144
- package/.framework/src/hooks/use-mobile.ts +48 -2
- package/.framework/src/hooks/useApi.ts +208 -159
- package/.framework/src/hooks/useAppPath.ts +32 -23
- package/.framework/src/hooks/useApps.ts +51 -20
- package/.framework/src/hooks/useEntityList.ts +32 -78
- package/.framework/src/hooks/useEntityRecord.ts +35 -96
- package/.framework/src/hooks/useForm.ts +32 -92
- package/.framework/src/hooks/useListSchema.ts +49 -78
- package/.framework/src/hooks/useSchemaRecord.ts +114 -105
- package/.framework/src/lib/api.ts +195 -116
- package/.framework/src/lib/supabase.ts +98 -64
- package/.framework/src/lib/utils.ts +287 -151
- package/.framework/src/main.tsx +49 -3
- package/.framework/src/pages/DashboardPage.tsx +52 -29
- package/.framework/src/pages/NotFoundPage.tsx +32 -10
- package/.framework/src/pages/SetupPage.tsx +32 -12
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +119 -10
- package/.framework/src/pages/admin/AIAgentsPage.tsx +48 -19
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +187 -17
- package/.framework/src/pages/admin/APIKeysPage.tsx +98 -22
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +113 -26
- package/.framework/src/pages/admin/AppDetailPage.tsx +125 -8
- package/.framework/src/pages/admin/AppsPage.tsx +49 -2
- package/.framework/src/pages/admin/DeliveriesPage.tsx +196 -0
- package/.framework/src/pages/admin/DesignedPage.tsx +32 -18
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +215 -484
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +116 -319
- package/.framework/src/pages/admin/ExtendedShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IncrementalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/IntegratedDashboard.tsx +32 -16
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +183 -26
- package/.framework/src/pages/admin/IntegrationsPage.tsx +48 -19
- package/.framework/src/pages/admin/InvitesPage.tsx +48 -14
- package/.framework/src/pages/admin/LogsPage.tsx +422 -75
- package/.framework/src/pages/admin/MinimalShadcnTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +113 -24
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +206 -34
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +50 -17
- package/.framework/src/pages/admin/PipelinesPage.tsx +160 -21
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +378 -88
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +125 -16
- package/.framework/src/pages/admin/ProperlyDesignedPage.tsx +49 -10
- package/.framework/src/pages/admin/RoleDetailPage.tsx +130 -10
- package/.framework/src/pages/admin/RolesPage.tsx +171 -18
- package/.framework/src/pages/admin/SelectTestPage.tsx +34 -9
- package/.framework/src/pages/admin/ShadcnTestPage.tsx +49 -11
- package/.framework/src/pages/admin/SimpleDashboard.tsx +49 -10
- package/.framework/src/pages/admin/TestRunDetailPage.tsx +49 -4
- package/.framework/src/pages/admin/TestingDashboard.tsx +98 -28
- package/.framework/src/pages/admin/TimerDetailPage.tsx +143 -33
- package/.framework/src/pages/admin/TimersPage.tsx +48 -20
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +118 -30
- package/.framework/src/pages/admin/TriggersPage.tsx +64 -19
- package/.framework/src/pages/admin/TypeDetailPage.tsx +138 -15
- package/.framework/src/pages/admin/TypesPage.tsx +48 -20
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +465 -0
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +787 -0
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +699 -0
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +647 -0
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +616 -0
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +1402 -0
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +614 -0
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +571 -0
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +731 -0
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +64 -0
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +52 -51
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +31 -22
- package/.framework/src/pages/auth/LoginPage.tsx +50 -23
- package/.framework/src/pages/auth/PendingApprovalPage.tsx +31 -15
- package/.framework/src/pages/auth/RegisterPage.tsx +281 -317
- package/.framework/src/pages/spine-framework/APIPage.tsx +33 -0
- package/.framework/src/pages/spine-framework/CLIPage.tsx +33 -0
- package/.framework/src/types/auth.ts +128 -71
- package/.framework/src/types/types.ts +373 -157
- package/custom/.devin/skills/spine-workbench-discovery/SKILL.md +39 -0
- package/custom/.devin/skills/spine-workbench-idea/SKILL.md +36 -0
- package/custom/.devin/skills/spine-workbench-implement/SKILL.md +46 -0
- package/custom/.devin/skills/spine-workbench-initiative/SKILL.md +28 -0
- package/custom/.devin/skills/spine-workbench-plan/SKILL.md +38 -0
- package/docs/README.md +9 -130
- package/netlify.toml +5 -2
- package/package.json +13 -25
- package/scripts/kb-ingest-docs.ts +203 -0
- package/spine.config.json +65 -4
- package/.framework/migrations/001_schema.sql +0 -425
- package/.framework/migrations/002_rls_and_functions.sql +0 -763
- package/.framework/migrations/004_enhancements.sql +0 -43
- package/.framework/migrations/005_auth_user_trigger.sql +0 -105
- package/.framework/migrations/006_fix_current_actor_id.sql +0 -21
- package/.framework/migrations/016_invites.sql +0 -27
- package/.framework/migrations/017_fix_get_account_apps.sql +0 -78
- package/.framework/migrations/018_apps_required_roles.sql +0 -17
- package/.framework/migrations/019_triggers_unique_constraint.sql +0 -13
- package/.framework/migrations/020_get_account_apps_role_filter.sql +0 -117
- package/.framework/migrations/021_app_domains.sql +0 -112
- package/.framework/migrations/022_route_prefix_domain_unique.sql +0 -21
- package/.framework/migrations/023_match_embeddings_rpc.sql +0 -78
- package/.framework/migrations/024_messages_account_id.sql +0 -9
- package/.framework/migrations/025_retype_threads_messages.sql +0 -240
- package/.framework/migrations/026_fix_rls_policies.sql +0 -47
- package/.framework/migrations/027_embedding_lifecycle.sql +0 -176
- package/.framework/migrations/028_fix_message_data_permissions.sql +0 -49
- package/.framework/migrations/029_tighten_support_triage_prompt.sql +0 -41
- package/.framework/migrations/030_messages_updated_by.sql +0 -6
- package/.framework/migrations/031_seed_upsert_constraints.sql +0 -35
- package/docs/APPS.md +0 -232
- package/docs/ARCHITECTURE.md +0 -246
- package/docs/INSTALL.md +0 -155
- package/docs/design-schema-spec.md +0 -1837
- package/docs/dev-guides/01-create-an-app.md +0 -183
- package/docs/dev-guides/02-create-a-function.md +0 -178
- package/docs/dev-guides/03-create-a-component.md +0 -178
- package/docs/dev-guides/04-webhook-handlers.md +0 -129
- package/docs/dev-guides/05-testing.md +0 -168
- package/docs/dev-guides/README.md +0 -40
- package/docs/npm-packages-plan.md +0 -288
- package/docs/spine-core--api-reference.md +0 -822
|
@@ -1,87 +1,147 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/lib/api
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-hook
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Authenticated fetch wrapper and account context for all Spine frontend
|
|
8
|
-
* API calls. Injects the Supabase JWT and `X-Account-Id` header into every
|
|
9
|
-
* request made via `apiFetch`.
|
|
10
|
-
*
|
|
11
|
-
* **Account context** is a module-level singleton set once after login:
|
|
12
|
-
* ```ts
|
|
13
|
-
* setAccountId(ctx.account_id) // called in AuthContext after auth.context()
|
|
14
|
-
* ```
|
|
15
|
-
* All subsequent `apiFetch` calls include `X-Account-Id` automatically.
|
|
16
|
-
*
|
|
17
|
-
* **401 interceptor:** Register a callback via `onUnauthorized(cb)` to be
|
|
18
|
-
* notified when any non-auth API call returns 401. AuthContext uses this to
|
|
19
|
-
* trigger logout when the session expires mid-use.
|
|
20
|
-
*
|
|
21
|
-
* INVARIANT: Call `setAccountId` before making any authenticated API requests.
|
|
22
|
-
* If `_accountId` is null, the backend may reject scoped requests.
|
|
23
|
-
*
|
|
24
|
-
* @seeAlso src/lib/supabase.ts (supabase client used for getSession)
|
|
25
|
-
* @seeAlso src/hooks/useApi.ts (wraps apiFetch with React state management)
|
|
26
|
-
* @seeAlso src/contexts/AuthContext.tsx (calls setAccountId after login)
|
|
27
|
-
*/
|
|
28
1
|
|
|
29
|
-
import { supabase } from './supabase'
|
|
30
2
|
|
|
31
|
-
// ─── ACCOUNT CONTEXT ─────────────────────────────────────────────────────────
|
|
32
3
|
|
|
33
|
-
let _accountId: string | null = null
|
|
34
4
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
// CIL[BEGIN chunk_id="api_imports_1783716639" type="module_header" identity="imports" parent="none"]
|
|
12
|
+
// CIL[DOC-MACRO purpose="Import Supabase client for authentication"]
|
|
13
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide Supabase client dependency"]
|
|
14
|
+
// CIL[DOC-CONTEXT module="api" layer="utility" 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\",\"\\\"]"]
|
|
15
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="supabase client" errors="none" side_effects="none"]
|
|
16
|
+
// CIL[DOC-MICRO logic_summary="Import statement for external dependency" notable_decisions="[]"]
|
|
17
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
18
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
19
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
20
|
+
// CIL[DOC-VECTOR type="context" content="Layer: utility. 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, \."]
|
|
21
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
22
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
23
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
24
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
25
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
26
|
+
import { supabase } from './supabase'
|
|
27
|
+
// CIL[END chunk_id="api_imports_1783716639"]
|
|
28
|
+
// CIL[BEGIN chunk_id="api__accountid_1783716639" type="variable" identity="_accountId" parent="none"]
|
|
29
|
+
// CIL[DOC-MACRO purpose="Store current account context"]
|
|
30
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Maintain account ID state"]
|
|
31
|
+
// CIL[DOC-CONTEXT module="api" layer="state" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
32
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="account ID storage" errors="none" side_effects="state_modification"]
|
|
33
|
+
// CIL[DOC-MICRO logic_summary="Module-level variable for account context" notable_decisions="[]"]
|
|
34
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
35
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
36
|
+
// CIL[DOC-VECTOR type="context" content="Layer: state. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
37
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
38
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
39
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
40
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
41
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
42
|
+
let _accountId: string | null = null
|
|
43
|
+
// CIL[END chunk_id="api__accountid_1783716639"]
|
|
44
|
+
// CIL[BEGIN chunk_id="api_setaccountid_1783716639" type="function" identity="setAccountId" parent="none"]
|
|
45
|
+
// CIL[DOC-MACRO purpose="Set current account context"]
|
|
46
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Update account ID state"]
|
|
47
|
+
// CIL[DOC-CONTEXT module="api" layer="state" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
48
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="state_modification"]
|
|
49
|
+
// CIL[DOC-MICRO logic_summary="Assign account ID to module variable" notable_decisions="[]"]
|
|
50
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
51
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
52
|
+
// CIL[DOC-VECTOR type="context" content="Layer: state. Direct callers: 1. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
53
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 1. Total affected: 1."]
|
|
54
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
55
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
56
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
57
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
43
58
|
export function setAccountId(id: string | null) {
|
|
44
59
|
_accountId = id
|
|
45
60
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
61
|
+
// CIL[END chunk_id="api_setaccountid_1783716639"]
|
|
62
|
+
// CIL[BEGIN chunk_id="api_getaccountid_1783716639" type="function" identity="getAccountId" parent="none"]
|
|
63
|
+
// CIL[DOC-MACRO purpose="Get current account context"]
|
|
64
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Retrieve account ID state"]
|
|
65
|
+
// CIL[DOC-CONTEXT module="api" layer="state" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
66
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="account_id: string|null" errors="none" side_effects="none"]
|
|
67
|
+
// CIL[DOC-MICRO logic_summary="Return account ID from module variable" notable_decisions="[]"]
|
|
68
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
69
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
70
|
+
// CIL[DOC-VECTOR type="context" content="Layer: state. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
71
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
72
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
73
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
74
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
75
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
54
76
|
export function getAccountId(): string | null {
|
|
55
77
|
return _accountId
|
|
56
78
|
}
|
|
57
|
-
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
79
|
+
// CIL[END chunk_id="api_getaccountid_1783716639"]
|
|
80
|
+
// CIL[BEGIN chunk_id="api_authpaths_1783716639" type="variable" identity="AUTH_PATHS" parent="none"]
|
|
81
|
+
// CIL[DOC-MACRO purpose="Define authentication API endpoints"]
|
|
82
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Maintain auth path configuration"]
|
|
83
|
+
// CIL[DOC-CONTEXT module="api" layer="config" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\"\\\"]"]
|
|
84
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="auth paths array" errors="none" side_effects="none"]
|
|
85
|
+
// CIL[DOC-MICRO logic_summary="Constant array of auth endpoint paths" notable_decisions="[]"]
|
|
86
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
87
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
88
|
+
// CIL[DOC-VECTOR type="context" content="Layer: config. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, .framework/functions/_shared/schema-utils.ts, custom/apps/cortex/functions/custom_cil-embeddings.ts, \."]
|
|
89
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
90
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
91
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
92
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
93
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
94
|
+
const AUTH_PATHS = ['/api/auth', '/api/admin-data']
|
|
95
|
+
// CIL[END chunk_id="api_authpaths_1783716639"]
|
|
96
|
+
// CIL[BEGIN chunk_id="api__unauthorizedcallback_1783716639" type="variable" identity="_onUnauthorizedCallback" parent="none"]
|
|
97
|
+
// CIL[DOC-MACRO purpose="Store unauthorized response handler"]
|
|
98
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Maintain callback state for 401 errors"]
|
|
99
|
+
// CIL[DOC-CONTEXT module="api" layer="state" related_files="[]"]
|
|
100
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="callback storage" errors="none" side_effects="state_modification"]
|
|
101
|
+
// CIL[DOC-MICRO logic_summary="Module-level variable for unauthorized callback" notable_decisions="[]"]
|
|
102
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
103
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
104
|
+
// CIL[DOC-VECTOR type="context" content="Layer: state. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
105
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
106
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
107
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
108
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
109
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
63
110
|
let _onUnauthorizedCallback: (() => void) | null = null
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
111
|
+
// CIL[END chunk_id="api__unauthorizedcallback_1783716639"]
|
|
112
|
+
// CIL[BEGIN chunk_id="api_onunauthorized_1783716639" type="function" identity="onUnauthorized" parent="none"]
|
|
113
|
+
// CIL[DOC-MACRO purpose="Register unauthorized response handler"]
|
|
114
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Manage 401 error callback lifecycle"]
|
|
115
|
+
// CIL[DOC-CONTEXT module="api" layer="error_handling" related_files="[]"]
|
|
116
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="cleanup: () => void" errors="none" side_effects="state_modification"]
|
|
117
|
+
// CIL[DOC-MICRO logic_summary="Set callback and return cleanup function" notable_decisions="[]"]
|
|
118
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
119
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
120
|
+
// CIL[DOC-VECTOR type="context" content="Layer: error_handling. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
121
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
122
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
123
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
124
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
125
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
73
126
|
export function onUnauthorized(cb: () => void): () => void {
|
|
74
127
|
_onUnauthorizedCallback = cb
|
|
75
128
|
return () => { _onUnauthorizedCallback = null }
|
|
76
129
|
}
|
|
77
|
-
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
130
|
+
// CIL[END chunk_id="api_onunauthorized_1783716639"]
|
|
131
|
+
// CIL[BEGIN chunk_id="api_normalizeheaders_1783716639" type="function" identity="normalizeHeaders" parent="none"]
|
|
132
|
+
// CIL[DOC-MACRO purpose="Convert headers to plain object format"]
|
|
133
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Normalize header data structures"]
|
|
134
|
+
// CIL[DOC-CONTEXT module="api" layer="utility" related_files="[]"]
|
|
135
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Record<string,string>" errors="none" side_effects="none"]
|
|
136
|
+
// CIL[DOC-MICRO logic_summary="Handle Headers, array, and object formats" notable_decisions="[]"]
|
|
137
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
138
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
139
|
+
// CIL[DOC-VECTOR type="context" content="Layer: utility. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
140
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
141
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
142
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
143
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
144
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
85
145
|
function normalizeHeaders(headers?: HeadersInit): Record<string, string> {
|
|
86
146
|
if (!headers) return {}
|
|
87
147
|
|
|
@@ -97,27 +157,29 @@ function normalizeHeaders(headers?: HeadersInit): Record<string, string> {
|
|
|
97
157
|
Object.entries(headers).map(([key, value]) => [key, String(value)])
|
|
98
158
|
)
|
|
99
159
|
}
|
|
100
|
-
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
160
|
+
// CIL[END chunk_id="api_normalizeheaders_1783716639"]
|
|
161
|
+
// CIL[BEGIN chunk_id="api_getauthheaders_1783716639" type="function" identity="getAuthHeaders" parent="none"]
|
|
162
|
+
// CIL[DOC-MACRO purpose="Build authentication headers for API requests"]
|
|
163
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Generate auth and account context headers"]
|
|
164
|
+
// CIL[DOC-CONTEXT module="api" layer="auth" related_files="[]"]
|
|
165
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Record<string,string>" errors="supabase_errors" side_effects="none"]
|
|
166
|
+
// CIL[DOC-MICRO logic_summary="Get session token and add account ID to headers" notable_decisions="[]"]
|
|
167
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
168
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
169
|
+
// CIL[DOC-VECTOR type="context" content="Layer: auth. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
170
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
171
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
172
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
173
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
174
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
115
175
|
export async function getAuthHeaders(): Promise<Record<string, string>> {
|
|
116
176
|
const headers: Record<string, string> = {}
|
|
117
177
|
|
|
118
178
|
const { data: { session } } = await supabase.auth.getSession()
|
|
119
179
|
if (session?.access_token) {
|
|
120
180
|
headers['Authorization'] = `Bearer ${session.access_token}`
|
|
181
|
+
} else {
|
|
182
|
+
|
|
121
183
|
}
|
|
122
184
|
|
|
123
185
|
if (_accountId) {
|
|
@@ -126,38 +188,43 @@ export async function getAuthHeaders(): Promise<Record<string, string>> {
|
|
|
126
188
|
|
|
127
189
|
return headers
|
|
128
190
|
}
|
|
191
|
+
// CIL[END chunk_id="api_getauthheaders_1783716639"]
|
|
192
|
+
// CIL[BEGIN chunk_id="api_apifetch_1783716639" type="function" identity="apiFetch" parent="none"]
|
|
193
|
+
// CIL[DOC-MACRO purpose="Authenticated HTTP request wrapper"]
|
|
194
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Handle API requests with auth and error handling"]
|
|
195
|
+
// CIL[DOC-CONTEXT module="api" layer="client" related_files="[]"]
|
|
196
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Response" errors="network_errors" side_effects="callback_execution"]
|
|
197
|
+
// CIL[DOC-MICRO logic_summary="Add auth headers, clean invalid tokens, handle 401s" notable_decisions="[]"]
|
|
198
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
199
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
200
|
+
// CIL[DOC-VECTOR type="context" content="Layer: client. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
201
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
202
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
203
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
204
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
205
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
206
|
+
let _sessionTraceId: string | null = null
|
|
207
|
+
let _sessionTraceState: string = ''
|
|
208
|
+
|
|
209
|
+
function generateHexId(length: number): string {
|
|
210
|
+
const uuid = crypto.randomUUID().replace(/-/g, '')
|
|
211
|
+
if (length > uuid.length) {
|
|
212
|
+
return (uuid + crypto.randomUUID().replace(/-/g, '')).slice(0, length).toLowerCase()
|
|
213
|
+
}
|
|
214
|
+
return uuid.slice(0, length).toLowerCase()
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
function getSessionTraceId(): string {
|
|
218
|
+
if (!_sessionTraceId) {
|
|
219
|
+
_sessionTraceId = generateHexId(32)
|
|
220
|
+
}
|
|
221
|
+
return _sessionTraceId
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
function buildTraceParent(): string {
|
|
225
|
+
return `00-${getSessionTraceId()}-${generateHexId(16)}-01`
|
|
226
|
+
}
|
|
129
227
|
|
|
130
|
-
// ─── FETCH WRAPPER ────────────────────────────────────────────────────────────────
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* Authenticated fetch wrapper. Injects `Authorization` + `X-Account-Id`
|
|
134
|
-
* headers, strips invalid Bearer values (`null`/`undefined`/empty), and
|
|
135
|
-
* forwards all other options (including `signal` for AbortController).
|
|
136
|
-
*
|
|
137
|
-
* If a non-auth endpoint returns 401, the registered `onUnauthorized`
|
|
138
|
-
* callback fires (typically triggers logout).
|
|
139
|
-
*
|
|
140
|
-
* Use this for ALL Spine API calls from the frontend. Never call `fetch`
|
|
141
|
-
* directly for API routes.
|
|
142
|
-
*
|
|
143
|
-
* @param path - API path, e.g. `'/.netlify/functions/items'`
|
|
144
|
-
* @param options - Standard `RequestInit` options (method, body, signal, etc.)
|
|
145
|
-
* @returns Raw `Response` — callers must check `response.ok` / status
|
|
146
|
-
* @throws Network errors from `fetch` (e.g. `TypeError: Failed to fetch`)
|
|
147
|
-
* @inputSpec path: string — relative URL to a Netlify function
|
|
148
|
-
* @inputSpec options.signal: AbortSignal | undefined — forwarded for cancellation
|
|
149
|
-
* @outputSpec Response — with auth headers injected; not yet parsed
|
|
150
|
-
* @sideEffects Network request; reads localStorage via getAuthHeaders;
|
|
151
|
-
* may trigger onUnauthorized callback on 401
|
|
152
|
-
* @calledBy src/hooks/useApi.ts, useEntityList.ts, useEntityRecord.ts
|
|
153
|
-
*
|
|
154
|
-
* @example
|
|
155
|
-
* ```ts
|
|
156
|
-
* const res = await apiFetch('/.netlify/functions/items?action=list')
|
|
157
|
-
* if (!res.ok) throw new Error(await res.text())
|
|
158
|
-
* const { data } = await res.json()
|
|
159
|
-
* ```
|
|
160
|
-
*/
|
|
161
228
|
export async function apiFetch(path: string, options: RequestInit = {}): Promise<Response> {
|
|
162
229
|
const authHeaders = await getAuthHeaders()
|
|
163
230
|
const optionHeaders = normalizeHeaders(options.headers)
|
|
@@ -171,17 +238,28 @@ export async function apiFetch(path: string, options: RequestInit = {}): Promise
|
|
|
171
238
|
delete optionHeaders.authorization
|
|
172
239
|
}
|
|
173
240
|
|
|
241
|
+
const traceparent = buildTraceParent()
|
|
242
|
+
|
|
174
243
|
const fetchOptions = {
|
|
175
244
|
...options,
|
|
176
245
|
headers: {
|
|
177
246
|
...authHeaders,
|
|
178
247
|
...optionHeaders,
|
|
248
|
+
traceparent,
|
|
179
249
|
},
|
|
180
250
|
}
|
|
181
251
|
|
|
182
252
|
const response = await fetch(path, fetchOptions)
|
|
183
253
|
|
|
184
|
-
|
|
254
|
+
const requestId = response.headers.get('X-Request-ID') || response.headers.get('x-request-id')
|
|
255
|
+
const responseTraceparent = response.headers.get('traceparent') || response.headers.get('Traceparent')
|
|
256
|
+
if (requestId) {
|
|
257
|
+
console.log('[Spine] requestId:', requestId, 'traceparent:', responseTraceparent || traceparent)
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
const responseTracestate = response.headers.get('tracestate') || response.headers.get('Tracestate')
|
|
261
|
+
if (responseTracestate) _sessionTraceState = responseTracestate
|
|
262
|
+
|
|
185
263
|
if (response.status === 401 && _onUnauthorizedCallback) {
|
|
186
264
|
const isAuthPath = AUTH_PATHS.some(p => path.startsWith(p))
|
|
187
265
|
if (!isAuthPath) {
|
|
@@ -191,3 +269,4 @@ export async function apiFetch(path: string, options: RequestInit = {}): Promise
|
|
|
191
269
|
|
|
192
270
|
return response
|
|
193
271
|
}
|
|
272
|
+
// CIL[END chunk_id="api_apifetch_1783716639"]
|
|
@@ -1,94 +1,128 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/lib/supabase
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-hook
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Browser-side Supabase client singleton and session helpers for the Spine
|
|
8
|
-
* frontend. Reads `VITE_SUPABASE_URL` and `VITE_SUPABASE_ANON_KEY` from
|
|
9
|
-
* Vite env at build time; throws immediately on missing values so
|
|
10
|
-
* misconfigured builds fail loudly rather than silently.
|
|
11
|
-
*
|
|
12
|
-
* INVARIANT: `supabase` is a module-level singleton — do not call
|
|
13
|
-
* `createClient` again in components or hooks. Import this module instead.
|
|
14
|
-
*
|
|
15
|
-
* @seeAlso src/lib/api.ts (uses supabase.auth.getSession for apiFetch headers)
|
|
16
|
-
* @seeAlso src/contexts/AuthContext.tsx (wraps supabase.auth for React state)
|
|
17
|
-
*/
|
|
18
1
|
|
|
19
|
-
import { createClient } from '@supabase/supabase-js'
|
|
20
2
|
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
// CIL[BEGIN chunk_id="supabase_module_header_1783672456" type="module_header" identity="imports" parent="none"]
|
|
8
|
+
// CIL[DOC-MACRO purpose="Import Supabase client"]
|
|
9
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Import Supabase client factory"]
|
|
10
|
+
// CIL[DOC-CONTEXT module="supabase" layer="frontend-hook" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"\\\"]"]
|
|
11
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="createClient function" errors="none" side_effects="none"]
|
|
12
|
+
// CIL[DOC-MICRO logic_summary="Imports Supabase client creation function" notable_decisions="[]"]
|
|
13
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
14
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
15
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
16
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, \."]
|
|
17
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
18
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
19
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
20
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
21
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
22
|
+
import { createClient } from '@supabase/supabase-js'
|
|
23
|
+
// CIL[END chunk_id="supabase_module_header_1783672456"]
|
|
24
|
+
// CIL[BEGIN chunk_id="supabase_envvars_1783672456" type="variable" identity="environmentVariables" parent="none"]
|
|
25
|
+
// CIL[DOC-MACRO purpose="Load Supabase environment variables"]
|
|
26
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Validate and store Supabase config"]
|
|
27
|
+
// CIL[DOC-CONTEXT module="supabase" layer="frontend-hook" related_files="[\"\\\"]"]
|
|
28
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Environment variables" errors="Error on missing vars" side_effects="May throw error"]
|
|
29
|
+
// CIL[DOC-MICRO logic_summary="Loads and validates required Supabase env vars" notable_decisions="[]"]
|
|
30
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
31
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
32
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: \."]
|
|
33
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
34
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
35
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
36
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
37
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
21
38
|
const supabaseUrl = import.meta.env.VITE_SUPABASE_URL
|
|
22
39
|
const supabaseAnonKey = import.meta.env.VITE_SUPABASE_ANON_KEY
|
|
23
40
|
|
|
24
41
|
if (!supabaseUrl || !supabaseAnonKey) {
|
|
25
42
|
throw new Error('Missing Supabase environment variables')
|
|
26
43
|
}
|
|
27
|
-
|
|
28
|
-
//
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
44
|
+
// CIL[END chunk_id="supabase_envvars_1783672456"]
|
|
45
|
+
// CIL[BEGIN chunk_id="supabase_client_1783672456" type="variable" identity="supabase" parent="none"]
|
|
46
|
+
// CIL[DOC-MACRO purpose="Create Supabase client singleton"]
|
|
47
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Initialize Supabase client with auth config"]
|
|
48
|
+
// CIL[DOC-CONTEXT module="supabase" layer="frontend-hook" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\"\\\"]"]
|
|
49
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Supabase client instance" errors="none" side_effects="Reads localStorage"]
|
|
50
|
+
// CIL[DOC-MICRO logic_summary="Configures session persistence, auto-refresh, and a no-op auth lock to bypass navigator.locks" notable_decisions="[]"]
|
|
51
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
52
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
53
|
+
// CIL[DOC-NOTE type="caution" content="No-op lock bypasses navigator.locks to avoid NavigatorLockAcquireTimeoutError during login"]
|
|
54
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, .framework/src/components/ui/dialog.tsx, \."]
|
|
55
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
56
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
57
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
58
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
59
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
42
60
|
export const supabase = createClient(supabaseUrl, supabaseAnonKey, {
|
|
43
61
|
auth: {
|
|
44
62
|
persistSession: true,
|
|
45
63
|
autoRefreshToken: true,
|
|
46
64
|
detectSessionInUrl: true,
|
|
65
|
+
lock: async <T>(_name: string, _acquireTimeout: number, fn: () => Promise<T>): Promise<T> => await fn(),
|
|
47
66
|
},
|
|
48
67
|
})
|
|
49
|
-
|
|
50
|
-
//
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
// CIL[END chunk_id="supabase_client_1783672456"]
|
|
69
|
+
// CIL[BEGIN chunk_id="supabase_getcurrentsession_1783672456" type="function" identity="getCurrentSession" parent="none"]
|
|
70
|
+
// CIL[DOC-MACRO purpose="Get current Supabase session"]
|
|
71
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Retrieve active auth session"]
|
|
72
|
+
// CIL[DOC-CONTEXT module="supabase" layer="frontend-hook" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
73
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Session object or null" errors="Supabase AuthError" side_effects="Reads localStorage"]
|
|
74
|
+
// CIL[DOC-MICRO logic_summary="Calls Supabase getSession and handles errors" notable_decisions="[]"]
|
|
75
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
76
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
77
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
78
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
79
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
80
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
81
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
82
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
60
83
|
export const getCurrentSession = async () => {
|
|
61
84
|
const { data: { session }, error } = await supabase.auth.getSession()
|
|
62
85
|
if (error) throw error
|
|
63
86
|
return session
|
|
64
87
|
}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
88
|
+
// CIL[END chunk_id="supabase_getcurrentsession_1783672456"]
|
|
89
|
+
// CIL[BEGIN chunk_id="supabase_getcurrentuser_1783672456" type="function" identity="getCurrentUser" parent="none"]
|
|
90
|
+
// CIL[DOC-MACRO purpose="Get current Supabase user"]
|
|
91
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Retrieve authenticated user data"]
|
|
92
|
+
// CIL[DOC-CONTEXT module="supabase" layer="frontend-hook" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
93
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="User object or null" errors="Supabase AuthError" side_effects="Reads localStorage"]
|
|
94
|
+
// CIL[DOC-MICRO logic_summary="Calls Supabase getUser and handles errors" notable_decisions="[]"]
|
|
95
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
96
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
97
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
98
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
99
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
100
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
101
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
102
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
74
103
|
export const getCurrentUser = async () => {
|
|
75
104
|
const { data: { user }, error } = await supabase.auth.getUser()
|
|
76
105
|
if (error) throw error
|
|
77
106
|
return user
|
|
78
107
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
108
|
+
// CIL[END chunk_id="supabase_getcurrentuser_1783672456"]
|
|
109
|
+
// CIL[BEGIN chunk_id="supabase_refreshsession_1783672456" type="function" identity="refreshSession" parent="none"]
|
|
110
|
+
// CIL[DOC-MACRO purpose="Refresh Supabase session"]
|
|
111
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Force session token refresh"]
|
|
112
|
+
// CIL[DOC-CONTEXT module="supabase" layer="frontend-hook" related_files="[]"]
|
|
113
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Session data" errors="Supabase AuthError" side_effects="Updates localStorage"]
|
|
114
|
+
// CIL[DOC-MICRO logic_summary="Calls Supabase refreshSession and handles errors" notable_decisions="[]"]
|
|
115
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
116
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
117
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-hook. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
118
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
119
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
120
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
121
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
122
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
90
123
|
export const refreshSession = async () => {
|
|
91
124
|
const { data, error } = await supabase.auth.refreshSession()
|
|
92
125
|
if (error) throw error
|
|
93
126
|
return data
|
|
94
127
|
}
|
|
128
|
+
// CIL[END chunk_id="supabase_refreshsession_1783672456"]
|