# Monitor SSE Proxy

Monitor locale per Hackapizza con controllo runtime agenti e relay SSE.

## Obiettivo

Il monitor centralizza la connettivita SSE:

- mantiene **una sola connessione SSE upstream** verso il server Hackapizza;
- mostra eventi upstream e log runtime nella UI;
- espone uno stream SSE locale che l'agente consuma (`SSE_URL` locale);
- permette controllo manuale del runtime (`start`, `stop`, `restart`);
- fornisce dashboard per analisi dati API e database locale.

In questo modo monitor e agente passano dallo stesso punto di controllo.

## Architettura

```text
Hackapizza SSE (upstream, 1 connessione)
            |
            v
   src/monitor/sse-proxy.py
      |            |
      |            +--> /stream  (UI monitor: eventi + log processo)
      |            |
      |            +--> /galaxy      (UI alternativa con vista galattica)
      |            +--> /dashboard   (dashboard dati API remoti)
      |            +--> /db          (dashboard database locale)
      |
      +--> /events/{TEAM_ID} (relay SSE locale per agente)
                     |
                     v
            hackapizza.main (runtime agenti)
```

## Endpoint del proxy

### Pagine UI

- `GET /`
  UI monitor principale (`sse-monitor.html`).

- `GET /galaxy`
  UI monitor alternativa con vista galattica (`galaxy-monitor.html`).

- `GET /dashboard`
  Dashboard dati API remoti (`dashboard-monitor.html`).
  - refresh **solo manuale** tramite bottone `Aggiorna ora`;
  - nessun polling automatico;
  - cache locale dell'ultimo payload (`localStorage`) caricata all'apertura pagina.

- `GET /db`
  Dashboard database locale (`db-dashboard.html`).
  Visualizza dati da `hackapizza.db`:
  - turn summary, service log, recipes;
  - market history, known intolerances;
  - intel (rankings, price benchmarks, bids);
  - strategy params e history.

### Stream SSE

- `GET /stream`
  Stream SSE per le UI monitor. Include:
  - eventi upstream (source `UPSTREAM`);
  - log processo agente (`STDOUT`/`STDERR`);
  - eventi di stato del monitor (`MONITOR`).

- `GET /events` e `GET /events/{restaurant_id}`
  Relay SSE locale per i consumer (runtime agente).
  Se il proxy e configurato con `TEAM_ID`, una richiesta con `restaurant_id` diverso ritorna `409`.

### Controllo runtime

- `POST /start`
  Avvia il runtime agente se non e gia attivo.

- `POST /stop`
  Ferma il runtime agente (terminate + kill fallback).

- `POST /restart`
  Riavvia il runtime agente.

- `GET /health`
  Stato processo e stato connessione upstream:
  - `running`
  - `pid`
  - `upstreamConfigured`
  - `upstreamRunning`

### API JSON

- `GET /api/dashboard`
  Endpoint JSON per la dashboard dati API remoti. Aggrega:
  - `/recipes`
  - `/restaurants`
  - `/market/entries`
  - `/restaurant/{TEAM_ID}` e `/restaurant/{TEAM_ID}/menu` (se `TEAM_ID` e configurato).

- `GET /api/db-dashboard`
  Endpoint JSON per la dashboard database locale. Restituisce dati da:
  - `turn_summary` (ultimi 100 turni)
  - `service_log` (ultimi 200 servizi)
  - `recipes`
  - `market_history` (ultimi 200)
  - `known_intolerances` (ultime 200)
  - `intel_rankings` (ultimi 100)
  - `intel_price_benchmarks` (ultimi 100)
  - `intel_all_bids` (ultimi 200)
  - `strategy_params`
  - `strategy_params_history` (ultimi 100)

### Asset statici

- `GET /css/{file}.css`
  Fogli di stile per le varie UI.

- `GET /svg/{filename}.svg`
  Icone SVG per le UI.

## Dashboard dati API (`/dashboard`)

La dashboard e pensata per una lettura rapida "a colpo d'occhio":

- layout compatto full viewport (`100vh`);
- KPI principali in cards (team, runtime, upstream, balance, reputation, ecc.);
- classifica completa ristoranti per balance (non solo top 10);
- colonna `Delta` con variazione posizione rispetto all'ultimo refresh;
- evidenziazione del proprio team (`TU`) nella classifica;
- tabelle principali con area scroll dedicata (header sticky).

Comportamento cache/refresh:

- all'apertura, se presente cache, mostra subito i dati salvati;
- le richieste HTTP partono solo quando l'utente clicca `Aggiorna ora`;
- dopo un refresh riuscito, il payload viene salvato in cache locale.

