spine-framework 0.3.125 → 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 +169 -97
- package/.framework/cli/commands/generate.ts +82 -160
- 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} +147 -54
- package/.framework/functions/_shared/db.ts +80 -126
- package/.framework/functions/_shared/hash-api-key.ts +63 -0
- package/.framework/functions/_shared/index.ts +222 -347
- 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 +162 -14
- 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 +687 -533
- 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 +173 -145
- 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 +192 -115
- 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 +3 -3
- 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,28 +1,48 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @module src/pages/admin/LogsPage
|
|
3
|
-
* @audience installer
|
|
4
|
-
* @layer frontend-page
|
|
5
|
-
* @stability stable
|
|
6
|
-
*
|
|
7
|
-
* Admin log viewer. Fetches system audit/activity logs via
|
|
8
|
-
* `/api/admin-data?action=logs`, applies client-side search, severity
|
|
9
|
-
* filter, date-range filter, and sort. Renders inside `AdminListPage`
|
|
10
|
-
* with a sortable table. Useful for debugging pipeline executions,
|
|
11
|
-
* auth events, and API errors.
|
|
12
|
-
*
|
|
13
|
-
* @seeAlso src/pages/admin/ObservabilityDashboard.tsx
|
|
14
|
-
*/
|
|
15
1
|
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
// CIL[BEGIN chunk_id="logspage_module_header_1783666257" type="module_header" identity="imports" parent="none"]
|
|
7
|
+
// CIL[DOC-MACRO purpose="Import React dependencies and UI components"]
|
|
8
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Import all required modules for LogsPage component"]
|
|
9
|
+
// CIL[DOC-CONTEXT module="LogsPage" layer="ui" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/src/components/layout/Sidebar.tsx\",\"custom/apps/portal/pages/CoursesPage.tsx\",\"\\\"]"]
|
|
10
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="React hooks, UI components, utilities" errors="Import errors" side_effects="Module loading"]
|
|
11
|
+
// CIL[DOC-MICRO logic_summary="Imports React, icons, UI components, and utility functions" notable_decisions="[]"]
|
|
12
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
13
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
14
|
+
// CIL[DOC-AUDIENCE audience="developer"]
|
|
15
|
+
// CIL[DOC-VECTOR type="context" content="Layer: ui. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/ui/dialog.tsx, .framework/src/components/layout/Sidebar.tsx, custom/apps/portal/pages/CoursesPage.tsx, \."]
|
|
16
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
17
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
18
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
19
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
20
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
21
|
+
import React, { useState, useEffect } from 'react'
|
|
22
|
+
import { FileText, Search, Calendar, AlertTriangle, CheckCircle, User, X } from 'lucide-react';
|
|
18
23
|
import { LoadingSpinner } from '../../components/ui/LoadingSpinner'
|
|
19
24
|
import { Button } from '../../components/ui/button'
|
|
25
|
+
import { Input } from '../../components/ui/input'
|
|
20
26
|
import { AdminListPage } from '../../components/admin/AdminListPage'
|
|
21
27
|
import { SortableTableHeader } from '../../components/admin/SortableTableHeader'
|
|
22
28
|
import { formatDateTime } from '../../lib/utils'
|
|
23
29
|
import { useApi } from '../../hooks/useApi'
|
|
24
30
|
import { apiFetch } from '../../lib/api'
|
|
25
|
-
|
|
31
|
+
// CIL[END chunk_id="logspage_module_header_1783666257"]
|
|
32
|
+
// CIL[BEGIN chunk_id="logspage_interface_logentry_1783666257" type="interface" identity="LogEntry" parent="none"]
|
|
33
|
+
// CIL[DOC-MACRO purpose="Define log entry data structure"]
|
|
34
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Type definition for log entries"]
|
|
35
|
+
// CIL[DOC-CONTEXT module="LogsPage" layer="types" related_files="[\".framework/src/pages/admin/IntegrationsPage.tsx\",\".framework/src/components/ui/dialog.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/cortex/functions/custom_cil-embeddings.ts\",\".framework/functions/_shared/principal.ts\",\"\\\"]"]
|
|
36
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="LogEntry interface" errors="Type errors" side_effects="Type system"]
|
|
37
|
+
// CIL[DOC-MICRO logic_summary="Defines structure for system log entries with optional fields" notable_decisions="[]"]
|
|
38
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
39
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
40
|
+
// CIL[DOC-VECTOR type="context" content="Layer: types. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/IntegrationsPage.tsx, .framework/src/components/ui/dialog.tsx, .framework/functions/_shared/schema-utils.ts, custom/apps/cortex/functions/custom_cil-embeddings.ts, .framework/functions/_shared/principal.ts, \."]
|
|
41
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
42
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
43
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
44
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
45
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
26
46
|
interface LogEntry {
|
|
27
47
|
id: string
|
|
28
48
|
event_type: string
|
|
@@ -30,8 +50,17 @@ interface LogEntry {
|
|
|
30
50
|
target_type?: string
|
|
31
51
|
target_id?: string
|
|
32
52
|
action?: string
|
|
53
|
+
span_name?: string
|
|
54
|
+
trace_id?: string
|
|
55
|
+
span_id?: string
|
|
56
|
+
parent_span_id?: string
|
|
57
|
+
duration_ms?: number
|
|
58
|
+
outcome?: string
|
|
59
|
+
event_category?: string
|
|
60
|
+
kind?: string
|
|
33
61
|
details?: Record<string, any>
|
|
34
62
|
metadata?: Record<string, any>
|
|
63
|
+
message?: string
|
|
35
64
|
created_at: string
|
|
36
65
|
actor?: {
|
|
37
66
|
id: string
|
|
@@ -40,50 +69,154 @@ interface LogEntry {
|
|
|
40
69
|
}
|
|
41
70
|
}
|
|
42
71
|
|
|
43
|
-
|
|
72
|
+
interface LogsResponse {
|
|
73
|
+
data: LogEntry[]
|
|
74
|
+
total: number
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
interface StatsResponse {
|
|
78
|
+
total: number
|
|
79
|
+
error_count: number
|
|
80
|
+
user_action_count: number
|
|
81
|
+
event_type_count: number
|
|
82
|
+
levels: string[]
|
|
83
|
+
sources: string[]
|
|
84
|
+
source_types: string[]
|
|
85
|
+
}
|
|
86
|
+
// CIL[END chunk_id="logspage_interface_logentry_1783666257"]
|
|
87
|
+
// CIL[BEGIN chunk_id="logspage_function_logspage_1783666257" type="function" identity="LogsPage" parent="none"]
|
|
88
|
+
// CIL[DOC-MACRO purpose="Render the complete logs interface"]
|
|
89
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Main render logic for logs page"]
|
|
90
|
+
// CIL[DOC-CONTEXT module="LogsPage" layer="ui" related_files="[\".framework/src/pages/admin/RolesPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/components/layout/Sidebar.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"custom/apps/portal/pages/ContentPage.tsx\"]"]
|
|
91
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="JSX structure" errors="Render errors" side_effects="DOM updates"]
|
|
92
|
+
// CIL[DOC-MICRO logic_summary="Renders AdminListPage with date filters, table, and empty states" notable_decisions="[]"]
|
|
93
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
94
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
95
|
+
// CIL[DOC-VECTOR type="context" content="Layer: ui. Direct callers: 0. Direct calls: 0. Related files: .framework/src/pages/admin/RolesPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/components/layout/Sidebar.tsx, .framework/functions/_shared/schema-utils.ts, custom/apps/portal/pages/ContentPage.tsx."]
|
|
96
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
97
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
98
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
99
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
100
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
101
|
+
export function LogsPage({ title = 'System Logs' }: { title?: string }) {
|
|
44
102
|
const [searchTerm, setSearchTerm] = useState('')
|
|
45
103
|
const [selectedEventType, setSelectedEventType] = useState('all')
|
|
104
|
+
const [selectedSource, setSelectedSource] = useState('all')
|
|
105
|
+
const [selectedSourceType, setSelectedSourceType] = useState('all')
|
|
106
|
+
const [sourceIdFilter, setSourceIdFilter] = useState('')
|
|
107
|
+
const [actorIdFilter, setActorIdFilter] = useState('')
|
|
46
108
|
const [dateFrom, setDateFrom] = useState('')
|
|
47
109
|
const [dateTo, setDateTo] = useState('')
|
|
48
110
|
const [sortKey, setSortKey] = useState('created_at')
|
|
49
111
|
const [sortDirection, setSortDirection] = useState<'asc' | 'desc'>('desc')
|
|
112
|
+
const [page, setPage] = useState(1)
|
|
113
|
+
const [expandedRowId, setExpandedRowId] = useState<string | null>(null)
|
|
114
|
+
const [traceIdFilter, setTraceIdFilter] = useState('')
|
|
115
|
+
const pageSize = 100
|
|
116
|
+
|
|
117
|
+
const buildLogUrl = (forStats = false) => {
|
|
118
|
+
const params = new URLSearchParams()
|
|
119
|
+
params.set('action', forStats ? 'stats' : 'account')
|
|
120
|
+
if (searchTerm.trim()) params.set('query', searchTerm.trim())
|
|
121
|
+
if (selectedEventType !== 'all') params.set('event_type', selectedEventType)
|
|
122
|
+
if (selectedSource !== 'all') params.set('source', selectedSource)
|
|
123
|
+
if (selectedSourceType !== 'all') params.set('target_type', selectedSourceType)
|
|
124
|
+
if (sourceIdFilter.trim()) params.set('source_id', sourceIdFilter.trim())
|
|
125
|
+
if (actorIdFilter.trim()) params.set('actor_id', actorIdFilter.trim())
|
|
126
|
+
if (traceIdFilter.trim()) params.set('trace_id', traceIdFilter.trim())
|
|
127
|
+
if (dateFrom) params.set('date_from', dateFrom)
|
|
128
|
+
if (dateTo) params.set('date_to', dateTo)
|
|
129
|
+
if (!forStats) {
|
|
130
|
+
params.set('limit', pageSize.toString())
|
|
131
|
+
params.set('offset', ((page - 1) * pageSize).toString())
|
|
132
|
+
}
|
|
133
|
+
return `/api/logs?${params.toString()}`
|
|
134
|
+
}
|
|
50
135
|
|
|
51
|
-
|
|
136
|
+
// CIL[BEGIN chunk_id="logspage_hooks_1783666257" type="hooks" identity="useApi" parent="logspage_function_logspage_1783666257"]
|
|
137
|
+
// CIL[DOC-MACRO purpose="Fetch logs and stats data from API"]
|
|
138
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Handle useApi"]
|
|
139
|
+
// CIL[DOC-CONTEXT module="LogsPage" layer="data" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/IntegrationsPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/functions/_shared/schema-utils.ts\",\"\\\"]"]
|
|
140
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="logs data, stats data" errors="API errors" side_effects="HTTP requests"]
|
|
141
|
+
// CIL[DOC-MICRO logic_summary="Uses useApi hook to fetch logs and statistics with date filtering" notable_decisions="[]"]
|
|
142
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
143
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
144
|
+
// CIL[DOC-VECTOR type="context" content="Layer: data. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/IntegrationsPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/functions/_shared/schema-utils.ts, \."]
|
|
145
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
146
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
147
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
148
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
149
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
150
|
+
const { data: logsData, loading, error, refetch } = useApi<LogsResponse>(
|
|
52
151
|
async () => {
|
|
53
|
-
|
|
54
|
-
if (dateFrom) url += `&date_from=${dateFrom}`
|
|
55
|
-
if (dateTo) url += `&date_to=${dateTo}`
|
|
56
|
-
|
|
57
|
-
const response = await apiFetch(url)
|
|
152
|
+
const response = await apiFetch(buildLogUrl())
|
|
58
153
|
if (!response.ok) throw new Error('Failed to fetch logs')
|
|
59
154
|
const result = await response.json()
|
|
60
|
-
return (result.data || result) as
|
|
155
|
+
return (result.data || result) as LogsResponse
|
|
61
156
|
},
|
|
62
157
|
{ immediate: true }
|
|
63
158
|
)
|
|
64
159
|
|
|
65
|
-
const
|
|
160
|
+
const logs = logsData?.data || []
|
|
161
|
+
const totalLogs = logsData?.total || 0
|
|
162
|
+
|
|
163
|
+
const { data: stats, refetch: refetchStats } = useApi<StatsResponse>(
|
|
66
164
|
async () => {
|
|
67
|
-
const response = await apiFetch(
|
|
165
|
+
const response = await apiFetch(buildLogUrl(true))
|
|
68
166
|
if (!response.ok) return null
|
|
69
167
|
const result = await response.json()
|
|
70
|
-
return result.data || result
|
|
168
|
+
return (result.data || result) as StatsResponse
|
|
71
169
|
},
|
|
72
170
|
{ immediate: true }
|
|
73
171
|
)
|
|
74
172
|
|
|
75
|
-
|
|
76
|
-
const
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
173
|
+
useEffect(() => {
|
|
174
|
+
const timer = setTimeout(() => {
|
|
175
|
+
refetch()
|
|
176
|
+
refetchStats()
|
|
177
|
+
}, 300)
|
|
178
|
+
return () => clearTimeout(timer)
|
|
179
|
+
}, [searchTerm, selectedEventType, selectedSource, selectedSourceType, sourceIdFilter, actorIdFilter, traceIdFilter, dateFrom, dateTo, page, refetch, refetchStats])
|
|
180
|
+
|
|
181
|
+
useEffect(() => {
|
|
182
|
+
setPage(1)
|
|
183
|
+
}, [searchTerm, selectedEventType, selectedSource, selectedSourceType, sourceIdFilter, actorIdFilter, traceIdFilter, dateFrom, dateTo])
|
|
184
|
+
// CIL[END chunk_id="logspage_hooks_1783666257"]
|
|
84
185
|
|
|
85
|
-
|
|
186
|
+
// CIL[BEGIN chunk_id="logspage_filters_1783666257" type="filter_logic" identity="filteredLogs" parent="logspage_function_logspage_1783666257"]
|
|
187
|
+
// CIL[DOC-MACRO purpose="Filter logs by search and event type"]
|
|
188
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Handle filteredLogs"]
|
|
189
|
+
// CIL[DOC-CONTEXT module="LogsPage" layer="logic" related_files="[\"custom/apps/portal/pages/ContentPage.tsx\",\".framework/src/pages/admin/TypeDetailPage.tsx\",\"custom/apps/cortex/pages/operations/OperationsDashboard.tsx\",\".framework/src/pages/admin/RolesPage.tsx\",\".framework/migrations/025_retype_threads_messages.sql\",\"\\\"]"]
|
|
190
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="filtered logs" errors="none" side_effects="none"]
|
|
191
|
+
// CIL[DOC-MICRO logic_summary="Filters logs based on search term and event type selection" notable_decisions="[]"]
|
|
192
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
193
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
194
|
+
// CIL[DOC-VECTOR type="context" content="Layer: logic. Direct callers: 0. Direct calls: 0. Related files: custom/apps/portal/pages/ContentPage.tsx, .framework/src/pages/admin/TypeDetailPage.tsx, custom/apps/cortex/pages/operations/OperationsDashboard.tsx, .framework/src/pages/admin/RolesPage.tsx, .framework/migrations/025_retype_threads_messages.sql, \."]
|
|
195
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
196
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
197
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
198
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
199
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
200
|
+
const filteredLogs = logs || []
|
|
86
201
|
|
|
202
|
+
const eventTypes = stats?.levels || []
|
|
203
|
+
const sourceOptions = stats?.sources || []
|
|
204
|
+
// CIL[END chunk_id="logspage_filters_1783666257"]
|
|
205
|
+
|
|
206
|
+
// CIL[BEGIN chunk_id="logspage_sorting_1783666257" type="sorting_logic" identity="handleSort" parent="logspage_function_logspage_1783666257"]
|
|
207
|
+
// CIL[DOC-MACRO purpose="Handle column sorting for logs table"]
|
|
208
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Handle handleSort"]
|
|
209
|
+
// CIL[DOC-CONTEXT module="handleSort" layer="unknown" related_files="[]"]
|
|
210
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
211
|
+
// CIL[DOC-MICRO logic_summary="Implements handleSort" notable_decisions="[]"]
|
|
212
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
213
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
214
|
+
// CIL[DOC-VECTOR type="context" content="Layer: unknown. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
215
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
216
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
217
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
218
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
219
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
87
220
|
const handleSort = (key: string) => {
|
|
88
221
|
if (sortKey === key) {
|
|
89
222
|
setSortDirection(sortDirection === 'asc' ? 'desc' : 'asc')
|
|
@@ -105,7 +238,22 @@ export function LogsPage() {
|
|
|
105
238
|
|
|
106
239
|
return 0
|
|
107
240
|
})
|
|
241
|
+
// CIL[END chunk_id="logspage_sorting_1783666257"]
|
|
108
242
|
|
|
243
|
+
// CIL[BEGIN chunk_id="logspage_badge_1783666257" type="utility_function" identity="getEventTypeBadge" parent="logspage_function_logspage_1783666257"]
|
|
244
|
+
// CIL[DOC-MACRO purpose="Generate colored badges for event types"]
|
|
245
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Handle getEventTypeBadge"]
|
|
246
|
+
// CIL[DOC-CONTEXT module="getEventTypeBadge" layer="unknown" related_files="[]"]
|
|
247
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
248
|
+
// CIL[DOC-MICRO logic_summary="Implements getEventTypeBadge" notable_decisions="[]"]
|
|
249
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
250
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
251
|
+
// CIL[DOC-VECTOR type="context" content="Layer: unknown. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
252
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
253
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
254
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
255
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
256
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
109
257
|
const getEventTypeBadge = (eventType: string) => {
|
|
110
258
|
if (eventType.includes('error') || eventType.includes('failed')) {
|
|
111
259
|
return <span className="inline-flex px-2 py-0.5 text-xs font-medium rounded-md bg-red-100 text-red-700">{eventType}</span>
|
|
@@ -118,51 +266,102 @@ export function LogsPage() {
|
|
|
118
266
|
}
|
|
119
267
|
return <span className="inline-flex px-2 py-0.5 text-xs font-medium rounded-md bg-slate-100 text-slate-600">{eventType}</span>
|
|
120
268
|
}
|
|
269
|
+
// CIL[END chunk_id="logspage_badge_1783666257"]
|
|
121
270
|
|
|
271
|
+
// CIL[BEGIN chunk_id="logspage_stats_1783666257" type="stats_config" identity="statsCards" parent="logspage_function_logspage_1783666257"]
|
|
272
|
+
// CIL[DOC-MACRO purpose="Configure statistics cards and filters"]
|
|
273
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Handle statsCards"]
|
|
274
|
+
// CIL[DOC-CONTEXT module="LogsPage" layer="ui" related_files="[]"]
|
|
275
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="stats cards, filter options" errors="none" side_effects="none"]
|
|
276
|
+
// CIL[DOC-MICRO logic_summary="Creates stats cards and filter options for logs display" notable_decisions="[]"]
|
|
277
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
278
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
279
|
+
// CIL[DOC-VECTOR type="context" content="Layer: ui. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
280
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
281
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
282
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
283
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
284
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
122
285
|
const statsCards = [
|
|
123
286
|
{
|
|
124
287
|
title: 'Total Events',
|
|
125
|
-
value: stats?.total
|
|
288
|
+
value: stats?.total ?? totalLogs,
|
|
126
289
|
icon: FileText,
|
|
127
290
|
iconColor: 'text-blue-500'
|
|
128
291
|
},
|
|
129
292
|
{
|
|
130
293
|
title: 'Event Types',
|
|
131
|
-
value: eventTypes.length,
|
|
294
|
+
value: stats?.event_type_count ?? eventTypes.length,
|
|
132
295
|
icon: Calendar,
|
|
133
296
|
iconColor: 'text-purple-500'
|
|
134
297
|
},
|
|
135
298
|
{
|
|
136
299
|
title: 'Errors',
|
|
137
|
-
value:
|
|
300
|
+
value: stats?.error_count ?? 0,
|
|
138
301
|
icon: AlertTriangle,
|
|
139
302
|
iconColor: 'text-red-500'
|
|
140
303
|
},
|
|
141
304
|
{
|
|
142
305
|
title: 'User Actions',
|
|
143
|
-
value:
|
|
306
|
+
value: stats?.user_action_count ?? 0,
|
|
144
307
|
icon: User,
|
|
145
308
|
iconColor: 'text-green-500'
|
|
146
309
|
}
|
|
147
310
|
]
|
|
148
311
|
|
|
149
|
-
const
|
|
150
|
-
|
|
151
|
-
|
|
312
|
+
const makeOptions = (values: string[], current: string) => {
|
|
313
|
+
const set = new Set(['all', current, ...values])
|
|
314
|
+
return Array.from(set)
|
|
315
|
+
.filter(v => v && v !== 'all')
|
|
316
|
+
.map(v => ({ value: v, label: v }))
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
const eventTypeOptions = [{ value: 'all', label: 'All Levels' }, ...makeOptions(eventTypes, selectedEventType)]
|
|
320
|
+
const sourceSelectOptions = [{ value: 'all', label: 'All Sources' }, ...makeOptions(sourceOptions, selectedSource)]
|
|
321
|
+
const sourceTypeOptions = [
|
|
322
|
+
{ value: 'all', label: 'All Source Types' },
|
|
323
|
+
...makeOptions(stats?.source_types || [], selectedSourceType)
|
|
152
324
|
]
|
|
153
325
|
|
|
154
326
|
const filters = [
|
|
155
327
|
{
|
|
156
|
-
label: '
|
|
328
|
+
label: 'Level',
|
|
157
329
|
value: selectedEventType,
|
|
158
330
|
options: eventTypeOptions,
|
|
159
331
|
onChange: setSelectedEventType
|
|
332
|
+
},
|
|
333
|
+
{
|
|
334
|
+
label: 'Source',
|
|
335
|
+
value: selectedSource,
|
|
336
|
+
options: sourceSelectOptions,
|
|
337
|
+
onChange: setSelectedSource
|
|
338
|
+
},
|
|
339
|
+
{
|
|
340
|
+
label: 'Source Type',
|
|
341
|
+
value: selectedSourceType,
|
|
342
|
+
options: sourceTypeOptions,
|
|
343
|
+
onChange: setSelectedSourceType
|
|
160
344
|
}
|
|
161
345
|
]
|
|
346
|
+
// CIL[END chunk_id="logspage_stats_1783666257"]
|
|
162
347
|
|
|
348
|
+
// CIL[BEGIN chunk_id="logspage_render_1783666257" type="render_logic" identity="return" parent="logspage_function_logspage_1783666257"]
|
|
349
|
+
// CIL[DOC-MACRO purpose="Render the complete logs interface"]
|
|
350
|
+
// CIL[DOC-RESPONSIBILITY responsibility="Handle return"]
|
|
351
|
+
// CIL[DOC-CONTEXT module="return" layer="unknown" related_files="[]"]
|
|
352
|
+
// CIL[DOC-CONTRACT inputs="none" outputs="none" errors="none" side_effects="none"]
|
|
353
|
+
// CIL[DOC-MICRO logic_summary="Implements return" notable_decisions="[]"]
|
|
354
|
+
// CIL[DOC-CONFIDENCE pass="second" score="0.95" flags="none"]
|
|
355
|
+
// CIL[DOC-STABILITY stability="stable"]
|
|
356
|
+
// CIL[DOC-VECTOR type="context" content="Layer: unknown. Direct callers: 0. Direct calls: 0. Related files: none."]
|
|
357
|
+
// CIL[DOC-VECTOR type="blast_radius" content="Direct callers: 0. Total affected: 0."]
|
|
358
|
+
// CIL[DOC-VECTOR type="configuration" content="No configuration dependencies."]
|
|
359
|
+
// CIL[DOC-VECTOR type="constraint" content="No test paths identified."]
|
|
360
|
+
// CIL[DOC-VECTOR type="implementation_pattern" content="" status="pending_human_input"]
|
|
361
|
+
// CIL[DOC-VECTOR type="user_journey" content="" status="pending_human_input"]
|
|
163
362
|
return (
|
|
164
363
|
<AdminListPage
|
|
165
|
-
title=
|
|
364
|
+
title={title}
|
|
166
365
|
description="Audit trail and event history"
|
|
167
366
|
statsCards={statsCards}
|
|
168
367
|
searchPlaceholder="Search logs..."
|
|
@@ -175,7 +374,7 @@ export function LogsPage() {
|
|
|
175
374
|
emptyIcon={FileText}
|
|
176
375
|
>
|
|
177
376
|
<div className="px-6 py-4 border-b border-slate-200 bg-slate-50">
|
|
178
|
-
<div className="flex items-center gap-4">
|
|
377
|
+
<div className="flex flex-wrap items-center gap-4">
|
|
179
378
|
<div>
|
|
180
379
|
<label className="block text-xs font-medium text-slate-500 mb-1">From</label>
|
|
181
380
|
<input
|
|
@@ -194,13 +393,77 @@ export function LogsPage() {
|
|
|
194
393
|
className="px-3 py-1.5 text-sm border border-slate-300 rounded-md"
|
|
195
394
|
/>
|
|
196
395
|
</div>
|
|
396
|
+
<div>
|
|
397
|
+
<label className="block text-xs font-medium text-slate-500 mb-1">Source ID</label>
|
|
398
|
+
<Input
|
|
399
|
+
type="text"
|
|
400
|
+
placeholder="uuid"
|
|
401
|
+
value={sourceIdFilter}
|
|
402
|
+
onChange={(e) => setSourceIdFilter(e.target.value)}
|
|
403
|
+
className="w-48 px-3 py-1.5 text-sm"
|
|
404
|
+
/>
|
|
405
|
+
</div>
|
|
406
|
+
<div>
|
|
407
|
+
<label className="block text-xs font-medium text-slate-500 mb-1">Actor ID</label>
|
|
408
|
+
<Input
|
|
409
|
+
type="text"
|
|
410
|
+
placeholder="uuid"
|
|
411
|
+
value={actorIdFilter}
|
|
412
|
+
onChange={(e) => setActorIdFilter(e.target.value)}
|
|
413
|
+
className="w-48 px-3 py-1.5 text-sm"
|
|
414
|
+
/>
|
|
415
|
+
</div>
|
|
416
|
+
<div>
|
|
417
|
+
<label className="block text-xs font-medium text-slate-500 mb-1">Trace ID</label>
|
|
418
|
+
<Input
|
|
419
|
+
type="text"
|
|
420
|
+
placeholder="trace id"
|
|
421
|
+
value={traceIdFilter}
|
|
422
|
+
onChange={(e) => setTraceIdFilter(e.target.value)}
|
|
423
|
+
className="w-48 px-3 py-1.5 text-sm"
|
|
424
|
+
/>
|
|
425
|
+
</div>
|
|
197
426
|
<div className="flex-1" />
|
|
427
|
+
<Button
|
|
428
|
+
variant="outline"
|
|
429
|
+
onClick={() => {
|
|
430
|
+
setSearchTerm('')
|
|
431
|
+
setSelectedEventType('all')
|
|
432
|
+
setSelectedSource('all')
|
|
433
|
+
setSelectedSourceType('all')
|
|
434
|
+
setSourceIdFilter('')
|
|
435
|
+
setActorIdFilter('')
|
|
436
|
+
setTraceIdFilter('')
|
|
437
|
+
setDateFrom('')
|
|
438
|
+
setDateTo('')
|
|
439
|
+
setPage(1)
|
|
440
|
+
}}
|
|
441
|
+
className="text-sm"
|
|
442
|
+
>
|
|
443
|
+
<X className="h-4 w-4 mr-1" />
|
|
444
|
+
Clear
|
|
445
|
+
</Button>
|
|
198
446
|
<Button variant="secondary" onClick={refetch} className="text-sm">
|
|
199
447
|
Refresh
|
|
200
448
|
</Button>
|
|
201
449
|
</div>
|
|
202
450
|
</div>
|
|
203
451
|
|
|
452
|
+
{traceIdFilter && (
|
|
453
|
+
<div className="px-6 py-3 bg-blue-50 border-b border-blue-100 flex items-center justify-between">
|
|
454
|
+
<div className="text-sm text-blue-900">
|
|
455
|
+
Viewing trace <span className="font-mono font-medium">{traceIdFilter}</span>
|
|
456
|
+
</div>
|
|
457
|
+
<Button
|
|
458
|
+
variant="outline"
|
|
459
|
+
size="sm"
|
|
460
|
+
onClick={() => setTraceIdFilter('')}
|
|
461
|
+
>
|
|
462
|
+
Clear trace
|
|
463
|
+
</Button>
|
|
464
|
+
</div>
|
|
465
|
+
)}
|
|
466
|
+
|
|
204
467
|
{sortedLogs.length === 0 ? (
|
|
205
468
|
<div className="p-8 text-center">
|
|
206
469
|
<FileText className="mx-auto h-12 w-12 text-slate-400" />
|
|
@@ -221,29 +484,50 @@ export function LogsPage() {
|
|
|
221
484
|
onSort={handleSort}
|
|
222
485
|
/>
|
|
223
486
|
<SortableTableHeader
|
|
224
|
-
title="
|
|
487
|
+
title="Trace"
|
|
488
|
+
sortKey="trace_id"
|
|
489
|
+
currentSortKey={sortKey}
|
|
490
|
+
currentSortDirection={sortDirection}
|
|
491
|
+
onSort={handleSort}
|
|
492
|
+
/>
|
|
493
|
+
<SortableTableHeader
|
|
494
|
+
title="Level"
|
|
225
495
|
sortKey="event_type"
|
|
226
496
|
currentSortKey={sortKey}
|
|
227
497
|
currentSortDirection={sortDirection}
|
|
228
498
|
onSort={handleSort}
|
|
229
499
|
/>
|
|
230
500
|
<SortableTableHeader
|
|
231
|
-
title="
|
|
501
|
+
title="Source"
|
|
232
502
|
sortKey="action"
|
|
233
503
|
currentSortKey={sortKey}
|
|
234
504
|
currentSortDirection={sortDirection}
|
|
235
505
|
onSort={handleSort}
|
|
236
506
|
/>
|
|
237
507
|
<SortableTableHeader
|
|
238
|
-
title="
|
|
508
|
+
title="Source Type"
|
|
239
509
|
sortKey="target_type"
|
|
240
510
|
currentSortKey={sortKey}
|
|
241
511
|
currentSortDirection={sortDirection}
|
|
242
512
|
onSort={handleSort}
|
|
243
513
|
/>
|
|
244
514
|
<SortableTableHeader
|
|
245
|
-
title="
|
|
246
|
-
sortKey="
|
|
515
|
+
title="Source ID"
|
|
516
|
+
sortKey="target_id"
|
|
517
|
+
currentSortKey={sortKey}
|
|
518
|
+
currentSortDirection={sortDirection}
|
|
519
|
+
onSort={handleSort}
|
|
520
|
+
/>
|
|
521
|
+
<SortableTableHeader
|
|
522
|
+
title="Person"
|
|
523
|
+
sortKey="actor_id"
|
|
524
|
+
currentSortKey={sortKey}
|
|
525
|
+
currentSortDirection={sortDirection}
|
|
526
|
+
onSort={handleSort}
|
|
527
|
+
/>
|
|
528
|
+
<SortableTableHeader
|
|
529
|
+
title="Message"
|
|
530
|
+
sortKey="message"
|
|
247
531
|
currentSortKey={sortKey}
|
|
248
532
|
currentSortDirection={sortDirection}
|
|
249
533
|
onSort={handleSort}
|
|
@@ -252,32 +536,95 @@ export function LogsPage() {
|
|
|
252
536
|
</thead>
|
|
253
537
|
<tbody className="bg-white divide-y divide-slate-200">
|
|
254
538
|
{sortedLogs.map((log) => (
|
|
255
|
-
<
|
|
256
|
-
<
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
539
|
+
<React.Fragment key={log.id}>
|
|
540
|
+
<tr
|
|
541
|
+
className="hover:bg-slate-50 cursor-pointer"
|
|
542
|
+
onClick={() => setExpandedRowId(expandedRowId === log.id ? null : log.id)}
|
|
543
|
+
>
|
|
544
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-slate-500">
|
|
545
|
+
{formatDateTime(log.created_at)}
|
|
546
|
+
</td>
|
|
547
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm">
|
|
548
|
+
{log.trace_id ? (
|
|
549
|
+
<button
|
|
550
|
+
className="text-blue-600 hover:text-blue-800 font-mono"
|
|
551
|
+
title={`Trace: ${log.trace_id}${log.span_name ? ` / ${log.span_name}` : ''}`}
|
|
552
|
+
onClick={(e) => {
|
|
553
|
+
e.stopPropagation()
|
|
554
|
+
setTraceIdFilter(log.trace_id!)
|
|
555
|
+
setPage(1)
|
|
556
|
+
}}
|
|
557
|
+
>
|
|
558
|
+
{log.trace_id.slice(0, 8)}
|
|
559
|
+
</button>
|
|
560
|
+
) : (
|
|
561
|
+
<span className="text-slate-300">—</span>
|
|
562
|
+
)}
|
|
563
|
+
</td>
|
|
564
|
+
<td className="px-6 py-4 whitespace-nowrap">
|
|
565
|
+
{getEventTypeBadge(log.event_type)}
|
|
566
|
+
</td>
|
|
567
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-slate-900">
|
|
568
|
+
{log.action || '—'}
|
|
569
|
+
</td>
|
|
570
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-slate-600">
|
|
571
|
+
{log.target_type || '—'}
|
|
572
|
+
</td>
|
|
573
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-slate-600">
|
|
574
|
+
{log.target_id ? log.target_id.slice(0, 8) : '—'}
|
|
575
|
+
</td>
|
|
576
|
+
<td className="px-6 py-4 whitespace-nowrap text-sm text-slate-600">
|
|
577
|
+
{log.actor?.full_name || log.actor_id?.slice(0, 8) || 'System'}
|
|
578
|
+
</td>
|
|
579
|
+
<td className="px-6 py-4 text-sm text-slate-600 max-w-md truncate" title={log.message}>
|
|
580
|
+
{log.message || '—'}
|
|
581
|
+
</td>
|
|
582
|
+
</tr>
|
|
583
|
+
{expandedRowId === log.id && (
|
|
584
|
+
<tr>
|
|
585
|
+
<td colSpan={8} className="p-0 border-b border-slate-200">
|
|
586
|
+
<div className="p-6 bg-slate-50">
|
|
587
|
+
<h4 className="text-sm font-semibold text-slate-900 mb-3">Log Record</h4>
|
|
588
|
+
<pre className="text-xs bg-white border border-slate-200 rounded-md p-4 overflow-auto max-h-96">
|
|
589
|
+
{JSON.stringify(log, null, 2)}
|
|
590
|
+
</pre>
|
|
591
|
+
</div>
|
|
592
|
+
</td>
|
|
593
|
+
</tr>
|
|
594
|
+
)}
|
|
595
|
+
</React.Fragment>
|
|
277
596
|
))}
|
|
278
597
|
</tbody>
|
|
279
598
|
</table>
|
|
280
599
|
)}
|
|
600
|
+
|
|
601
|
+
{totalLogs > 0 && (
|
|
602
|
+
<div className="px-6 py-4 border-t border-slate-200 bg-slate-50 flex items-center justify-between">
|
|
603
|
+
<div className="text-sm text-slate-600">
|
|
604
|
+
Page {page} of {Math.max(1, Math.ceil(totalLogs / pageSize))} ({totalLogs} total)
|
|
605
|
+
</div>
|
|
606
|
+
<div className="flex gap-2">
|
|
607
|
+
<Button
|
|
608
|
+
variant="outline"
|
|
609
|
+
size="sm"
|
|
610
|
+
onClick={() => setPage(p => Math.max(1, p - 1))}
|
|
611
|
+
disabled={page <= 1}
|
|
612
|
+
>
|
|
613
|
+
Previous
|
|
614
|
+
</Button>
|
|
615
|
+
<Button
|
|
616
|
+
variant="outline"
|
|
617
|
+
size="sm"
|
|
618
|
+
onClick={() => setPage(p => p + 1)}
|
|
619
|
+
disabled={page >= Math.ceil(totalLogs / pageSize)}
|
|
620
|
+
>
|
|
621
|
+
Next
|
|
622
|
+
</Button>
|
|
623
|
+
</div>
|
|
624
|
+
</div>
|
|
625
|
+
)}
|
|
281
626
|
</AdminListPage>
|
|
282
627
|
)
|
|
283
628
|
}
|
|
629
|
+
// CIL[END chunk_id="logspage_render_1783666257"]
|
|
630
|
+
// CIL[END chunk_id="logspage_function_logspage_1783666257"]
|