# Plan: qc-trace Live Dashboard

**Date:** 2026-02-06
**Branch:** `feat/dashboard`
**Parent:** `feat/traced-v2-integration`

## Goal

Build a Vite + React dashboard at `localhost:5173` that gives a real-time visual view of the traced pipeline: daemon → server → Postgres. See data flowing without scripts or curl.

## Architecture

```
┌──────────────────┐     ┌──────────────────┐     ┌────────────────┐
│  Daemon (watcher) │────▶│ Ingest Server    │────▶│ PostgreSQL     │
│  port: n/a        │     │ :7777            │     │ :5432          │
└──────────────────┘     └──────────────────┘     └───────┬────────┘
                                                          │
                    ┌─────────────────────────────────────┘
                    │
         ┌──────────▼──────────────────────────────────────┐
         │  Read API (added to :7777)                       │
         │  GET /api/stats      — aggregate counts          │
         │  GET /api/sessions   — session list              │
         │  GET /api/messages   — messages for session_id   │
         │  GET /api/feed       — latest N messages (live)  │
         └──────────┬──────────────────────────────────────┘
                    │
         ┌──────────▼──────────────────────────────────────┐
         │  Vite + React  :5173                            │
         │  - Pipeline status bar                          │
         │  - Live message feed (polls /api/feed)          │
         │  - Sessions table with drill-down               │
         │  - Token usage charts                           │
         │  - Source breakdown                             │
         └─────────────────────────────────────────────────┘
```

## Approach: Add Read Endpoints to Existing Server + Vite Frontend

### Backend Changes

Add read-only GET endpoints to the existing ingest server (:7777) with CORS.

**New file:** `qc_trace/db/reader.py` — async SQL queries
**Modified:** `qc_trace/server/handlers.py` — new GET handlers
**Modified:** `qc_trace/server/app.py` — route registration + CORS

| Endpoint | Returns |
|----------|---------|
| `GET /api/stats` | totals: sessions, messages, tokens; breakdowns by source and msg_type |
| `GET /api/sessions` | sessions with message count, latest timestamp. `?source=&limit=&offset=` |
| `GET /api/messages` | messages for a session. `?session_id=&limit=&offset=` |
| `GET /api/feed` | latest N messages across all sessions (for live ticker). `?since=&limit=` |

### Frontend: `dashboard/` at repo root

Vite + React + TypeScript + Tailwind + recharts

```
dashboard/
├── index.html
├── package.json
├── vite.config.ts
├── src/
│   ├── main.tsx
│   ├── App.tsx
│   ├── api.ts              — fetch helpers, polling hook
│   ├── components/
│   │   ├── Layout.tsx       — sidebar nav + header
│   │   ├── PipelineStatus.tsx
│   │   ├── StatsCards.tsx
│   │   ├── LiveFeed.tsx     — polls /api/feed every 2s
│   │   ├── SessionsTable.tsx
│   │   ├── MessageList.tsx
│   │   └── TokenChart.tsx
│   └── pages/
│       ├── Overview.tsx
│       ├── Sessions.tsx
│       └── SessionDetail.tsx
```

## Implementation Steps

1. Add `qc_trace/db/reader.py` with query functions
2. Add read endpoints + CORS to server
3. Scaffold Vite project with React + Tailwind + recharts
4. Build Overview page (status + stats + live feed)
5. Build Sessions page (table + source filter)
6. Build Session Detail page (message list)
7. Add token charts

## How to Test

```bash
# Terminal 1: Postgres
docker-compose up -d

# Terminal 2: Server (now serves both ingest + read API)
python -m qc_trace.server.app

# Terminal 3: Vite dev server
cd dashboard && npm run dev

# Terminal 4: Daemon
python -m qc_trace.cli.traced start

# Open http://localhost:5173 — watch data flow in real time
```

Quick test without daemon:
```bash
curl -X POST http://localhost:7777/ingest \
  -H 'Content-Type: application/json' \
  -d '[{"id":"test-1","session_id":"s1","source":"claude_code","msg_type":"user","timestamp":"2026-02-06T00:00:00Z","content":"hello world","source_schema_version":1}]'
```