## Dashboard database (`/db`)

Dashboard per ispezionare il database SQLite locale (`hackapizza.db`):

- **Turn Summary**: storico turni con metriche (revenue, costs, profit, clients served/failed);
- **Service Log**: dettaglio servizi per turno e cliente;
- **Recipes**: ricette disponibili;
- **Market History**: storico acquisti al mercato;
- **Known Intolerances**: intolleranze clienti scoperte;
- **Intel Rankings**: classifiche ristoranti raccolte;
- **Intel Price Benchmarks**: benchmark prezzi;
- **Intel All Bids**: storico offerte aste;
- **Strategy Params**: parametri strategia correnti;
- **Strategy History**: storico modifiche parametri.

## Galaxy Monitor (`/galaxy`)

Vista alternativa del monitor con tema galattico. Stesse funzionalita del monitor principale (`/`) con UI differente.

## Variabili ambiente

Variabili usate dal proxy:

- `TEAM_ID`  
  Team Hackapizza (es. `14`).

- `HACKAPIZZA_API_KEY`  
  Chiave API usata per la connessione SSE upstream.

- `HACKAPIZZA_BASE_URL` (opzionale)  
  Default: `https://hackapizza.datapizza.tech`.

- `UPSTREAM_SSE_URL` (opzionale)  
  Override completo dell'endpoint upstream.  
  Se assente, usa: `{HACKAPIZZA_BASE_URL}/events/{TEAM_ID}`.

- `MONITOR_DRY_RUN` (opzionale)  
  Se `1/true/yes/on`, disattiva la connessione al server reale e genera eventi SSE simulati in locale.

Variabile iniettata nel runtime agente dal proxy:

- `SSE_URL=http://127.0.0.1:8765/events/{TEAM_ID}`  
  Il runtime quindi non apre SSE diretta verso internet.

## Uso rapido

1. Avvia il proxy monitor:

```bash
uv run python src/monitor/sse-proxy.py
```

2. Apri una delle UI disponibili:

| URL | Descrizione |
|-----|-------------|
| `http://127.0.0.1:8765` | Monitor principale |
| `http://127.0.0.1:8765/galaxy` | Monitor tema galattico |
| `http://127.0.0.1:8765/dashboard` | Dashboard dati API |
| `http://127.0.0.1:8765/db` | Dashboard database locale |

3. Dalla UI monitor (`/` o `/galaxy`):
- `Avvia runtime` per avviare gli agenti;
- `Ferma runtime` per spegnerli;
- `Riavvia runtime` per restart pulito.

Per mantenere una sola connessione SSE upstream, non avviare `hackapizza.main` separatamente mentre il proxy e' attivo: il runtime va gestito dalla UI del monitor.

## Dry run (offline)

Per provare monitor e runtime senza server remoto:

```bash
# nel file .env
# MONITOR_DRY_RUN=1
uv run python src/monitor/sse-proxy.py
```

Con questa modalita:

- il proxy non apre la SSE upstream reale;
- genera eventi simulati (`game_started`, `game_phase_changed`, `new_message`, ecc.);
- continua a esporre `/stream` e `/events/{TEAM_ID}` per UI e runtime.

## Note operative

- La connessione upstream viene avviata su startup del proxy e resta attiva con reconnessione automatica.
- Aprire la UI non avvia automaticamente il runtime agente.
- Il relay SSE locale puo essere consumato anche da strumenti esterni (debug), ma la connessione upstream resta unica.
- Runtime e monitor condividono il contratto SSE (`src/hackapizza/infra/sse_contract.py`) per parsing frame, normalizzazione payload e mappa routing.
- Flusso consigliato: avvia `src/monitor/sse-proxy.py` e gestisci gli agenti dai bottoni UI (`start/stop/restart`), senza lanciare `hackapizza.main` separatamente.

## Struttura file

```text
src/monitor/
├── sse-proxy.py              # Server principale
├── README.md
├── html/
│   ├── sse-monitor.html      # UI monitor principale
│   ├── galaxy-monitor.html   # UI monitor galattico
│   ├── dashboard-monitor.html # Dashboard API
│   └── db-dashboard.html     # Dashboard database
├── css/
│   ├── sse-monitor.css
│   ├── galaxy-monitor.css
│   ├── dashboard-monitor.css
│   ├── db-dashboard.css
│   └── monitor-theme.css     # Tema condiviso
└── svg/
    ├── chef.svg
    ├── maitre.svg
    ├── patron.svg
    ├── brigata.svg
    ├── magazzini.svg
    ├── evaluator.svg
    ├── pr.svg
    ├── sse.svg
    └── ui-icons.svg
```
