spine-framework 0.4.3 → 0.5.0-rc.4
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 +13 -3
- package/.framework/cli/commands/bootstrap.ts +392 -0
- package/.framework/cli/commands/dev.ts +91 -218
- package/.framework/cli/commands/doctor.ts +132 -26
- package/.framework/cli/commands/generate.ts +38 -298
- package/.framework/cli/commands/init.ts +20 -1
- package/.framework/cli/commands/migrate.ts +36 -30
- package/.framework/cli/commands/migrations.ts +16 -56
- package/.framework/cli/commands/upgrade.ts +35 -0
- package/.framework/cli/commands/validate-schema.ts +147 -0
- package/.framework/cli/context.ts +223 -110
- package/.framework/cli/index.ts +6 -0
- package/.framework/cli/lib/project-files.ts +241 -1
- package/.framework/functions/_shared/agent-runner.ts +1000 -81
- package/.framework/functions/_shared/cil.ts +2 -1
- package/.framework/functions/_shared/db.ts +3 -6
- package/.framework/functions/_shared/hash-api-key.ts +183 -79
- package/.framework/functions/_shared/kb.ts +61 -7
- package/.framework/functions/_shared/logging.ts +562 -224
- package/.framework/functions/_shared/message-sequence.ts +53 -0
- package/.framework/functions/_shared/middleware.ts +47 -44
- package/.framework/functions/_shared/pipeline-runner.ts +150 -37
- package/.framework/functions/_shared/principal.ts +9 -6
- package/.framework/functions/_shared/trigger-engine.ts +149 -40
- package/.framework/functions/admin-data.ts +48 -31
- package/.framework/functions/ai-agents.ts +103 -33
- package/.framework/functions/api-keys.ts +301 -122
- package/.framework/functions/apps.ts +43 -26
- package/.framework/functions/cil-ingest.ts +48 -15
- package/.framework/functions/debug-auth.ts +14 -8
- package/.framework/functions/deliveries.ts +39 -12
- package/.framework/functions/embeddings.ts +145 -76
- package/.framework/functions/integration-outbound.ts +67 -27
- package/.framework/functions/integrations.ts +254 -127
- package/.framework/functions/logs.ts +273 -133
- package/.framework/functions/observability.ts +277 -147
- package/.framework/functions/pipeline-executions.ts +1 -1
- package/.framework/functions/pipeline-runner-background.ts +120 -0
- package/.framework/functions/pipelines.ts +14 -9
- package/.framework/functions/prompt-configs.ts +7 -4
- package/.framework/functions/roles.ts +8 -5
- package/.framework/functions/security.ts +30 -17
- package/.framework/functions/system-cron.ts +250 -128
- package/.framework/functions/tests.ts +7 -6
- package/.framework/functions/timers.ts +310 -107
- package/.framework/functions/trigger-scheduler.ts +65 -5
- package/.framework/functions/triggers.ts +28 -13
- package/.framework/functions/types.ts +13 -10
- package/.framework/migrations/064_episode_leases.sql +196 -0
- package/.framework/migrations/065_execution_tables_updated_at.sql +20 -0
- package/.framework/migrations/066_episode_steal_thread_merge.sql +148 -0
- package/.framework/migrations/067_episode_lease_stale_steal.sql +93 -0
- package/.framework/migrations/068_cron_schedule_timer_rpcs.sql +251 -0
- package/.framework/migrations/069_log_stats_window.sql +54 -0
- package/.framework/migrations/070_app_type_schema_rpcs.sql +166 -0
- package/.framework/migrations/071_timer_interval_keys.sql +96 -0
- package/.framework/migrations/072_slug_autofill.sql +77 -0
- package/.framework/migrations/073_seed_member_roles.sql +26 -0
- package/.framework/schemas/spine.config.schema.json +62 -0
- package/.framework/src/App.tsx +3 -1
- package/.framework/src/apps/admin/index.tsx +1141 -775
- package/.framework/src/components/ErrorBoundary.tsx +136 -0
- package/.framework/src/components/admin/AdminListPage.tsx +81 -73
- package/.framework/src/components/admin/AdminSidebar.tsx +92 -81
- package/.framework/src/components/admin/EntitySelect.tsx +181 -0
- package/.framework/src/components/admin/PageInstructions.tsx +86 -127
- package/.framework/src/components/app-shell/GenericAppShell.tsx +3 -1
- package/.framework/src/components/app-shell/GenericDetailPage.tsx +37 -13
- package/.framework/src/components/app-shell/GenericListPage.tsx +28 -32
- package/.framework/src/components/auth/TurnstileWidget.tsx +9 -6
- package/.framework/src/components/kb/KBArticleEditor.tsx +49 -6
- package/.framework/src/components/layout/Layout.tsx +4 -2
- package/.framework/src/components/layout/Sidebar.tsx +304 -179
- package/.framework/src/components/runtime/DataDetailPage.tsx +67 -35
- package/.framework/src/components/runtime/DataHeader.tsx +96 -48
- package/.framework/src/components/runtime/DataListPage.tsx +3 -26
- package/.framework/src/components/runtime/DataStats.tsx +10 -10
- package/.framework/src/components/runtime/DataTable.tsx +12 -10
- package/.framework/src/components/ui/sheet.tsx +24 -26
- package/.framework/src/components/ui/textarea.tsx +74 -48
- package/.framework/src/hooks/useBranding.ts +47 -0
- package/.framework/src/hooks/useEntityList.ts +12 -9
- package/.framework/src/hooks/useListSchema.ts +108 -58
- package/.framework/src/instructions/README.md +57 -0
- package/.framework/src/instructions/ai-agents.md +69 -0
- package/.framework/src/instructions/alerts.md +80 -0
- package/.framework/src/instructions/api-keys.md +87 -0
- package/.framework/src/instructions/apps.md +77 -0
- package/.framework/src/instructions/concepts/ai-and-prompts.md +150 -0
- package/.framework/src/instructions/concepts/apps-and-renderers.md +162 -0
- package/.framework/src/instructions/concepts/auth-and-api-keys.md +133 -0
- package/.framework/src/instructions/concepts/automation.md +186 -0
- package/.framework/src/instructions/concepts/concurrency-and-idempotency.md +125 -0
- package/.framework/src/instructions/concepts/core-vs-custom.md +124 -0
- package/.framework/src/instructions/concepts/design-schema.md +152 -0
- package/.framework/src/instructions/concepts/integrations-and-webhooks.md +127 -0
- package/.framework/src/instructions/concepts/observability.md +116 -0
- package/.framework/src/instructions/concepts/permissions.md +150 -0
- package/.framework/src/instructions/concepts/runtime-records.md +111 -0
- package/.framework/src/instructions/concepts/scope-and-accounts.md +112 -0
- package/.framework/src/instructions/concepts/spine-way.md +172 -0
- package/.framework/src/instructions/deliveries.md +59 -0
- package/.framework/src/instructions/guide/00-orientation.md +106 -0
- package/.framework/src/instructions/guide/01-install-and-first-run.md +253 -0
- package/.framework/src/instructions/guide/02-project-map.md +147 -0
- package/.framework/src/instructions/guide/03-domain-model.md +223 -0
- package/.framework/src/instructions/guide/04-first-app.md +227 -0
- package/.framework/src/instructions/guide/05-glossary.md +183 -0
- package/.framework/src/instructions/integrations.md +96 -0
- package/.framework/src/instructions/internal/cil-markers.md +83 -0
- package/.framework/src/instructions/invites.md +60 -0
- package/.framework/src/instructions/kb.md +80 -0
- package/.framework/src/instructions/logs.md +77 -0
- package/.framework/src/instructions/observability.md +61 -0
- package/.framework/src/instructions/operations/deployment.md +115 -0
- package/.framework/src/instructions/operations/migrations.md +125 -0
- package/.framework/src/instructions/operations/security-checklist.md +148 -0
- package/.framework/src/instructions/operations/troubleshooting.md +170 -0
- package/.framework/src/instructions/operations/upgrade.md +116 -0
- package/.framework/src/instructions/pipeline-executions.md +62 -0
- package/.framework/src/instructions/pipelines.md +78 -0
- package/.framework/src/instructions/prompts.md +95 -0
- package/.framework/src/instructions/reference/api/admin-data.md +162 -0
- package/.framework/src/instructions/reference/api/auth.md +113 -0
- package/.framework/src/instructions/reference/api/errors-and-envelopes.md +113 -0
- package/.framework/src/instructions/reference/app-manifest.md +150 -0
- package/.framework/src/instructions/reference/cli.md +124 -0
- package/.framework/src/instructions/reference/database.md +132 -0
- package/.framework/src/instructions/reference/design-schema.md +280 -0
- package/.framework/src/instructions/reference/env-vars.md +133 -0
- package/.framework/src/instructions/reference/functions/account-nodes.md +75 -0
- package/.framework/src/instructions/reference/functions/admin-data.md +195 -0
- package/.framework/src/instructions/reference/functions/admin-funnel.md +90 -0
- package/.framework/src/instructions/reference/functions/admin-install-funnel.md +107 -0
- package/.framework/src/instructions/reference/functions/admin-signals.md +102 -0
- package/.framework/src/instructions/reference/functions/ai-agents.md +148 -0
- package/.framework/src/instructions/reference/functions/ai-interactions.md +156 -0
- package/.framework/src/instructions/reference/functions/api-keys.md +130 -0
- package/.framework/src/instructions/reference/functions/apps.md +140 -0
- package/.framework/src/instructions/reference/functions/auth.md +99 -0
- package/.framework/src/instructions/reference/functions/debug-auth.md +91 -0
- package/.framework/src/instructions/reference/functions/deliveries.md +110 -0
- package/.framework/src/instructions/reference/functions/embeddings.md +166 -0
- package/.framework/src/instructions/reference/functions/eval-harness.md +149 -0
- package/.framework/src/instructions/reference/functions/index.md +103 -0
- package/.framework/src/instructions/reference/functions/integration-outbound.md +200 -0
- package/.framework/src/instructions/reference/functions/integration-routes.md +151 -0
- package/.framework/src/instructions/reference/functions/integrations.md +130 -0
- package/.framework/src/instructions/reference/functions/invites.md +182 -0
- package/.framework/src/instructions/reference/functions/item-progress.md +107 -0
- package/.framework/src/instructions/reference/functions/kb.md +166 -0
- package/.framework/src/instructions/reference/functions/logs.md +141 -0
- package/.framework/src/instructions/reference/functions/observability.md +105 -0
- package/.framework/src/instructions/reference/functions/pipeline-executions.md +132 -0
- package/.framework/src/instructions/reference/functions/pipeline-runner-background.md +121 -0
- package/.framework/src/instructions/reference/functions/pipelines.md +136 -0
- package/.framework/src/instructions/reference/functions/prompt-configs.md +121 -0
- package/.framework/src/instructions/reference/functions/roles.md +121 -0
- package/.framework/src/instructions/reference/functions/security.md +140 -0
- package/.framework/src/instructions/reference/functions/system-cron.md +136 -0
- package/.framework/src/instructions/reference/functions/system.md +106 -0
- package/.framework/src/instructions/reference/functions/tests.md +97 -0
- package/.framework/src/instructions/reference/functions/timers.md +117 -0
- package/.framework/src/instructions/reference/functions/trigger-scheduler.md +102 -0
- package/.framework/src/instructions/reference/functions/triggers.md +140 -0
- package/.framework/src/instructions/reference/functions/types.md +146 -0
- package/.framework/src/instructions/reference/seeds.md +126 -0
- package/.framework/src/instructions/reference/shared-modules.md +127 -0
- package/.framework/src/instructions/reference/spine-config.md +114 -0
- package/.framework/src/instructions/roles.md +80 -0
- package/.framework/src/instructions/runtime-detail.md +70 -0
- package/.framework/src/instructions/runtime-list.md +77 -0
- package/.framework/src/instructions/security.md +67 -0
- package/.framework/src/instructions/tasks/add-a-pipeline.md +110 -0
- package/.framework/src/instructions/tasks/add-a-role.md +96 -0
- package/.framework/src/instructions/tasks/add-a-timer.md +114 -0
- package/.framework/src/instructions/tasks/add-a-trigger.md +106 -0
- package/.framework/src/instructions/tasks/add-a-type.md +151 -0
- package/.framework/src/instructions/tasks/add-a-webhook.md +108 -0
- package/.framework/src/instructions/tasks/add-an-ai-agent.md +108 -0
- package/.framework/src/instructions/tasks/add-an-integration.md +124 -0
- package/.framework/src/instructions/tasks/build-a-custom-page.md +118 -0
- package/.framework/src/instructions/tasks/package-and-install-an-app.md +127 -0
- package/.framework/src/instructions/tasks/test-your-code.md +108 -0
- package/.framework/src/instructions/tasks/write-a-function.md +132 -0
- package/.framework/src/instructions/tasks/write-a-migration.md +110 -0
- package/.framework/src/instructions/testing.md +59 -0
- package/.framework/src/instructions/timers.md +82 -0
- package/.framework/src/instructions/triggers.md +69 -0
- package/.framework/src/instructions/types.md +93 -0
- package/.framework/src/lib/branding.ts +128 -0
- package/.framework/src/pages/NoAppPage.tsx +3 -1
- package/.framework/src/pages/NotFoundPage.tsx +62 -31
- package/.framework/src/pages/SetupPage.tsx +5 -2
- package/.framework/src/pages/admin/AIAgentDetailPage.tsx +117 -106
- package/.framework/src/pages/admin/AIAgentsPage.tsx +86 -48
- package/.framework/src/pages/admin/APIKeyDetailPage.tsx +153 -152
- package/.framework/src/pages/admin/APIKeysPage.tsx +91 -90
- package/.framework/src/pages/admin/AlertsConfigPage.tsx +29 -18
- package/.framework/src/pages/admin/AppDetailPage.tsx +6 -60
- package/.framework/src/pages/admin/AppsPage.tsx +104 -66
- package/.framework/src/pages/admin/DeliveriesPage.tsx +5 -5
- package/.framework/src/pages/admin/EmbeddingDetailPage.tsx +5 -23
- package/.framework/src/pages/admin/EmbeddingsPage.tsx +5 -26
- package/.framework/src/pages/admin/IntegrationDetailPage.tsx +7 -7
- package/.framework/src/pages/admin/IntegrationsPage.tsx +85 -43
- package/.framework/src/pages/admin/LogsPage.tsx +144 -76
- package/.framework/src/pages/admin/ObservabilityDashboard.tsx +223 -140
- package/.framework/src/pages/admin/PipelineDetailPage.tsx +134 -113
- package/.framework/src/pages/admin/PipelineExecutionsPage.tsx +108 -45
- package/.framework/src/pages/admin/PipelinesPage.tsx +160 -115
- package/.framework/src/pages/admin/PromptConfigDetailPage.tsx +96 -98
- package/.framework/src/pages/admin/PromptConfigsPage.tsx +101 -59
- package/.framework/src/pages/admin/RoleDetailPage.tsx +90 -79
- package/.framework/src/pages/admin/RolesPage.tsx +86 -43
- package/.framework/src/pages/admin/SecurityPage.tsx +1 -1
- package/.framework/src/pages/admin/TestingDashboard.tsx +16 -28
- package/.framework/src/pages/admin/TimerDetailPage.tsx +117 -100
- package/.framework/src/pages/admin/TimersPage.tsx +90 -62
- package/.framework/src/pages/admin/TriggerDetailPage.tsx +90 -83
- package/.framework/src/pages/admin/TriggersPage.tsx +124 -99
- package/.framework/src/pages/admin/TypeDetailPage.tsx +152 -138
- package/.framework/src/pages/admin/TypesPage.tsx +90 -48
- package/.framework/src/pages/admin/cil/CILAgentPage.tsx +17 -25
- package/.framework/src/pages/admin/cil/CILChunkDetailPage.tsx +17 -27
- package/.framework/src/pages/admin/cil/CILDashboardPage.tsx +72 -40
- package/.framework/src/pages/admin/cil/CILFileListPage.tsx +321 -129
- package/.framework/src/pages/admin/cil/CILFileSelectPage.tsx +18 -29
- package/.framework/src/pages/admin/cil/CILGraphPage.tsx +26 -38
- package/.framework/src/pages/admin/cil/CILIngestionPage.tsx +34 -46
- package/.framework/src/pages/admin/cil/CILProjectsPage.tsx +189 -103
- package/.framework/src/pages/admin/cil/CILSearchPage.tsx +246 -136
- package/.framework/src/pages/admin/cil/CILSuggestionsPage.tsx +11 -22
- package/.framework/src/pages/admin/cil/CILVersionsPage.tsx +9 -20
- package/.framework/src/pages/admin/cil/FlexiblePipelinePage.tsx +26 -38
- package/.framework/src/pages/admin/kb/KBAdminPage.tsx +7 -26
- package/.framework/src/pages/auth/AuthConfirmPage.tsx +3 -1
- package/.framework/src/pages/auth/ForgotPasswordPage.tsx +3 -1
- package/.framework/src/pages/auth/LoginPage.tsx +4 -2
- package/.framework/src/pages/auth/RegisterPage.tsx +3 -1
- package/.framework/templates/agent/AGENTS.md +150 -0
- package/.framework/templates/agent/skills/spine-add-ai-agent/SKILL.md +58 -0
- package/.framework/templates/agent/skills/spine-add-automation/SKILL.md +62 -0
- package/.framework/templates/agent/skills/spine-add-integration/SKILL.md +63 -0
- package/.framework/templates/agent/skills/spine-architect/SKILL.md +86 -0
- package/.framework/templates/agent/skills/spine-install-app/SKILL.md +72 -0
- package/.framework/templates/agent/skills/spine-migration/SKILL.md +75 -0
- package/.framework/templates/agent/skills/spine-new-app/SKILL.md +67 -0
- package/.framework/templates/agent/skills/spine-new-function/SKILL.md +65 -0
- package/.framework/templates/agent/skills/spine-new-type/SKILL.md +65 -0
- package/.framework/templates/agent/skills/spine-schema/SKILL.md +77 -0
- package/.framework/templates/agent/skills/spine-test/SKILL.md +67 -0
- package/.framework/templates/agent/skills/spine-troubleshoot/SKILL.md +74 -0
- package/.framework/templates/agent/skills/spine-upgrade/SKILL.md +69 -0
- package/.framework/templates/project.json +5 -1
- package/.framework/tests/unit/account-scoping-gates.test.ts +392 -0
- package/.framework/tests/unit/agent-files.test.ts +355 -0
- package/.framework/tests/unit/agent-runner.test.ts +496 -47
- package/.framework/tests/unit/api-keys-create-scope-gate.test.ts +160 -0
- package/.framework/tests/unit/api-keys-omit-secret-fields.test.ts +38 -0
- package/.framework/tests/unit/bootstrap.test.ts +242 -0
- package/.framework/tests/unit/cli-context-api-key.test.ts +114 -0
- package/.framework/tests/unit/debug-auth.test.ts +38 -0
- package/.framework/tests/unit/deliveries-account-scoping.test.ts +185 -0
- package/.framework/tests/unit/episode-lease.test.ts +695 -0
- package/.framework/tests/unit/integration-outbound-credentials.test.ts +167 -0
- package/.framework/tests/unit/integrations-audit-redaction.test.ts +130 -0
- package/.framework/tests/unit/kb-ingest-lease.test.ts +19 -0
- package/.framework/tests/unit/logging-app-id.test.ts +75 -0
- package/.framework/tests/unit/pipeline-runner-background.test.ts +120 -0
- package/.framework/tests/unit/pipeline-runner.test.ts +153 -1
- package/.framework/tests/unit/principal-cache.test.ts +15 -0
- package/.framework/tests/unit/system-context-denial.test.ts +145 -0
- package/.framework/tests/unit/system-cron.test.ts +240 -0
- package/.framework/tests/unit/timers.test.ts +159 -0
- package/.framework/tests/unit/trigger-engine.test.ts +278 -91
- package/.framework/tests/unit/trigger-scheduler.test.ts +78 -0
- package/README.md +125 -166
- package/config/tsconfig.cli.json +2 -2
- package/netlify.toml +5 -0
- package/package.json +15 -4
- package/templates/project/package-lock.json +2 -2
- package/.framework/docs/admin-routes.md +0 -76
- package/.framework/docs/api-docs-progress.md +0 -38
- package/.framework/docs/api-governance.md +0 -146
- package/.framework/docs/api-testing-results.md +0 -212
- package/.framework/docs/assembly-launch-guide.md +0 -138
- package/.framework/docs/audit-results.md +0 -590
- package/.framework/docs/db-api-inventory.md +0 -95
- package/.framework/docs/gap-remediation-backlog.md +0 -103
- package/.framework/docs/ui-adoption-verification.md +0 -111
- package/.framework/docs/ui-api-coverage.md +0 -84
- package/.framework/docs/v2-compatibility-audit.md +0 -228
- package/.framework/mcp/index.ts +0 -133
- package/.framework/mcp/load-env.ts +0 -60
- package/.framework/mcp/shared/app-manifest.ts +0 -275
- package/.framework/mcp/shared/db.ts +0 -477
- package/.framework/mcp/shared/kb.ts +0 -118
- package/.framework/mcp/tools/architect.ts +0 -431
- package/.framework/mcp/tools/cil/context.ts +0 -345
- package/.framework/mcp/tools/cil/graph.ts +0 -242
- package/.framework/mcp/tools/cil/ingest.ts +0 -1217
- package/.framework/mcp/tools/cil/pipeline-orchestrator.ts +0 -693
- package/.framework/mcp/tools/cil/pipeline.ts +0 -767
- package/.framework/mcp/tools/cil/project.ts +0 -791
- package/.framework/mcp/tools/cil/retrieval.ts +0 -336
- package/.framework/mcp/tools/cil/search-core.ts +0 -454
- package/.framework/mcp/tools/cil/search.ts +0 -97
- package/.framework/mcp/tools/cil/suggest.ts +0 -186
- package/.framework/mcp/tools/cil/validate.ts +0 -1369
- package/.framework/mcp/tools/kb/delete.ts +0 -139
- package/.framework/mcp/tools/kb/index.ts +0 -52
- package/.framework/mcp/tools/kb/ingest.ts +0 -84
- package/.framework/mcp/tools/kb/list-types.ts +0 -102
- package/.framework/mcp/tools/kb/publish.ts +0 -100
- package/.framework/mcp/tools/kb/reindex.ts +0 -86
- package/.framework/mcp/tools/kb/revoke.ts +0 -85
- package/.framework/mcp/tools/kb/search.ts +0 -101
- package/.framework/mcp/tools/kb/upsert.ts +0 -125
- package/.framework/mcp/tools/observability.ts +0 -510
|
@@ -1,12 +1,28 @@
|
|
|
1
|
-
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/APIKeyDetailPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent=""]
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/APIKeyDetailPage.tsx:module_header:module_header" type="module_header" identity="module_header" parent="~/.framework/src/pages/admin/APIKeyDetailPage.tsx"]
|
|
2
|
+
/**
|
|
3
|
+
* @module APIKeyDetailPage
|
|
4
|
+
* @audience both
|
|
5
|
+
* @layer shared-core
|
|
6
|
+
* @stability stable
|
|
7
|
+
*
|
|
8
|
+
* This module provides the UI for managing API keys within the admin section of the application. It allows users to view, create, and delete API keys, handling state and side effects related to API interactions.
|
|
9
|
+
* INVARIANT: Users must have appropriate permissions to access this page and perform actions on API keys.
|
|
10
|
+
*
|
|
11
|
+
* @seeAlso useApi (custom hook for API interactions).
|
|
12
|
+
* @seeAlso apiFetch (utility for making API requests).
|
|
13
|
+
* @seeAlso PageInstructions (provides guidance on using the page).
|
|
14
|
+
*
|
|
15
|
+
* @cil-generated
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
|
|
10
26
|
|
|
11
27
|
|
|
12
28
|
|
|
@@ -20,6 +36,7 @@ import { Textarea } from '../../components/ui/textarea'
|
|
|
20
36
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../../components/ui/select'
|
|
21
37
|
import { Checkbox } from '../../components/ui/checkbox'
|
|
22
38
|
import { Label } from '../../components/ui/label'
|
|
39
|
+
import { AppSelect } from '../../components/admin/EntitySelect'
|
|
23
40
|
import { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card'
|
|
24
41
|
import { Skeleton } from '../../components/ui/skeleton'
|
|
25
42
|
import { Alert, AlertDescription, AlertTitle } from '../../components/ui/alert'
|
|
@@ -27,30 +44,37 @@ import { ArrowLeft, Key, RefreshCw, Trash2, AlertCircle, Copy, Check } from 'luc
|
|
|
27
44
|
import { useApi } from '../../hooks/useApi'
|
|
28
45
|
import { apiFetch } from '../../lib/api'
|
|
29
46
|
import { formatDateTime } from '../../lib/utils'
|
|
30
|
-
import { PageInstructions } from '../../components/admin/PageInstructions'
|
|
31
|
-
|
|
32
|
-
// CIL[DOC-VECTOR type="context" content="purpose='Defines the admin API key detail/create page module and imports its dependencies.'; No verified external callers; imports: .framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/textarea.tsx"]
|
|
33
|
-
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
34
|
-
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
35
|
-
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
36
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
37
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
38
47
|
// CIL[END stable_id="~/.framework/src/pages/admin/APIKeyDetailPage.tsx:module_header:module_header"]
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/APIKeyDetailPage.tsx:APIKey:interface" type="interface" identity="APIKey" parent="~/.framework/src/pages/admin/APIKeyDetailPage.tsx"]
|
|
65
|
+
/**
|
|
66
|
+
* The APIKey interface defines the structure of an API key object used within the application, encapsulating its properties and metadata. It provides a consistent representation of API keys across the system.
|
|
67
|
+
*
|
|
68
|
+
* @sideEffects none
|
|
69
|
+
* @stability internal
|
|
70
|
+
* @cil-generated
|
|
71
|
+
*/
|
|
47
72
|
interface APIKey {
|
|
48
73
|
id: string
|
|
49
74
|
name: string
|
|
50
75
|
integration_id?: string
|
|
51
76
|
app_id?: string
|
|
52
77
|
key_type: 'inbound' | 'outbound' | 'internal' | 'cli'
|
|
53
|
-
key_value?: string
|
|
54
78
|
key_prefix: string
|
|
55
79
|
is_active: boolean
|
|
56
80
|
permissions?: Record<string, any>
|
|
@@ -66,46 +90,69 @@ interface APIKey {
|
|
|
66
90
|
created_at: string
|
|
67
91
|
updated_at: string
|
|
68
92
|
}
|
|
69
|
-
// CIL[DOC-VECTOR type="context" content="purpose='Defines the API key record shape used by the admin detail page.'; No verified external callers; imports: .framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/textarea.tsx"]
|
|
70
|
-
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
71
|
-
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
72
|
-
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
73
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
74
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
75
93
|
// CIL[END stable_id="~/.framework/src/pages/admin/APIKeyDetailPage.tsx:APIKey:interface"]
|
|
76
94
|
|
|
77
95
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/APIKeyDetailPage.tsx:KEY_TYPE_OPTIONS:constant" type="constant" identity="KEY_TYPE_OPTIONS" parent="~/.framework/src/pages/admin/APIKeyDetailPage.tsx"]
|
|
112
|
+
/**
|
|
113
|
+
* KEY_TYPE_OPTIONS defines a structured set of options for categorizing different types of API keys used in the application. It helps in organizing keys based on their intended use cases.
|
|
114
|
+
*
|
|
115
|
+
* @sideEffects none
|
|
116
|
+
* @stability internal
|
|
117
|
+
* @cil-generated
|
|
118
|
+
*/
|
|
86
119
|
const KEY_TYPE_OPTIONS = [
|
|
87
120
|
{ value: 'inbound', label: 'Inbound (External callers to Spine)' },
|
|
88
121
|
{ value: 'outbound', label: 'Outbound (Spine to external services)' },
|
|
89
122
|
{ value: 'internal', label: 'Internal (Spine-to-Spine)' },
|
|
90
123
|
{ value: 'cli', label: 'CLI / Script' }
|
|
91
124
|
]
|
|
92
|
-
// CIL[DOC-VECTOR type="context" content="purpose='Defines the selectable labels for API key types.'; No verified external callers; imports: .framework/src/components/ui/button.tsx,.framework/src/components/ui/input.tsx,.framework/src/components/ui/textarea.tsx"]
|
|
93
|
-
// CIL[DOC-VECTOR type="blast_radius" content="No direct caller data from CIL graph; local impact only"]
|
|
94
|
-
// CIL[DOC-VECTOR type="configuration" content="No environment or build configuration dependencies identified"]
|
|
95
|
-
// CIL[DOC-VECTOR type="constraint" content="Standard runtime; no special invariants documented"]
|
|
96
|
-
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
97
|
-
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
98
125
|
// CIL[END stable_id="~/.framework/src/pages/admin/APIKeyDetailPage.tsx:KEY_TYPE_OPTIONS:constant"]
|
|
99
126
|
|
|
100
127
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
// CIL[BEGIN stable_id="~/.framework/src/pages/admin/APIKeyDetailPage.tsx:APIKeyDetailPage:component" type="component" identity="APIKeyDetailPage" parent="~/.framework/src/pages/admin/APIKeyDetailPage.tsx"]
|
|
144
|
+
/**
|
|
145
|
+
* The APIKeyDetailPage component manages the creation and editing of API keys, providing a user interface for inputting key details and submitting them to the server. It handles both the retrieval of existing API key data and the submission of new or updated key information.
|
|
146
|
+
*
|
|
147
|
+
* @macro Component responsible for managing API key details in an admin interface.
|
|
148
|
+
* @micro Utilizes React hooks for state management and side effects, including fetching API key data and handling form submissions.
|
|
149
|
+
* @outputSpec JSX.Element — renders the API key detail page UI
|
|
150
|
+
* @sideEffects Makes API calls to fetch and submit API key data
|
|
151
|
+
* @stability internal
|
|
152
|
+
* @calls useParams, useNavigate, useApi, apiFetch
|
|
153
|
+
* @errorHandling none
|
|
154
|
+
* @cil-generated
|
|
155
|
+
*/
|
|
109
156
|
export function APIKeyDetailPage() {
|
|
110
157
|
const { id } = useParams<{ id: string }>()
|
|
111
158
|
const navigate = useNavigate()
|
|
@@ -131,7 +178,9 @@ export function APIKeyDetailPage() {
|
|
|
131
178
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
|
132
179
|
const [error, setError] = useState<string | null>(null)
|
|
133
180
|
const [generatedKey, setGeneratedKey] = useState<string | null>(null)
|
|
181
|
+
const [createdKeyId, setCreatedKeyId] = useState<string | null>(null)
|
|
134
182
|
const [copied, setCopied] = useState(false)
|
|
183
|
+
const [isRevoking, setIsRevoking] = useState(false)
|
|
135
184
|
|
|
136
185
|
const { data: apiKey, loading, error: fetchError } = useApi<APIKey>(
|
|
137
186
|
async () => {
|
|
@@ -186,8 +235,8 @@ export function APIKeyDetailPage() {
|
|
|
186
235
|
})
|
|
187
236
|
if (!response.ok) throw new Error('Failed to create API key')
|
|
188
237
|
const result = await response.json()
|
|
189
|
-
setGeneratedKey(result.
|
|
190
|
-
|
|
238
|
+
setGeneratedKey(result.data?.raw_key ?? result.raw_key)
|
|
239
|
+
setCreatedKeyId(result.id || result.data?.id)
|
|
191
240
|
} catch (err) {
|
|
192
241
|
setError(err instanceof Error ? err.message : 'Failed to create API key')
|
|
193
242
|
} finally {
|
|
@@ -221,49 +270,6 @@ export function APIKeyDetailPage() {
|
|
|
221
270
|
<Button variant="ghost" onClick={() => navigate(-1)}><ArrowLeft className="h-5 w-5" /></Button>
|
|
222
271
|
<h1 className="text-2xl font-bold">{apiKey.name}</h1>
|
|
223
272
|
</div>
|
|
224
|
-
<PageInstructions
|
|
225
|
-
description="Create an API key and set its permissions, rate limits, and expiration."
|
|
226
|
-
sections={[
|
|
227
|
-
{ title: 'What this API key controls', content: 'API keys authenticate callers to Spine. A key controls which callers are accepted, how fast they can call, and which permissions they carry.' },
|
|
228
|
-
{ title: 'Fields explained', content: <ul className="list-disc pl-4 space-y-1">
|
|
229
|
-
<li><strong>Name</strong> — string, required. A human-readable label. Missing name blocks creation.</li>
|
|
230
|
-
<li><strong>Integration ID</strong> — string. Optional UUID of the integration this key is for.</li>
|
|
231
|
-
<li><strong>App ID</strong> — string. Optional UUID of the owning app.</li>
|
|
232
|
-
<li><strong>Key Type</strong> — select. inbound, outbound, internal, or cli. Determines which direction the key is used and how it is validated.</li>
|
|
233
|
-
<li><strong>Prefix</strong> — string. The public prefix that appears before the generated secret. Default is "sk_". The create API may override this with the generated prefix.</li>
|
|
234
|
-
<li><strong>Rate Limit (requests/min)</strong> — number 1-10000. Enforces a cap on calls per minute. Missing or 0 may prevent usage.</li>
|
|
235
|
-
<li><strong>Expires At</strong> — date. Optional expiration. After this date the key is rejected.</li>
|
|
236
|
-
<li><strong>Machine Type</strong> — string. The machine principal type, e.g. integration.</li>
|
|
237
|
-
<li><strong>Internal</strong> — checkbox. Marks a key for internal service-to-service use.</li>
|
|
238
|
-
<li><strong>Active</strong> — checkbox. Inactive keys are rejected.</li>
|
|
239
|
-
<li><strong>Permissions (JSON)</strong> — JSON object. Defines allowed actions/resources. Invalid JSON fails creation.</li>
|
|
240
|
-
<li><strong>Scopes (JSON)</strong> — JSON array of scope strings. Invalid JSON fails creation.</li>
|
|
241
|
-
<li><strong>Metadata (JSON)</strong> — JSON object. Optional notes such as environment. Invalid JSON fails creation.</li>
|
|
242
|
-
</ul> },
|
|
243
|
-
{ title: 'Options and values', content: <ul className="list-disc pl-4 space-y-1">
|
|
244
|
-
<li><strong>inbound</strong>: External callers into Spine APIs.</li>
|
|
245
|
-
<li><strong>outbound</strong>: Spine calling external services.</li>
|
|
246
|
-
<li><strong>internal</strong>: Service-to-service calls within Spine.</li>
|
|
247
|
-
<li><strong>cli</strong>: Scripts or command-line tooling.</li>
|
|
248
|
-
</ul> },
|
|
249
|
-
{ title: 'Downstream impact', content: <ul className="list-disc pl-4 space-y-1">
|
|
250
|
-
<li>API gateway validates the key on every call. An inactive, expired, or missing key is rejected.</li>
|
|
251
|
-
<li>Rate limits are enforced at the edge; a misconfigured limit may throttle or deny callers.</li>
|
|
252
|
-
<li>Permission JSON is parsed and used for authorization checks. Badly shaped permissions may grant too much or too little access.</li>
|
|
253
|
-
</ul> },
|
|
254
|
-
{ title: 'How to create, save, and validate', content: <ol className="list-decimal pl-4 space-y-1">
|
|
255
|
-
<li>Only create mode is available; existing keys are shown read-only with the value masked.</li>
|
|
256
|
-
<li>Fill Name, Key Type, and Rate Limit. Provide valid JSON for Permissions and Metadata.</li>
|
|
257
|
-
<li>Submit the form. A one-time key is generated and shown; copy it immediately because it cannot be retrieved again.</li>
|
|
258
|
-
<li>Validation checks required fields, rate limit range, and valid JSON.</li>
|
|
259
|
-
</ol> },
|
|
260
|
-
{ title: 'Common mistakes', content: <ul className="list-disc pl-4 space-y-1">
|
|
261
|
-
<li>Forgetting to copy the generated key before leaving the page.</li>
|
|
262
|
-
<li>Entering Permissions as a comma-separated list instead of JSON.</li>
|
|
263
|
-
<li>Setting Rate Limit to 0, which blocks all requests.</li>
|
|
264
|
-
</ul> },
|
|
265
|
-
]}
|
|
266
|
-
/>
|
|
267
273
|
<Card><CardContent className="p-6">
|
|
268
274
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
269
275
|
<div className="flex justify-between"><span className="text-muted-foreground">Key Type</span><span>{apiKey.key_type}</span></div>
|
|
@@ -273,8 +279,46 @@ export function APIKeyDetailPage() {
|
|
|
273
279
|
<div className="flex justify-between"><span className="text-muted-foreground">Usage</span><span>{apiKey.usage_count} requests</span></div>
|
|
274
280
|
<div className="flex justify-between"><span className="text-muted-foreground">Created</span><span>{formatDateTime(apiKey.created_at)}</span></div>
|
|
275
281
|
</div>
|
|
276
|
-
<div className="mt-4"><span className="text-muted-foreground">Key Value</span><div className="mt-1 font-mono text-sm bg-muted p-3 rounded">{apiKey.key_value || '***'}</div></div>
|
|
277
282
|
</CardContent></Card>
|
|
283
|
+
{apiKey.is_active && (
|
|
284
|
+
<div className="flex justify-end">
|
|
285
|
+
<Button
|
|
286
|
+
variant="destructive"
|
|
287
|
+
disabled={isRevoking}
|
|
288
|
+
onClick={async () => {
|
|
289
|
+
if (!confirm('Revoke this API key? It will stop working immediately.')) return
|
|
290
|
+
setIsRevoking(true)
|
|
291
|
+
try {
|
|
292
|
+
/**
|
|
293
|
+
* The constant 'res' holds the response from an API call to revoke an API key, determining the success of the operation and handling navigation. It is essential for managing the revocation process of API keys.
|
|
294
|
+
*
|
|
295
|
+
* @throws Error — if the response is not ok, indicating a failure to revoke the API key.
|
|
296
|
+
* @sideEffects Makes an external API call to '/api/api-keys?action=revoke'.
|
|
297
|
+
* @stability internal
|
|
298
|
+
* @calls apiFetch, navigate
|
|
299
|
+
* @errorHandling Alerts the user with an error message if the revocation fails.
|
|
300
|
+
* @cil-generated
|
|
301
|
+
*/
|
|
302
|
+
const res = await apiFetch('/api/api-keys?action=revoke', {
|
|
303
|
+
method: 'POST',
|
|
304
|
+
headers: { 'Content-Type': 'application/json' },
|
|
305
|
+
body: JSON.stringify({ id: apiKey.id }),
|
|
306
|
+
})
|
|
307
|
+
if (!res.ok) throw new Error('Failed to revoke API key')
|
|
308
|
+
navigate('/spine-framework/admin/configs/api-keys')
|
|
309
|
+
} catch (err) {
|
|
310
|
+
setError(err instanceof Error ? err.message : 'Failed to revoke API key')
|
|
311
|
+
} finally {
|
|
312
|
+
setIsRevoking(false)
|
|
313
|
+
}
|
|
314
|
+
}}
|
|
315
|
+
>
|
|
316
|
+
<Trash2 className="h-4 w-4 mr-2" />
|
|
317
|
+
{isRevoking ? 'Revoking…' : 'Revoke Key'}
|
|
318
|
+
</Button>
|
|
319
|
+
</div>
|
|
320
|
+
)}
|
|
321
|
+
{error && <Alert variant="destructive"><AlertCircle className="h-4 w-4" /><AlertTitle>Error</AlertTitle><AlertDescription>{error}</AlertDescription></Alert>}
|
|
278
322
|
</div>
|
|
279
323
|
)
|
|
280
324
|
}
|
|
@@ -287,7 +331,7 @@ export function APIKeyDetailPage() {
|
|
|
287
331
|
<Alert><AlertCircle className="h-4 w-4" /><AlertTitle>Save this key now</AlertTitle><AlertDescription>You won't be able to see it again. Copy it now and store it securely.</AlertDescription></Alert>
|
|
288
332
|
<Card><CardContent className="p-6">
|
|
289
333
|
<div className="flex items-center gap-2"><code className="flex-1 bg-muted p-4 rounded font-mono text-lg">{generatedKey}</code><Button size="icon" onClick={handleCopy}>{copied ? <Check className="h-4 w-4" /> : <Copy className="h-4 w-4" />}</Button></div>
|
|
290
|
-
<Button className="mt-4" onClick={() => navigate(
|
|
334
|
+
<Button className="mt-4" onClick={() => navigate(`/spine-framework/admin/configs/api-keys/${createdKeyId}`)}>Done</Button>
|
|
291
335
|
</CardContent></Card>
|
|
292
336
|
</div>
|
|
293
337
|
)
|
|
@@ -299,49 +343,6 @@ export function APIKeyDetailPage() {
|
|
|
299
343
|
<Button variant="ghost" onClick={() => navigate(-1)}><ArrowLeft className="h-5 w-5" /></Button>
|
|
300
344
|
<h1 className="text-2xl font-bold">Create API Key</h1>
|
|
301
345
|
</div>
|
|
302
|
-
<PageInstructions
|
|
303
|
-
description="Create an API key and set its permissions, rate limits, and expiration."
|
|
304
|
-
sections={[
|
|
305
|
-
{ title: 'What this API key controls', content: 'API keys authenticate callers to Spine. A key controls which callers are accepted, how fast they can call, and which permissions they carry.' },
|
|
306
|
-
{ title: 'Fields explained', content: <ul className="list-disc pl-4 space-y-1">
|
|
307
|
-
<li><strong>Name</strong> — string, required. A human-readable label. Missing name blocks creation.</li>
|
|
308
|
-
<li><strong>Integration ID</strong> — string. Optional UUID of the integration this key is for.</li>
|
|
309
|
-
<li><strong>App ID</strong> — string. Optional UUID of the owning app.</li>
|
|
310
|
-
<li><strong>Key Type</strong> — select. inbound, outbound, internal, or cli. Determines which direction the key is used and how it is validated.</li>
|
|
311
|
-
<li><strong>Prefix</strong> — string. The public prefix that appears before the generated secret. Default is "sk_". The create API may override this with the generated prefix.</li>
|
|
312
|
-
<li><strong>Rate Limit (requests/min)</strong> — number 1-10000. Enforces a cap on calls per minute. Missing or 0 may prevent usage.</li>
|
|
313
|
-
<li><strong>Expires At</strong> — date. Optional expiration. After this date the key is rejected.</li>
|
|
314
|
-
<li><strong>Machine Type</strong> — string. The machine principal type, e.g. integration.</li>
|
|
315
|
-
<li><strong>Internal</strong> — checkbox. Marks a key for internal service-to-service use.</li>
|
|
316
|
-
<li><strong>Active</strong> — checkbox. Inactive keys are rejected.</li>
|
|
317
|
-
<li><strong>Permissions (JSON)</strong> — JSON object. Defines allowed actions/resources. Invalid JSON fails creation.</li>
|
|
318
|
-
<li><strong>Scopes (JSON)</strong> — JSON array of scope strings. Invalid JSON fails creation.</li>
|
|
319
|
-
<li><strong>Metadata (JSON)</strong> — JSON object. Optional notes such as environment. Invalid JSON fails creation.</li>
|
|
320
|
-
</ul> },
|
|
321
|
-
{ title: 'Options and values', content: <ul className="list-disc pl-4 space-y-1">
|
|
322
|
-
<li><strong>inbound</strong>: External callers into Spine APIs.</li>
|
|
323
|
-
<li><strong>outbound</strong>: Spine calling external services.</li>
|
|
324
|
-
<li><strong>internal</strong>: Service-to-service calls within Spine.</li>
|
|
325
|
-
<li><strong>cli</strong>: Scripts or command-line tooling.</li>
|
|
326
|
-
</ul> },
|
|
327
|
-
{ title: 'Downstream impact', content: <ul className="list-disc pl-4 space-y-1">
|
|
328
|
-
<li>API gateway validates the key on every call. An inactive, expired, or missing key is rejected.</li>
|
|
329
|
-
<li>Rate limits are enforced at the edge; a misconfigured limit may throttle or deny callers.</li>
|
|
330
|
-
<li>Permission JSON is parsed and used for authorization checks. Badly shaped permissions may grant too much or too little access.</li>
|
|
331
|
-
</ul> },
|
|
332
|
-
{ title: 'How to create, save, and validate', content: <ol className="list-decimal pl-4 space-y-1">
|
|
333
|
-
<li>Only create mode is available; existing keys are shown read-only with the value masked.</li>
|
|
334
|
-
<li>Fill Name, Key Type, and Rate Limit. Provide valid JSON for Permissions and Metadata.</li>
|
|
335
|
-
<li>Submit the form. A one-time key is generated and shown; copy it immediately because it cannot be retrieved again.</li>
|
|
336
|
-
<li>Validation checks required fields, rate limit range, and valid JSON.</li>
|
|
337
|
-
</ol> },
|
|
338
|
-
{ title: 'Common mistakes', content: <ul className="list-disc pl-4 space-y-1">
|
|
339
|
-
<li>Forgetting to copy the generated key before leaving the page.</li>
|
|
340
|
-
<li>Entering Permissions as a comma-separated list instead of JSON.</li>
|
|
341
|
-
<li>Setting Rate Limit to 0, which blocks all requests.</li>
|
|
342
|
-
</ul> },
|
|
343
|
-
]}
|
|
344
|
-
/>
|
|
345
346
|
{error && <Alert variant="destructive"><AlertCircle className="h-4 w-4" /><AlertTitle>Error</AlertTitle><AlertDescription>{error}</AlertDescription></Alert>}
|
|
346
347
|
<form onSubmit={handleSubmit} className="space-y-6">
|
|
347
348
|
<Card><CardContent className="p-6 space-y-4">
|
|
@@ -349,7 +350,7 @@ export function APIKeyDetailPage() {
|
|
|
349
350
|
<div className="space-y-2"><Label>Name *</Label><Input value={formData.name} onChange={e => setFormData({...formData, name: e.target.value})} required placeholder="e.g., Production API Key" /></div>
|
|
350
351
|
<div className="space-y-2"><Label>Key Type</Label><Select value={formData.key_type} onValueChange={v => setFormData({...formData, key_type: v as 'inbound' | 'outbound' | 'internal' | 'cli'})}><SelectTrigger><SelectValue /></SelectTrigger><SelectContent>{KEY_TYPE_OPTIONS.map(opt => <SelectItem key={opt.value} value={opt.value}>{opt.label}</SelectItem>)}</SelectContent></Select></div>
|
|
351
352
|
<div className="space-y-2"><Label>Integration ID</Label><Input value={formData.integration_id} onChange={e => setFormData({...formData, integration_id: e.target.value})} placeholder="Optional integration UUID" /></div>
|
|
352
|
-
<div className="space-y-2"><Label>App
|
|
353
|
+
<div className="space-y-2"><Label>App</Label><AppSelect value={formData.app_id} onChange={v => setFormData({...formData, app_id: v})} /></div>
|
|
353
354
|
<div className="space-y-2"><Label>Prefix</Label><Input value={formData.key_prefix} onChange={e => setFormData({...formData, key_prefix: e.target.value})} placeholder="e.g., sk_" /></div>
|
|
354
355
|
<div className="space-y-2"><Label>Rate Limit (requests/min)</Label><Input type="number" value={formData.rate_limit} onChange={e => setFormData({...formData, rate_limit: parseInt(e.target.value)})} min={1} max={10000} /></div>
|
|
355
356
|
<div className="space-y-2"><Label>Expires At</Label><Input type="date" value={formData.expires_at} onChange={e => setFormData({...formData, expires_at: e.target.value})} /></div>
|
|
@@ -368,10 +369,10 @@ export function APIKeyDetailPage() {
|
|
|
368
369
|
</div>
|
|
369
370
|
)
|
|
370
371
|
}
|
|
371
|
-
// CIL[
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
372
|
+
// CIL[END stable_id="~/.framework/src/pages/admin/APIKeyDetailPage.tsx:APIKeyDetailPage:component"]
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
|
|
378
|
+
|