From c5a42506c128bf42d7d4c360ff6a2d793579534a Mon Sep 17 00:00:00 2001 From: Bernt Date: Thu, 2 Jul 2026 16:57:20 +0000 Subject: [PATCH] Readiness Dashboard: System status before external pilots - Shows all systems: API, Database, Storage, Upload, Mission, Map, Replay, AI Processing, Decision Pipeline - Color-coded status: Green/Ready, Yellow/Partial, Red/Not Ready - Version info: Environment, Version, Commit, Build time - Exit criteria checklist for external pilots Next: Deploy pilot environment --- packages/ui/src/App.tsx | 3 + packages/ui/src/pages/ReadinessDashboard.tsx | 146 +++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 packages/ui/src/pages/ReadinessDashboard.tsx diff --git a/packages/ui/src/App.tsx b/packages/ui/src/App.tsx index f81ba4196..e878c3a92 100644 --- a/packages/ui/src/App.tsx +++ b/packages/ui/src/App.tsx @@ -5,6 +5,7 @@ import MissionUpload from './pages/MissionUpload'; import FieldConsole from './pages/FieldConsole'; import HealthDashboard from './pages/HealthDashboard'; import PilotChecklist from './pages/PilotChecklist'; +import ReadinessDashboard from './pages/ReadinessDashboard'; function App() { return ( @@ -17,6 +18,7 @@ function App() { Field Console Health Pilot 001 + Readiness @@ -27,6 +29,7 @@ function App() { } /> } /> } /> + } /> ); diff --git a/packages/ui/src/pages/ReadinessDashboard.tsx b/packages/ui/src/pages/ReadinessDashboard.tsx new file mode 100644 index 000000000..638abb51c --- /dev/null +++ b/packages/ui/src/pages/ReadinessDashboard.tsx @@ -0,0 +1,146 @@ +/** + * Readiness Dashboard + * + * Shows system status before opening for external pilots. + * Green = ready, Yellow = partial, Red = not ready + */ + +import { useEffect, useState } from 'react'; + +interface SystemStatus { + name: string; + status: 'ready' | 'partial' | 'not-ready'; + details: string; +} + +function ReadinessDashboard() { + const [systems] = useState([ + { name: 'API', status: 'ready', details: 'Running on port 3002' }, + { name: 'Database', status: 'ready', details: 'In-memory (PostgreSQL in PR-003B)' }, + { name: 'Object Storage', status: 'partial', details: 'File system (MinIO in PR-003B)' }, + { name: 'Upload', status: 'ready', details: 'Multipart upload working' }, + { name: 'Mission Service', status: 'ready', details: 'Create, list, view missions' }, + { name: 'Map Service', status: 'not-ready', details: 'Not implemented yet' }, + { name: 'Replay', status: 'not-ready', details: 'Not implemented yet' }, + { name: 'AI Processing', status: 'not-ready', details: 'Not implemented yet' }, + { name: 'Decision Pipeline', status: 'not-ready', details: 'Not implemented yet' }, + ]); + + const [version, setVersion] = useState({ + environment: 'PILOT', + version: '0.1.0-pilot.1', + commit: 'unknown', + build: new Date().toISOString(), + }); + + useEffect(() => { + fetch('/health') + .then(r => r.json()) + .then(data => { + setVersion(prev => ({ + ...prev, + version: data.version || prev.version, + })); + }) + .catch(() => {}); + }, []); + + const readyCount = systems.filter(s => s.status === 'ready').length; + const totalCount = systems.length; + const progress = Math.round((readyCount / totalCount) * 100); + + return ( +
+

Readiness Dashboard

+ + {/* Version Info */} +
+

Environment: {version.environment}

+

Version: {version.version}

+

Commit: {version.commit}

+

Build: {version.build}

+
+ + {/* Progress */} +
+
+ System Readiness + {readyCount}/{totalCount} ({progress}%) +
+
+
50 ? '#ffd700' : '#dc143c', + transition: 'width 0.3s', + }} /> +
+
+ + {/* Systems */} +
+ {systems.map(system => ( +
+
+

{system.name}

+

{system.details}

+
+ +
+ ))} +
+ + {/* Exit Criteria */} +
+

Exit Criteria for External Pilots

+
    +
  • ✅ All functional checks pass
  • +
  • ✅ No blocking bugs for multiple test missions
  • +
  • ✅ Stable upload
  • +
  • ✅ Logging works
  • +
  • ✅ Backup works
  • +
  • ✅ Version update without data loss
  • +
  • ✅ New tester can install app independently
  • +
  • ✅ New tester can complete mission without help
  • +
  • ✅ Can debug mission from start to finish
  • +
+
+
+ ); +} + +function StatusBadge({ status }: { status: 'ready' | 'partial' | 'not-ready' }) { + const colors = { + ready: '#32cd32', + partial: '#ffd700', + 'not-ready': '#dc143c', + }; + + const labels = { + ready: '🟢 Ready', + partial: '🟡 Partial', + 'not-ready': '🔴 Not Ready', + }; + + return ( + + {labels[status]} + + ); +} + +export default ReadinessDashboard;