# Bug Fixes: Device Status, Traffic, Firewall, UI Features

## TL;DR
> Fix 5 bugs: device status stuck online, traffic monitoring empty, firewall broken for non-/24, linked devices redundant, connection status missing chart.

**Deliverables**:
- Fix transfer bytes fallback preventing offline transition
- Fix traffic monitoring data flow (agent → server → DB)
- Fix firewall for comma-separated AllowedIPs
- Improve linked devices section
- Add chart to connection status

**Estimated Effort**: Medium
**Parallel Execution**: YES - 3 waves

---

## Context

### Bugs Reported
1. **Device status stuck online**: When WireGuard deactivated, status stays "Online" forever
2. **Traffic monitoring empty**: 0 records in device_traffic table despite connected devices
3. **Firewall broken for non-/24**: Cannot ping through firewall when AllowedIPs is not /24
4. **Linked devices**: "Perangkat Tertaut" only shows current device, not linked peers
5. **Connection status**: No chart, just text debug panel

### Root Causes Found

#### Bug 1: Transfer bytes fallback (redis.go:103-108)
```go
if rx, exists := transferBytes[device.PublicKey]; exists && rx > 0 {
    isActiveFromWG = true  // CUMULATIVE bytes — never goes back to 0
}
```
`GetPeerTransfer()` returns cumulative `ReceiveBytes` from kernel. Once > 0, always true. Device never goes offline.

**Secondary**: Agent heartbeat UUID mismatch — sends HWID (SHA-256) instead of database UUID, so Redis pings always fail.

#### Bug 2: Traffic monitoring
- `POST /api/v1/traffic/report` endpoint exists and works
- But nobody calls it — device-agent doesn't report traffic
- `HandshakeCollector` in handshakesync.go is DEAD CODE (never started in main.go)
- Kernel sync records handshake but NOT traffic bytes

#### Bug 3: Firewall non-/24
- `AddForwardRule` directly interpolates CIDR into nftables command
- Single CIDR (e.g., `10.0.0.0/16`) works fine in nftables
- **Comma-separated CIDRs** (e.g., `10.0.0.0/8, 192.168.0.0/16`) produce INVALID nftables syntax
- Startup recovery uses `FirewallRule.DestIPRange` instead of `Device.EndpointAllowedIPs`

#### Bug 4: Linked devices
- "Perangkat Tertaut" only shows current device's own info
- Redundant with device info card above
- Should show peer relationships or connected devices

#### Bug 5: Connection status
- No chart — just text debug panel
- SSE stream has `rx_rate`/`tx_rate` data but unused by frontend

---

## Work Objectives

### Must Have
- Fix transfer bytes fallback (remove or add time window)
- Fix startup recovery to use `Device.EndpointAllowedIPs`
- Fix `AddForwardRule` for comma-separated CIDRs
- Start `HandshakeCollector` or integrate traffic recording into `SyncToDB`

### Must NOT Have
- Do NOT change Docker behavior
- Do NOT break existing firewall rules
- Do NOT change API endpoints

---

## Execution Strategy

### Wave 1: Backend fixes (parallel)
- T1: Fix transfer bytes fallback in redis.go
- T2: Fix startup recovery in main.go
- T3: Fix AddForwardRule for multiple CIDRs

### Wave 2: Traffic recording
- T4: Integrate traffic recording into SyncToDB or start HandshakeCollector

### Wave 3: Frontend improvements
- T5: Improve linked devices section
- T6: Add chart to connection status (optional)

---

## TODOs

- [x] 1. Fix transfer bytes fallback in redis.go
- [x] 2. Fix startup recovery in main.go (use Device.EndpointAllowedIPs)
- [x] 3. Fix AddForwardRule for comma-separated CIDRs
- [x] 4. Integrate traffic recording into SyncToDB
- [x] 5. Improve linked devices section
- [x] 6. Add chart to connection status (optional)

---

## Final Verification

- [x] F1: `go build -tags dev ./...` passes
- [x] F2: `npm run build` passes
- [x] F3: Device goes offline when WG deactivated
- [x] F4: Traffic data recorded in device_traffic table
- [x] F5: Firewall works with non-/24 AllowedIPs

---

## Success Criteria

```bash
go build -tags dev ./...  # Expected: no errors
cd apps/dashboard-ui && npm run build  # Expected: no errors
```
