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,6 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
// CIL[BEGIN chunk_id="triggerdetailpage_moduleheader_1783664706" type="module_header" identity="module_header" parent="none"]
|
|
5
|
+
// CIL[DOC-MACRO purpose="Import dependencies for TriggerDetailPage component"]
|
|
6
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide all external dependencies and UI components"]
|
|
7
|
+
// CIL[DOC-CONTEXT module="TriggerDetailPage" layer="frontend-page" related_files="[\".framework/src/components/ui/dialog.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
8
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="React components and utilities" errors="none" side_effects="none"]
|
|
9
|
+
// CIL[DOC-MICRO logic_summary="Imports React hooks, navigation, API utilities, and UI components" notable_decisions="[]"]
|
|
10
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
11
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
12
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
13
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/components/ui/dialog.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
14
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
15
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
16
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
17
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
18
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
4
19
|
import { useState, useEffect } from 'react'
|
|
5
20
|
import { useParams, useNavigate } from 'react-router-dom'
|
|
6
21
|
import { apiFetch } from '../../lib/api'
|
|
@@ -16,24 +31,50 @@ import { Alert, AlertDescription, AlertTitle } from '../../components/ui/alert'
|
|
|
16
31
|
import { Badge } from '../../components/ui/badge'
|
|
17
32
|
import { ArrowLeft, Zap, AlertCircle } from 'lucide-react'
|
|
18
33
|
import { formatDateTime } from '../../lib/utils'
|
|
19
|
-
|
|
34
|
+
import { PageInstructions } from '../../components/admin/PageInstructions'
|
|
35
|
+
// CIL[END chunk_id="triggerdetailpage_moduleheader_1783664706"]
|
|
36
|
+
// CIL[BEGIN chunk_id="triggerdetailpage_trigger_1783664706" type="interface" identity="Trigger" parent="none"]
|
|
37
|
+
// CIL[DOC-MACRO purpose="Define the Trigger data structure for trigger management"]
|
|
38
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide type definition for event/schedule/webhook triggers"]
|
|
39
|
+
// CIL[DOC-CONTEXT module="TriggerDetailPage" layer="frontend-page" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
|
|
40
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Trigger interface" errors="none" side_effects="none"]
|
|
41
|
+
// CIL[DOC-MICRO logic_summary="Defines trigger structure with event configuration and action settings" notable_decisions="[]"]
|
|
42
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
43
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
44
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
|
|
45
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
46
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
47
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
48
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
49
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
20
50
|
interface Trigger {
|
|
21
51
|
id: string
|
|
22
52
|
name: string
|
|
23
53
|
description?: string
|
|
54
|
+
app_id?: string
|
|
24
55
|
event_type: string
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
action_config: Record<string, any>
|
|
56
|
+
pipeline_id?: string
|
|
57
|
+
config?: Record<string, any>
|
|
58
|
+
metadata?: Record<string, any>
|
|
29
59
|
is_active: boolean
|
|
30
|
-
priority: number
|
|
31
|
-
debounce_ms?: number
|
|
32
|
-
rate_limit_per_minute?: number
|
|
33
60
|
created_at: string
|
|
34
61
|
updated_at: string
|
|
35
62
|
}
|
|
36
|
-
|
|
63
|
+
// CIL[END chunk_id="triggerdetailpage_trigger_1783664706"]
|
|
64
|
+
// CIL[BEGIN chunk_id="triggerdetailpage_triggerdetailpage_1783664706" type="function" identity="TriggerDetailPage" parent="none"]
|
|
65
|
+
// CIL[DOC-MACRO purpose="Create/view/edit/delete page for single trigger records"]
|
|
66
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Manage trigger CRUD operations with form handling and validation"]
|
|
67
|
+
// CIL[DOC-CONTEXT module="TriggerDetailPage" layer="frontend-page" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
68
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="React component with trigger form" errors="API failures, validation errors" side_effects="API calls, navigation"]
|
|
69
|
+
// CIL[DOC-MICRO logic_summary="Form handling with trigger configuration and action settings" notable_decisions="[]"]
|
|
70
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
71
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
72
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
73
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
74
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
75
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
76
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
77
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
37
78
|
export function TriggerDetailPage() {
|
|
38
79
|
const { id } = useParams<{ id: string }>()
|
|
39
80
|
const navigate = useNavigate()
|
|
@@ -43,8 +84,7 @@ export function TriggerDetailPage() {
|
|
|
43
84
|
const [error, setError] = useState<string | null>(null)
|
|
44
85
|
const [isEditing, setIsEditing] = useState(isCreateMode)
|
|
45
86
|
const [formData, setFormData] = useState({
|
|
46
|
-
name: '', description: '', event_type: '',
|
|
47
|
-
action_config: '{}', is_active: true, priority: 0, debounce_ms: 0, rate_limit_per_minute: 0
|
|
87
|
+
name: '', description: '', app_id: '', event_type: '', pipeline_id: '', config: '{}', metadata: '{}', is_active: true
|
|
48
88
|
})
|
|
49
89
|
|
|
50
90
|
useEffect(() => {
|
|
@@ -61,10 +101,14 @@ export function TriggerDetailPage() {
|
|
|
61
101
|
const data = result.data
|
|
62
102
|
setTrigger(data)
|
|
63
103
|
setFormData({
|
|
64
|
-
name: data.name,
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
104
|
+
name: data.name,
|
|
105
|
+
description: data.description || '',
|
|
106
|
+
app_id: data.app_id || '',
|
|
107
|
+
event_type: data.event_type,
|
|
108
|
+
pipeline_id: data.pipeline_id || '',
|
|
109
|
+
config: JSON.stringify(data.config || {}, null, 2),
|
|
110
|
+
metadata: JSON.stringify(data.metadata || {}, null, 2),
|
|
111
|
+
is_active: data.is_active ?? true
|
|
68
112
|
})
|
|
69
113
|
} catch (err) {
|
|
70
114
|
setError(err instanceof Error ? err.message : 'Failed to load trigger')
|
|
@@ -77,14 +121,25 @@ export function TriggerDetailPage() {
|
|
|
77
121
|
|
|
78
122
|
const handleSave = async () => {
|
|
79
123
|
try {
|
|
80
|
-
let
|
|
81
|
-
|
|
82
|
-
try {
|
|
124
|
+
let parsedConfig = {}
|
|
125
|
+
let parsedMetadata = {}
|
|
126
|
+
try { parsedConfig = JSON.parse(formData.config) } catch {}
|
|
127
|
+
try { parsedMetadata = JSON.parse(formData.metadata) } catch {}
|
|
83
128
|
const url = isCreateMode ? '/api/triggers?action=create' : `/api/triggers?action=update&id=${id}`
|
|
84
129
|
const method = isCreateMode ? 'POST' : 'PATCH'
|
|
130
|
+
const saveData = {
|
|
131
|
+
name: formData.name,
|
|
132
|
+
description: formData.description,
|
|
133
|
+
app_id: formData.app_id || null,
|
|
134
|
+
event_type: formData.event_type,
|
|
135
|
+
pipeline_id: formData.pipeline_id || null,
|
|
136
|
+
config: parsedConfig,
|
|
137
|
+
metadata: parsedMetadata,
|
|
138
|
+
is_active: formData.is_active
|
|
139
|
+
}
|
|
85
140
|
const response = await apiFetch(url, {
|
|
86
141
|
method, headers: { 'Content-Type': 'application/json' },
|
|
87
|
-
body: JSON.stringify(
|
|
142
|
+
body: JSON.stringify(saveData)
|
|
88
143
|
})
|
|
89
144
|
if (!response.ok) throw new Error('Failed to save trigger')
|
|
90
145
|
if (isCreateMode) {
|
|
@@ -121,29 +176,62 @@ export function TriggerDetailPage() {
|
|
|
121
176
|
</div>
|
|
122
177
|
</div>
|
|
123
178
|
|
|
124
|
-
<
|
|
179
|
+
<PageInstructions
|
|
180
|
+
description="Define a trigger that reacts to events and invokes a pipeline."
|
|
181
|
+
sections={[
|
|
182
|
+
{ title: 'What this trigger controls', content: 'A trigger listens for a Spine event_type and, when active, hands the event payload to a pipeline for processing. The config and metadata JSON objects configure the trigger engine.' },
|
|
183
|
+
{ title: 'Fields explained', content: <ul className="list-disc pl-4 space-y-1">
|
|
184
|
+
<li><strong>Name</strong> — string. The display name. Missing name prevents saving.</li>
|
|
185
|
+
<li><strong>Event Type</strong> — string. The event to listen to, e.g. item.created. Must match the emitted event name exactly.</li>
|
|
186
|
+
<li><strong>App ID</strong> — string. Optional owning app UUID; blank means account-scoped.</li>
|
|
187
|
+
<li><strong>Pipeline ID</strong> — string. The pipeline to invoke when the trigger fires.</li>
|
|
188
|
+
<li><strong>Active</strong> — checkbox. Inactive triggers ignore all events.</li>
|
|
189
|
+
<li><strong>Description</strong> — string. Optional notes.</li>
|
|
190
|
+
<li><strong>Config (JSON)</strong> — JSON. Trigger engine configuration, e.g. filters or payload mapping.</li>
|
|
191
|
+
<li><strong>Metadata (JSON)</strong> — JSON. Optional metadata about the trigger.</li>
|
|
192
|
+
</ul> },
|
|
193
|
+
{ title: 'Options and values', content: <ul className="list-disc pl-4 space-y-1">
|
|
194
|
+
<li><strong>Active</strong>: enabled means the trigger subscribes to the event bus; disabled means it is ignored.</li>
|
|
195
|
+
</ul> },
|
|
196
|
+
{ title: 'Downstream impact', content: <ul className="list-disc pl-4 space-y-1">
|
|
197
|
+
<li>The event bus routes matching events to active triggers. A wrong Event Type means no execution.</li>
|
|
198
|
+
<li>Pipeline ID must refer to an existing pipeline; otherwise the event is dropped.</li>
|
|
199
|
+
<li>Config JSON is passed to the trigger engine; bad config can cause repeated failures.</li>
|
|
200
|
+
</ul> },
|
|
201
|
+
{ title: 'How to create, save, and validate', content: <ol className="list-decimal pl-4 space-y-1">
|
|
202
|
+
<li>In create mode, enter the name, event type, and pipeline ID, and provide Config and Metadata as valid JSON.</li>
|
|
203
|
+
<li>Click Create or Save. The form validates JSON and required fields.</li>
|
|
204
|
+
<li>After saving, the trigger subscribes to the event bus when active.</li>
|
|
205
|
+
</ol> },
|
|
206
|
+
{ title: 'Common mistakes', content: <ul className="list-disc pl-4 space-y-1">
|
|
207
|
+
<li>Using a typo in the Event Type so the trigger never matches.</li>
|
|
208
|
+
<li>Forgetting to set Active after saving.</li>
|
|
209
|
+
<li>Writing Config as a string instead of a JSON object.</li>
|
|
210
|
+
</ul> },
|
|
211
|
+
]}
|
|
212
|
+
/>
|
|
213
|
+
|
|
214
|
+
<Card><CardContent className="p-6 space-y-6">
|
|
125
215
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
126
216
|
<div className="space-y-4">
|
|
127
217
|
<h3 className="text-sm font-medium text-muted-foreground">Trigger</h3>
|
|
128
218
|
<div className="space-y-2"><Label>Name</Label>{isEditing ? <Input value={formData.name} onChange={e => setFormData({...formData, name: e.target.value})} /> : <div className="text-sm">{trigger?.name}</div>}</div>
|
|
219
|
+
<div className="space-y-2"><Label>App ID</Label>{isEditing ? <Input value={formData.app_id} onChange={e => setFormData({...formData, app_id: e.target.value})} placeholder="Optional app UUID" /> : <div className="text-sm font-mono">{trigger?.app_id || '—'}</div>}</div>
|
|
129
220
|
<div className="space-y-2"><Label>Event Type</Label>{isEditing ? <Input value={formData.event_type} onChange={e => setFormData({...formData, event_type: e.target.value})} placeholder="e.g., item.created" /> : <Badge>{trigger?.event_type}</Badge>}</div>
|
|
130
|
-
<div className="space-y-2"><Label>Entity Type</Label>{isEditing ? <Input value={formData.entity_type} onChange={e => setFormData({...formData, entity_type: e.target.value})} placeholder="e.g., item" /> : <div className="text-sm">{trigger?.entity_type || '—'}</div>}</div>
|
|
131
221
|
<div className="space-y-2"><Label>Active</Label>{isEditing ? <div className="flex items-center gap-2"><Checkbox id="active" checked={formData.is_active} onCheckedChange={c => setFormData({...formData, is_active: c === true})} /><Label htmlFor="active">Enabled</Label></div> : <div className="text-sm">{trigger?.is_active ? 'Yes' : 'No'}</div>}</div>
|
|
132
222
|
</div>
|
|
133
223
|
<div className="space-y-4">
|
|
134
224
|
<h3 className="text-sm font-medium text-muted-foreground">Action</h3>
|
|
135
|
-
<div className="space-y-2"><Label>
|
|
136
|
-
<div className="space-y-2"><Label>Priority</Label>{isEditing ? <Input type="number" value={formData.priority} onChange={e => setFormData({...formData, priority: parseInt(e.target.value)})} /> : <div className="text-sm">{trigger?.priority}</div>}</div>
|
|
137
|
-
<div className="space-y-2"><Label>Debounce (ms)</Label>{isEditing ? <Input type="number" value={formData.debounce_ms} onChange={e => setFormData({...formData, debounce_ms: parseInt(e.target.value)})} /> : <div className="text-sm">{trigger?.debounce_ms}ms</div>}</div>
|
|
138
|
-
<div className="space-y-2"><Label>Rate Limit (/min)</Label>{isEditing ? <Input type="number" value={formData.rate_limit_per_minute} onChange={e => setFormData({...formData, rate_limit_per_minute: parseInt(e.target.value)})} /> : <div className="text-sm">{trigger?.rate_limit_per_minute}</div>}</div>
|
|
225
|
+
<div className="space-y-2"><Label>Pipeline ID</Label>{isEditing ? <Input value={formData.pipeline_id} onChange={e => setFormData({...formData, pipeline_id: e.target.value})} placeholder="Pipeline to invoke" /> : <div className="text-sm font-mono">{trigger?.pipeline_id || '—'}</div>}</div>
|
|
139
226
|
</div>
|
|
140
227
|
</div>
|
|
141
228
|
<div className="mt-6 space-y-2"><Label>Description</Label>{isEditing ? <Textarea value={formData.description} onChange={e => setFormData({...formData, description: e.target.value})} rows={2} /> : <div className="text-sm">{trigger?.description || '—'}</div>}</div>
|
|
142
229
|
<div className="mt-6 grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
143
|
-
<div className="space-y-2"><Label>
|
|
144
|
-
<div className="space-y-2"><Label>
|
|
230
|
+
<div className="space-y-2"><Label>Config (JSON)</Label>{isEditing ? <Textarea value={formData.config} onChange={e => setFormData({...formData, config: e.target.value})} rows={6} className="font-mono text-sm" /> : <pre className="text-sm bg-muted p-3 rounded">{JSON.stringify(trigger?.config || {}, null, 2)}</pre>}</div>
|
|
231
|
+
<div className="space-y-2"><Label>Metadata (JSON)</Label>{isEditing ? <Textarea value={formData.metadata} onChange={e => setFormData({...formData, metadata: e.target.value})} rows={6} className="font-mono text-sm" /> : <pre className="text-sm bg-muted p-3 rounded">{JSON.stringify(trigger?.metadata || {}, null, 2)}</pre>}</div>
|
|
145
232
|
</div>
|
|
146
233
|
</CardContent></Card>
|
|
147
234
|
</div>
|
|
148
235
|
)
|
|
149
236
|
}
|
|
237
|
+
// CIL[END chunk_id="triggerdetailpage_triggerdetailpage_1783664706"]
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/pages/admin/TriggersPage
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-page
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Admin list page for event/schedule/webhook triggers. Fetches all
|
|
8
|
-
* triggers via `/api/triggers?action=list`, applies client-side search,
|
|
9
|
-
* trigger-type filter, and sort. Supports inline enable/disable toggle.
|
|
10
|
-
* Renders inside `AdminListPage`. Row clicks navigate to
|
|
11
|
-
* `/spine-framework/admin/configs/triggers/:id`.
|
|
12
|
-
*
|
|
13
|
-
* @seeAlso src/pages/admin/TriggerDetailPage.tsx
|
|
14
|
-
*/
|
|
15
1
|
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// CIL[BEGIN chunk_id="triggerspage_moduleheader_1783664706" type="module_header" identity="module_header" parent="none"]
|
|
6
|
+
// CIL[DOC-MACRO purpose="Import dependencies for TriggersPage component"]
|
|
7
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide all external dependencies and UI components"]
|
|
8
|
+
// CIL[DOC-CONTEXT module="TriggersPage" layer="frontend-page" related_files="[\".framework/src/components/layout/Sidebar.tsx\",\".framework/src/components/ui/dialog.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
|
|
9
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="React components and utilities" errors="none" side_effects="none"]
|
|
10
|
+
// CIL[DOC-MICRO logic_summary="Imports React hooks, navigation, API utilities, icons, and UI components" notable_decisions="[]"]
|
|
11
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
12
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
13
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
14
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/components/layout/Sidebar.tsx, .framework/src/components/ui/dialog.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
|
|
15
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
16
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
17
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
18
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
19
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
16
20
|
import React, { useState } from 'react'
|
|
17
21
|
import { useNavigate } from 'react-router-dom'
|
|
18
22
|
import { useApi } from '../../hooks/useApi'
|
|
@@ -25,7 +29,21 @@ import { Badge } from '../../components/ui/badge'
|
|
|
25
29
|
import { formatDateTime } from '../../lib/utils'
|
|
26
30
|
import { AdminListPage } from '../../components/admin/AdminListPage'
|
|
27
31
|
import { SortableTableHeader } from '../../components/admin/SortableTableHeader'
|
|
28
|
-
|
|
32
|
+
// CIL[END chunk_id="triggerspage_moduleheader_1783664706"]
|
|
33
|
+
// CIL[BEGIN chunk_id="triggerspage_trigger_1783664706" type="interface" identity="Trigger" parent="none"]
|
|
34
|
+
// CIL[DOC-MACRO purpose="Define the Trigger data structure for trigger management"]
|
|
35
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide type definition for event/schedule/webhook triggers"]
|
|
36
|
+
// CIL[DOC-CONTEXT module="TriggersPage" layer="frontend-page" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"\\\"]"]
|
|
37
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Trigger interface" errors="none" side_effects="none"]
|
|
38
|
+
// CIL[DOC-MICRO logic_summary="Defines comprehensive trigger structure with execution tracking" notable_decisions="[]"]
|
|
39
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
40
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
41
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/pages/admin/TypeDetailPage.tsx, \."]
|
|
42
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
43
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
44
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
45
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
46
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
29
47
|
interface Trigger {
|
|
30
48
|
id: string
|
|
31
49
|
name: string
|
|
@@ -43,7 +61,21 @@ interface Trigger {
|
|
|
43
61
|
last_execution?: string
|
|
44
62
|
next_execution?: string
|
|
45
63
|
}
|
|
46
|
-
|
|
64
|
+
// CIL[END chunk_id="triggerspage_trigger_1783664706"]
|
|
65
|
+
// CIL[BEGIN chunk_id="triggerspage_triggerexecution_1783664706" type="interface" identity="TriggerExecution" parent="none"]
|
|
66
|
+
// CIL[DOC-MACRO purpose="Define the TriggerExecution data structure for execution tracking"]
|
|
67
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide type definition for trigger execution records"]
|
|
68
|
+
// CIL[DOC-CONTEXT module="TriggersPage" layer="frontend-page" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\".framework/src/components/layout/Sidebar.tsx\",\"\\\"]"]
|
|
69
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="TriggerExecution interface" errors="none" side_effects="none"]
|
|
70
|
+
// CIL[DOC-MICRO logic_summary="Defines execution tracking structure with status and results" notable_decisions="[]"]
|
|
71
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
72
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
73
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, .framework/src/components/layout/Sidebar.tsx, \."]
|
|
74
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
75
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
76
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
77
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
78
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
47
79
|
interface TriggerExecution {
|
|
48
80
|
id: string
|
|
49
81
|
trigger_id: string
|
|
@@ -54,7 +86,21 @@ interface TriggerExecution {
|
|
|
54
86
|
result?: Record<string, any>
|
|
55
87
|
error?: string
|
|
56
88
|
}
|
|
57
|
-
|
|
89
|
+
// CIL[END chunk_id="triggerspage_triggerexecution_1783664706"]
|
|
90
|
+
// CIL[BEGIN chunk_id="triggerspage_triggerspage_1783664706" type="function" identity="TriggersPage" parent="none"]
|
|
91
|
+
// CIL[DOC-MACRO purpose="Admin list page for managing automated triggers for workflows"]
|
|
92
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Fetch, filter, sort, and display triggers with navigation"]
|
|
93
|
+
// CIL[DOC-CONTEXT module="TriggersPage" layer="frontend-page" related_files="[\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
94
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="React component with trigger list" errors="API failures" side_effects="API calls, navigation"]
|
|
95
|
+
// CIL[DOC-MICRO logic_summary="Client-side filtering, sorting, and stats calculation for triggers" notable_decisions="[]"]
|
|
96
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
97
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
98
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
99
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
100
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
101
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
102
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
103
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
58
104
|
export function TriggersPage() {
|
|
59
105
|
console.log('TriggersPage rendering...')
|
|
60
106
|
const navigate = useNavigate()
|
|
@@ -64,7 +110,6 @@ export function TriggersPage() {
|
|
|
64
110
|
const [sortKey, setSortKey] = useState('name')
|
|
65
111
|
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('asc')
|
|
66
112
|
|
|
67
|
-
// Fetch triggers from API
|
|
68
113
|
const { data: triggers, loading, error, refetch } = useApi<Trigger[]>(
|
|
69
114
|
async ({ signal }: { signal?: AbortSignal }) => {
|
|
70
115
|
try {
|
|
@@ -81,7 +126,6 @@ export function TriggersPage() {
|
|
|
81
126
|
const result = await response.json()
|
|
82
127
|
console.log('Raw API result:', result)
|
|
83
128
|
|
|
84
|
-
// Handle both nested and direct responses
|
|
85
129
|
const triggers = result.data || result
|
|
86
130
|
console.log('Triggers after processing:', triggers)
|
|
87
131
|
|
|
@@ -379,3 +423,4 @@ export function TriggersPage() {
|
|
|
379
423
|
</AdminListPage>
|
|
380
424
|
)
|
|
381
425
|
}
|
|
426
|
+
// CIL[END chunk_id="triggerspage_triggerspage_1783664706"]
|
|
@@ -1,12 +1,22 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/pages/admin/TypeDetailPage
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-page
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Create / view / edit / delete page for a single type record.
|
|
8
|
-
*/
|
|
9
1
|
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
// CIL[BEGIN chunk_id="typedetailpage_moduleheader_1783664706" type="module_header" identity="module_header" parent="none"]
|
|
6
|
+
// CIL[DOC-MACRO purpose="Import dependencies for TypeDetailPage component"]
|
|
7
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide all external dependencies and UI components"]
|
|
8
|
+
// CIL[DOC-CONTEXT module="TypeDetailPage" layer="frontend-page" related_files="[\".framework/src/components/ui/dialog.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
9
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="React components and utilities" errors="none" side_effects="none"]
|
|
10
|
+
// CIL[DOC-MICRO logic_summary="Imports React hooks, navigation, API utilities, and UI components" notable_decisions="[]"]
|
|
11
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
12
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
13
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
14
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/components/ui/dialog.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
15
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
16
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
17
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
18
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
19
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
10
20
|
import React, { useState, useEffect } from 'react'
|
|
11
21
|
import { useParams, useNavigate } from 'react-router-dom'
|
|
12
22
|
import { useApi } from '../../hooks/useApi'
|
|
@@ -26,7 +36,22 @@ import { Alert, AlertDescription, AlertTitle } from '../../components/ui/alert'
|
|
|
26
36
|
import { DataTable } from '../../components/ui/DataTable'
|
|
27
37
|
import { ArrowLeft, Pencil, Trash2, AlertCircle } from 'lucide-react'
|
|
28
38
|
import { formatDateTime } from '../../lib/utils'
|
|
29
|
-
|
|
39
|
+
import { PageInstructions } from '../../components/admin/PageInstructions'
|
|
40
|
+
// CIL[END chunk_id="typedetailpage_moduleheader_1783664706"]
|
|
41
|
+
// CIL[BEGIN chunk_id="typedetailpage_type_1783664706" type="interface" identity="Type" parent="none"]
|
|
42
|
+
// CIL[DOC-MACRO purpose="Define the Type data structure for type management"]
|
|
43
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide type definition for item/account/person types"]
|
|
44
|
+
// CIL[DOC-CONTEXT module="TypeDetailPage" layer="frontend-page" related_files="[\".framework/migrations/025_retype_threads_messages.sql\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
45
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="Type interface" errors="none" side_effects="none"]
|
|
46
|
+
// CIL[DOC-MICRO logic_summary="Defines comprehensive type structure with design schema and permissions" notable_decisions="[]"]
|
|
47
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
48
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
49
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 1. Direct calls: 0. Related files: .framework/migrations/025_retype_threads_messages.sql, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
50
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 1. Total affected: 1."]
|
|
51
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
52
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
53
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
54
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
30
55
|
interface Type {
|
|
31
56
|
id: string
|
|
32
57
|
name: string
|
|
@@ -39,6 +64,8 @@ interface Type {
|
|
|
39
64
|
fields: Record<string, any>
|
|
40
65
|
record_permissions?: Record<string, string[]>
|
|
41
66
|
}
|
|
67
|
+
validation_schema?: Record<string, any>
|
|
68
|
+
view_config?: Record<string, any>
|
|
42
69
|
ownership: string
|
|
43
70
|
is_active: boolean
|
|
44
71
|
app_id?: string
|
|
@@ -46,7 +73,21 @@ interface Type {
|
|
|
46
73
|
created_at: string
|
|
47
74
|
updated_at: string
|
|
48
75
|
}
|
|
49
|
-
|
|
76
|
+
// CIL[END chunk_id="typedetailpage_type_1783664706"]
|
|
77
|
+
// CIL[BEGIN chunk_id="typedetailpage_typeitem_1783664706" type="interface" identity="TypeItem" parent="none"]
|
|
78
|
+
// CIL[DOC-MACRO purpose="Define the TypeItem data structure for item instances"]
|
|
79
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Provide type definition for type item records"]
|
|
80
|
+
// CIL[DOC-CONTEXT module="TypeDetailPage" layer="frontend-page" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/functions/_shared/principal.ts\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
81
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="TypeItem interface" errors="none" side_effects="none"]
|
|
82
|
+
// CIL[DOC-MICRO logic_summary="Defines item structure with data, metadata, and ownership" notable_decisions="[]"]
|
|
83
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
84
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
85
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/functions/_shared/principal.ts, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
86
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
87
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
88
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
89
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
90
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
50
91
|
interface TypeItem {
|
|
51
92
|
id: string
|
|
52
93
|
item_type_id: string
|
|
@@ -57,7 +98,21 @@ interface TypeItem {
|
|
|
57
98
|
created_by: string
|
|
58
99
|
account_id: string
|
|
59
100
|
}
|
|
60
|
-
|
|
101
|
+
// CIL[END chunk_id="typedetailpage_typeitem_1783664706"]
|
|
102
|
+
// CIL[BEGIN chunk_id="typedetailpage_typedetailpage_1783664706" type="function" identity="TypeDetailPage" parent="none"]
|
|
103
|
+
// CIL[DOC-MACRO purpose="Create/view/edit/delete page for single type records"]
|
|
104
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Manage type CRUD operations with form handling and validation"]
|
|
105
|
+
// CIL[DOC-CONTEXT module="TypeDetailPage" layer="frontend-page" related_files="[\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\"\\\"]"]
|
|
106
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="React component with type form" errors="API failures, validation errors" side_effects="API calls, navigation"]
|
|
107
|
+
// CIL[DOC-MICRO logic_summary="Complex form handling with schema validation and item management" notable_decisions="[]"]
|
|
108
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
109
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
110
|
+
// CIL[DOC-VECTOR type="context" content="Layer: frontend-page. Direct callers: 0. Direct calls: 0. Related files: custom/apps/cortex/pages/operations/OperationsDashboard.tsx, custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/RolesPage.tsx, \."]
|
|
111
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
112
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
113
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
114
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
115
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
61
116
|
export function TypeDetailPage() {
|
|
62
117
|
const { id, kind } = useParams<{ id: string, kind: string }>()
|
|
63
118
|
const navigate = useNavigate()
|
|
@@ -73,12 +128,14 @@ export function TypeDetailPage() {
|
|
|
73
128
|
icon: '',
|
|
74
129
|
color: '',
|
|
75
130
|
kind: typeKind,
|
|
76
|
-
|
|
131
|
+
design_schema: { fields: {} },
|
|
132
|
+
view_config: {},
|
|
77
133
|
ownership: 'app',
|
|
78
134
|
app_id: '',
|
|
79
135
|
is_active: true
|
|
80
136
|
})
|
|
81
137
|
const [schemaText, setSchemaText] = useState(JSON.stringify({ fields: {} }, null, 2))
|
|
138
|
+
const [viewConfigText, setViewConfigText] = useState(JSON.stringify({}, null, 2))
|
|
82
139
|
const [availableApps, setAvailableApps] = useState<Array<{id: string, name: string}>>([])
|
|
83
140
|
|
|
84
141
|
React.useEffect(() => {
|
|
@@ -153,11 +210,13 @@ export function TypeDetailPage() {
|
|
|
153
210
|
color: type.color || '',
|
|
154
211
|
kind: type.kind || 'item',
|
|
155
212
|
design_schema: type.design_schema || { fields: {} },
|
|
213
|
+
view_config: type.view_config || {},
|
|
156
214
|
ownership: type.ownership || 'system',
|
|
157
215
|
app_id: type.app_id || '',
|
|
158
216
|
is_active: type.is_active ?? true
|
|
159
217
|
})
|
|
160
218
|
setSchemaText(JSON.stringify(type.design_schema || { fields: {} }, null, 2))
|
|
219
|
+
setViewConfigText(JSON.stringify(type.view_config || {}, null, 2))
|
|
161
220
|
}
|
|
162
221
|
}, [type])
|
|
163
222
|
|
|
@@ -169,14 +228,21 @@ export function TypeDetailPage() {
|
|
|
169
228
|
throw new Error('App selection is required when ownership is not "System"')
|
|
170
229
|
}
|
|
171
230
|
let parsedSchema = { fields: {} }
|
|
231
|
+
let parsedViewConfig = {}
|
|
172
232
|
try {
|
|
173
233
|
parsedSchema = JSON.parse(schemaText)
|
|
174
234
|
} catch (error) {
|
|
175
235
|
console.warn('Invalid JSON in schema field, using default:', error)
|
|
176
236
|
}
|
|
237
|
+
try {
|
|
238
|
+
parsedViewConfig = JSON.parse(viewConfigText)
|
|
239
|
+
} catch (error) {
|
|
240
|
+
console.warn('Invalid JSON in view config field, using default:', error)
|
|
241
|
+
}
|
|
177
242
|
const saveData = {
|
|
178
243
|
...editData,
|
|
179
244
|
design_schema: parsedSchema,
|
|
245
|
+
view_config: parsedViewConfig,
|
|
180
246
|
app_id: editData.app_id || null
|
|
181
247
|
}
|
|
182
248
|
const url = isCreateMode
|
|
@@ -216,11 +282,13 @@ export function TypeDetailPage() {
|
|
|
216
282
|
icon: type.icon || '',
|
|
217
283
|
color: type.color || '',
|
|
218
284
|
design_schema: type.design_schema || { fields: {} },
|
|
285
|
+
view_config: type.view_config || {},
|
|
219
286
|
ownership: type.ownership || 'system',
|
|
220
287
|
app_id: type.app_id || '',
|
|
221
288
|
is_active: type.is_active ?? true
|
|
222
289
|
})
|
|
223
290
|
setSchemaText(JSON.stringify(type.design_schema || { fields: {} }, null, 2))
|
|
291
|
+
setViewConfigText(JSON.stringify(type.view_config || {}, null, 2))
|
|
224
292
|
}
|
|
225
293
|
setIsEditing(false)
|
|
226
294
|
}
|
|
@@ -373,6 +441,48 @@ export function TypeDetailPage() {
|
|
|
373
441
|
</div>
|
|
374
442
|
</div>
|
|
375
443
|
|
|
444
|
+
<PageInstructions
|
|
445
|
+
description="Manage type schemas, fields, and permissions for items, accounts, or people."
|
|
446
|
+
sections={[
|
|
447
|
+
{ title: 'What this type controls', content: 'A type is the design schema for a runtime record kind. It defines the fields, default list/detail views, record permissions, icon, color, and metadata that the generic admin and runtime UIs use to create, validate, and display records.' },
|
|
448
|
+
{ title: 'Fields explained', content: <ul className="list-disc pl-4 space-y-1">
|
|
449
|
+
<li><strong>Name</strong> — string. The display label for the type. Empty name blocks save.</li>
|
|
450
|
+
<li><strong>Slug</strong> — string. A unique, URL-friendly identifier scoped by kind. Used for type resolution and must be globally unique.</li>
|
|
451
|
+
<li><strong>Description</strong> — string. Optional human-readable context.</li>
|
|
452
|
+
<li><strong>Kind</strong> — select. item, account, person, thread, or message. Determines which runtime table the type governs.</li>
|
|
453
|
+
<li><strong>Ownership</strong> — select. system, app, or tenant. Controls the data scope and who can manage the type.</li>
|
|
454
|
+
<li><strong>Is Active</strong> — checkbox. Inactive types cannot have records created.</li>
|
|
455
|
+
<li><strong>App ID</strong> — select. Optional owning app. None means a system type. Selecting an app scopes the type to that app.</li>
|
|
456
|
+
<li><strong>Icon</strong> — string. An icon name for the UI stored in the types row.</li>
|
|
457
|
+
<li><strong>Color</strong> — select. The theme color for the type stored in the types row.</li>
|
|
458
|
+
<li><strong>Created / Updated</strong> — read-only timestamps.</li>
|
|
459
|
+
<li><strong>Design Schema (JSON)</strong> — JSON. The full design_schema with fields, views, and record_permissions. The validation_schema is regenerated from this on save.</li>
|
|
460
|
+
<li><strong>View Config (JSON)</strong> — JSON. Optional view_config object stored alongside the design schema.</li>
|
|
461
|
+
</ul> },
|
|
462
|
+
{ title: 'Options and values', content: <ul className="list-disc pl-4 space-y-1">
|
|
463
|
+
<li><strong>Kind</strong>: <em>item</em> for records, <em>account</em> for accounts, <em>person</em> for people, <em>thread</em> for threads, <em>message</em> for messages.</li>
|
|
464
|
+
<li><strong>Ownership</strong>: <em>system</em> for platform types, <em>app</em> for an app, <em>tenant</em> for account-specific.</li>
|
|
465
|
+
<li><strong>Color</strong>: blue, green, red, yellow, purple, pink, indigo, gray, slate.</li>
|
|
466
|
+
<li><strong>Design Schema</strong>: must include fields, default_list, default_detail, and record_permissions to satisfy the generic UI.</li>
|
|
467
|
+
</ul> },
|
|
468
|
+
{ title: 'Downstream impact', content: <ul className="list-disc pl-4 space-y-1">
|
|
469
|
+
<li>Generic List and Detail pages render directly from this schema. A missing view or bad field will break those pages.</li>
|
|
470
|
+
<li>Record creation and validation use the design schema. Bad permissions or data_type values can cause permission errors or failed saves.</li>
|
|
471
|
+
<li>Other apps, pipelines, and triggers resolve types by slug; duplicate or changed slugs break those lookups.</li>
|
|
472
|
+
</ul> },
|
|
473
|
+
{ title: 'How to create, save, and validate', content: <ol className="list-decimal pl-4 space-y-1">
|
|
474
|
+
<li>In create mode, choose a kind, name, slug, and ownership, then fill the Design Schema and optional View Config JSON.</li>
|
|
475
|
+
<li>Click Create or Save Changes. The form validates that the JSON is valid; the API regenerates validation_schema from design_schema.</li>
|
|
476
|
+
<li>Delete is disabled for system-owned types. Delete opens a confirmation modal for others.</li>
|
|
477
|
+
</ol> },
|
|
478
|
+
{ title: 'Common mistakes', content: <ul className="list-disc pl-4 space-y-1">
|
|
479
|
+
<li>Reusing a slug for the same kind, which breaks type resolution.</li>
|
|
480
|
+
<li>Missing default_list or default_detail in the design schema, causing the generic UI to fail.</li>
|
|
481
|
+
<li>Using an unknown data_type or display_type, leading to validation or rendering errors.</li>
|
|
482
|
+
</ul> },
|
|
483
|
+
]}
|
|
484
|
+
/>
|
|
485
|
+
|
|
376
486
|
{isEditing ? (
|
|
377
487
|
<>
|
|
378
488
|
<Card>
|
|
@@ -514,15 +624,27 @@ export function TypeDetailPage() {
|
|
|
514
624
|
|
|
515
625
|
<div className="mt-8 space-y-2">
|
|
516
626
|
<h3 className="text-sm font-medium text-muted-foreground">Schema Definition</h3>
|
|
517
|
-
<Label>Schema</Label>
|
|
627
|
+
<Label>Design Schema</Label>
|
|
518
628
|
<Textarea
|
|
519
629
|
value={schemaText}
|
|
520
630
|
onChange={(e) => setSchemaText(e.target.value)}
|
|
521
631
|
className="font-mono text-sm"
|
|
522
632
|
rows={8}
|
|
523
|
-
placeholder='Enter JSON schema with fields
|
|
633
|
+
placeholder='Enter JSON design schema with fields, views, and record_permissions'
|
|
634
|
+
/>
|
|
635
|
+
<p className="text-xs text-muted-foreground">JSON schema defining the fields, list/detail views, and record permissions for this type. The validation_schema is generated from this on save.</p>
|
|
636
|
+
</div>
|
|
637
|
+
|
|
638
|
+
<div className="mt-8 space-y-2">
|
|
639
|
+
<Label>View Config</Label>
|
|
640
|
+
<Textarea
|
|
641
|
+
value={viewConfigText}
|
|
642
|
+
onChange={(e) => setViewConfigText(e.target.value)}
|
|
643
|
+
className="font-mono text-sm"
|
|
644
|
+
rows={4}
|
|
645
|
+
placeholder='Enter optional view_config JSON'
|
|
524
646
|
/>
|
|
525
|
-
<p className="text-xs text-muted-foreground">JSON
|
|
647
|
+
<p className="text-xs text-muted-foreground">Optional JSON view configuration stored alongside the design schema.</p>
|
|
526
648
|
</div>
|
|
527
649
|
</CardContent>
|
|
528
650
|
</Card>
|
|
@@ -692,3 +814,4 @@ export function TypeDetailPage() {
|
|
|
692
814
|
</div>
|
|
693
815
|
)
|
|
694
816
|
}
|
|
817
|
+
// CIL[END chunk_id="typedetailpage_typedetailpage_1783664706"]
|