# Milestone 4: Multi-User Routing (The Switchboard)
**Goal:** Support multiple users in rooms with stable, synchronized audio.

### 1. Server State & Broadcast (`server_node/udp_relay.rs`)
- [ ] **Data Structure:** Expand the `DashMap` to track `ChannelId -> Vec<SessionToken>`.
- [ ] **Routing Loop:** When a UDP packet arrives, look up the sender's `ChannelId`. Iterate through all other `SessionToken`s in that channel, grab their `SocketAddr`, and use `UdpSocket::send_to` to forward the exact bytes. (Zero-copy payload routing).
- [ ] **Whisper Lists (Direct UDP):** Modify the UDP header to include a `Target_SessionToken`. If this value is `!= 0`, bypass the channel iteration and forward the packet strictly to that target's `SocketAddr`.

### 2. Client Jitter Buffer (`client_node/network/jitter.rs`)
- [ ] **Data Structure:** Create a `std::collections::BinaryHeap` wrapped in a Mutex, ordered by the packet's `SequenceNumber`.
- [ ] **Buffering Logic:** When packets arrive from the UDP socket, push them into the heap. Do NOT start popping until the heap contains at least 2 packets (40ms "Watermark").
- [ ] **Tick Loop:** Every 20ms, the audio playback thread pops the next expected `SequenceNumber`.

### 3. Packet Loss Concealment (PLC) & Playback
- [ ] **Missed Sequences:** If the `SequenceNumber` popped from the Jitter Buffer is missing (skipped a number), call `decoder.decode_float()` but pass `None` or a null buffer to the Opus library. This triggers internal PLC synthesis.
- [ ] **Late Packets:** If a packet arrives with a `SequenceNumber` older than what has already been played, immediately drop it.

### 4. TCP Chat & Presence Sync
- [ ] **Broadcast Events:** When a user joins or leaves a channel, the server broadcasts a `TcpEvent::UserJoined` or `UserLeft` to all users in that channel.
- [ ] **Chat Routing:** Client sends `TcpEvent::ChatMessage`. Server broadcasts it to the relevant channel.
- [ ] **UI Updates:** The client parses these TCP events to update the `egui` Tree View and append messages to the Chat Log in real-time.

### 5. Diagnostics Overlay
- [ ] **Debug UI:** Implement a developer panel (toggled via `F3` or a button) in `egui`.
- [ ] **Metrics:** Hook into the Jitter Buffer length, calculate packet loss % over the last 10 seconds, and ping the server via TCP to display live network health on the UI.