# Project Codex Development Roadmap ## Phase 1: Core Stability & Reliability (Immediate) Focus: Fixing the "flaky" node connections and ensuring data reliability. - [ ] Refactor Node MQTT Logic (node_main.py) - [ ] Move initial API check-in out of on_connect blocking callback. - [ ] Implement mqtt_lifecycle_manager with a 30s heartbeat loop. - [ ] Add explicit "Clean Shutdown" signal to the finally block to trigger immediate offline status. - [ ] Verify LWT (Last Will and Testament) triggers only on ungraceful crashes. - [ ] Update C2 Brain Logic (c2_main.py) - [ ] Update handle_message to refresh last_seen timestamp on any message type. - [ ] Add logic to mark a node as "Unknown/Stale" if last_seen > 90 seconds. - [ ] Standardize Node Configuration - [ ] Add location object (lat, lng, description) to the node's local config.json. - [ ] Ensure config.json is sent during the initial MQTT Check-in so the C2 knows where the node is geographically. ## Phase 2: The Metadata Pipeline ("The Sidecar") Focus: Getting real-time talkgroup data out of OP25 and into the cloud. - [ ] Create Metadata Sidecar (Edge Node) - [ ] Update node_main.py to spawn a subprocess that tails OP25's UDP metadata port or log file. - [ ] Parse lines for: Frequency, Talkgroup ID, Alpha Tag, Signal Strength. - [ ] Publish payload to topic: nodes/{NODE_ID}/metadata. - [ ] C2 Metadata Ingestion - [ ] Subscribe C2 to nodes/+/metadata. - [ ] Write received metadata to a Firestore Subcollection: nodes/{node_id}/history (for historical playback/logs). - [ ] Update the current_call field on the main node document (for "Now Playing" UI). ## Phase 3: The Web Command Center (Frontend) Focus: The User Interface for management and monitoring. Setup - [ ] Initialize Next.js 14+ (App Router) project with Tailwind CSS. - [ ] Configure Firebase Client SDK (Auth + Firestore). ### Page: Fleet Dashboard (/app/dashboard/page.tsx) - [ ] Component: NodeList: Real-time cards for physical radio nodes (Online/Offline status). - [ ] Component: SystemLoader: Control panel to push configs to nodes. ### Page: The Live Map (/app/map/page.tsx) This is the primary intelligence view. - [ ] Data Source: Subscribe to incidents collection (not just nodes). - [ ] Layer: Incidents - [ ] Icons: Dynamic markers based on type (Fire, Police, EMS, Hazard). - [ ] Status Indication: Pulse animation for "Active"; Static/Dimmed for "Cleared". - [ ] Filter Controls: "Rolling Window" slider (Active Only <-> Active + Past 30 mins <-> Past 24 hours). - [ ] Interaction: - [ ] Click Icon -> Preview Popup (Type, 1-line summary, active units). - [ ] Click "More Info" -> Navigates to Incident Detail Page. ### Page: Incident Detail (/app/incidents/[id]/page.tsx) - [ ] Component: IncidentHeader: Status (Active/Cleared), Duration, Incident Type. - [ ] Component: LiveSummary: Streaming text summary of the event so far (generated by LLM). - [ ] Component: UnitTracker: List of units currently detected on scene. - [ ] Component: TranscriptFeed: - [ ] Filtered list of audio/text clips specifically tagged to this incident_id. - [ ] Support multi-system interleaving (e.g., PD and FD audio mixed chronologically). - [ ] Component: LocationHistory: Mini-map showing the incident location (and breadcrumbs if it was mobile/chase). ## Phase 4: Audio & Discord Distribution - [ ] Persistent Command Bot (Text Interface) - [ ] Create Python bot using discord.py (always online). - [ ] Implement C2 Listener: Subscribes to MQTT discord/commands. - [ ] Feature: !status -> Queries C2 API for active nodes. - [ ] Feature: !join {node_id} -> Spawns/Commands a Voice Bot to join. - [ ] Voice Streamer Bots (Audio Retransmission) - [ ] Create lightweight bot instances specifically for audio piping. - [ ] Logic: Join voice channel requested by Command Bot. - [ ] Audio: Connect to icecast://central-server/{node_id} using FFmpeg/Opus. - [ ] Presence: Update "Playing" status with current Icecast metadata (Talkgroup/Alpha Tag). ## Phase 5: The Intelligence Engine (Backend) Focus: Transcribing, Classifying, and Aggregating. - [ ] Intelligence Service (radio-intelligence-engine) - [ ] Module: Transcriber: Whisper STT on "Call End". - [ ] Module: Analyzer (LLM): - [ ] Extract Incident Type, Location, Units Involved. - [ ] Generate 1-sentence summary of the transmission. - [ ] Module: Incident Aggregator (The "Global Brain"): - [ ] Input: New transcript + Location + Time. - [ ] Logic: Query active incidents within X miles and Y minutes. - [ ] Decision: - Match Found: Append transcript to existing incident_id, update summary, update units, extend "Last Updated" time. - No Match: Create new Incident document in Firestore. - [ ] Cross-System Merge: Allow merging transcripts from Node A (Police) and Node B (Fire) into the same Incident if location/context matches.