Progress Log
Pre-Flight Check System
Pre-Flight Check System
Date: 2026-04-13 Type: Build Log
Context
The control center had a basic inline pre-flight check on the new-mission page that just read current telemetry values. We wanted a proper sequenced pre-flight system that also tests hardware (steering, motor, camera) and system health (SD card writes, clock sync) before launching a mission. The rover needs to be verified while it's still "home" and accessible.
What Changed
Convex Schema & Backend
Added two new tables (preflight_runs, preflight_checks) to persist pre-flight executions with per-check status tracking. Extended rover_commands with 5 new preflight command types: preflight_steering, preflight_drive, preflight_camera, preflight_write_test, preflight_clock_check.
Created convex/preflight.ts with mutations (startRun, resolveCheck, markCheckRunning, cancelRun) and queries (getActiveRun, getCommandStatus). The shared check definitions constant was extracted to src/lib/preflight-checks.ts to avoid Convex server imports in the browser (Convex warned about this).
Pi Agent Handlers
Created pi/preflight_checks.py with 5 hardware check handlers:
- Steering sweep: full left/center/right/center servo test (2s mock delay)
- Drive motor pulse: brief forward + reverse (1.5s mock delay)
- Camera snap: test photo capture, verify file size (2s mock, real uses
libcamera-still) - SD write test: write/read/delete temp file
- Clock check: report system time for drift comparison
All handlers return JSON {status, message, value} results. Registered in pi/main.py.
Frontend
Built src/hooks/use-preflight.ts — orchestration hook that:
- Resolves 6 passive checks instantly from telemetry (battery, GPS, voltage sensor, CPU temp, disk, WiFi)
- Sequences 5 active checks one at a time via rover commands
- Watches command completion via Convex subscriptions
- Handles 30s timeouts per active check
- Tracks run staleness (10 min expiry)
Refactored src/app/control-center/new-mission/page.tsx with animated checklist grouped by category (Sensors/Hardware/System), per-check status icons with transitions, summary bar, and launch gated behind all blocking checks passing.
Control Center Layout
Also in this session: removed the stats card row (Missions/Captures/Ticks Found/System Health), combined Latest Mission + Weather into a single side-by-side row, added GPS satellite quality labels to telemetry, and moved Disk Free to an inline detail.
Files Modified
convex/schema.ts— addedpreflight_runs,preflight_checkstables; extendedrover_commandsunionconvex/preflight.ts— new file: mutations, queries for preflight systemconvex/rover.ts— extendedsendCommandargs with preflight command typessrc/lib/preflight-checks.ts— new file: shared check definitions constantsrc/lib/telemetry.ts— addedgpsQuality()functionsrc/hooks/use-preflight.ts— new file: preflight orchestration hooksrc/app/control-center/new-mission/page.tsx— refactored with animated checklist UIsrc/app/control-center/page.tsx— removed stats row, combined mission+weather, GPS quality labelssrc/components/weather-widget.tsx— removedmax-w-xsconstraintpi/preflight_checks.py— new file: 5 hardware check handlerspi/main.py— registered preflight command handlers
Key Takeaways
- Convex server modules can't be imported in browser code — shared constants need to live in
src/lib/and be imported by both sides - Active check sequencing needed careful gating: React effects re-run before Convex subscriptions propagate, so local
firedActiveKeysstate prevents double-firing while waiting for the "running" status to round-trip through Convex - The Pi agent's 3-second command poll interval means active checks take ~3s minimum each even with fast mock handlers — total preflight with 5 active checks takes ~20-30s
- The existing
rover_commandsrequest/response pattern (pending → acknowledged → completed with result JSON) worked perfectly for hardware checks with no new infrastructure needed
