# BetterBrain Trends Dashboard — Deploy & Operation Guide

Sistema autonomo che:
1. Fetcha Google Trends US per 7 keyword medical/category daily alle 6:00
2. Salva snapshot JSON storici (2 anni di retention)
3. Espone una dashboard HTML always-on via Tailscale

## Architettura

```
Mac mini (always-on, Tailscale 100.74.154.42)
├── launchd: fetch daily 6:00     → pytrends → data/YYYY-MM-DD/snapshot.json + data/latest.json
├── launchd: HTTP server 24/7      → serve dashboard/ + data/ su porta 8765
└── Tailscale network              → accessibile da iPhone/Mac/PC del team su Tailscale

Utente apre nel browser:
  http://100.74.154.42:8765/dashboard/
  ↓
  index.html legge data/latest.json
  ↓
  Render chart + date picker + related queries + geo
```

## Deploy steps

### 1. Aggiungere dipendenze al progetto

```bash
ssh sandro@100.74.154.42
cd ~/agents
/Users/sandro/.local/bin/uv add pytrends pyyaml
```

### 2. SCP del codice dal PC

Dal PC cmd, una sola comanda recursive:

```
scp -r "C:\Users\aandr\Desktop\- CLAUDE\ABOUT ME\Symetrics\growth-hub-agenti\scaffold\projects\symetrics_trends" sandro@100.74.154.42:/Users/sandro/agents/projects/
```

Trasferisce: config, fetcher, server, dashboard (HTML+CSS+JS), 2 plist.

### 3. Primo fetch manuale (per popolare data/latest.json)

```bash
ssh sandro@100.74.154.42 "cd ~/agents && /Users/sandro/.local/bin/uv run python -m projects.symetrics_trends.betterbrain.fetch_trends"
```

Dura ~3-5 minuti per la prima volta (28 chiamate pytrends rate-limited).

Output atteso: `✓ Saved snapshot: ...` e `✓ Updated latest: ...`.

Se fallisce su rate-limit (429): rilancia dopo 10-15 min, pytrends ha cool-down naturale.

### 4. Carica launchd plist per fetch daily

```
scp "C:\Users\aandr\Desktop\- CLAUDE\ABOUT ME\Symetrics\growth-hub-agenti\scaffold\projects\symetrics_trends\betterbrain\co.symetrics.trends.betterbrain.fetch.plist" sandro@100.74.154.42:~/Library/LaunchAgents/
```

```
ssh sandro@100.74.154.42 "launchctl unload ~/Library/LaunchAgents/co.symetrics.trends.betterbrain.fetch.plist 2>/dev/null; launchctl load ~/Library/LaunchAgents/co.symetrics.trends.betterbrain.fetch.plist && launchctl list | grep trends"
```

Output atteso: `-       0   co.symetrics.trends.betterbrain.fetch`.

### 5. Carica launchd plist per HTTP server (always-on)

```
scp "C:\Users\aandr\Desktop\- CLAUDE\ABOUT ME\Symetrics\growth-hub-agenti\scaffold\projects\symetrics_trends\betterbrain\co.symetrics.trends.betterbrain.server.plist" sandro@100.74.154.42:~/Library/LaunchAgents/
```

```
ssh sandro@100.74.154.42 "mkdir -p ~/Library/Logs/agents && launchctl unload ~/Library/LaunchAgents/co.symetrics.trends.betterbrain.server.plist 2>/dev/null; launchctl load ~/Library/LaunchAgents/co.symetrics.trends.betterbrain.server.plist && launchctl list | grep trends"
```

Output atteso (2 righe): la riga fetch + una nuova riga con PID positivo (server running):
```
73214   0   co.symetrics.trends.betterbrain.server
-       0   co.symetrics.trends.betterbrain.fetch
```

### 6. Apri la dashboard

Da QUALSIASI device connesso alla rete Tailscale del team Datlab:

**http://100.74.154.42:8765/dashboard/**

Bookmarka. Apri quando vuoi. La pagina riflette sempre l'ultimo snapshot (refresh giornaliero alle 6:00).

## Operation

### Verificare che il fetch sia girato stamattina

```bash
ssh sandro@100.74.154.42 "tail -50 ~/Library/Logs/agents/trends-betterbrain.out.log"
```

### Verificare che il server stia girando

```bash
ssh sandro@100.74.154.42 "launchctl list | grep trends && tail -20 ~/Library/Logs/agents/trends-betterbrain-server.out.log"
```

### Forzare un refresh manuale (es. cambiando keyword)

```bash
ssh sandro@100.74.154.42 "launchctl kickstart -k gui/$(id -u sandro)/co.symetrics.trends.betterbrain.fetch"
```

### Cambiare keyword

Edit `config.yaml` (sul Mac), poi forza un refresh manuale. Il prossimo fetch automatico (6:00 next day) usa la nuova config.

```bash
ssh sandro@100.74.154.42 "nano ~/agents/projects/symetrics_trends/betterbrain/config.yaml"
```

### Aggiungere un nuovo cliente (es. Novos Trends)

Copia `betterbrain/` come template:

```bash
ssh sandro@100.74.154.42 "cp -r ~/agents/projects/symetrics_trends/betterbrain ~/agents/projects/symetrics_trends/novos"
```

Poi edita `config.yaml` con keyword Novos + adatta porta server (es. 8766 invece di 8765 — uno per cliente). Crea nuovo plist con label diverso. Dashboard separata su porta diversa, stesso Tailscale IP.

## Troubleshooting

| Problema | Causa probabile | Fix |
|---|---|---|
| `latest.json` not found nel browser | Server gira ma fetch non è ancora girato | Run fetch manuale (step 3) |
| pytrends `429 Too Many Requests` | Rate limit Google | Aspetta 30 min, rilancia. Se persiste, upgrade a SerpApi |
| Dashboard mostra "ERROR loading data" | Network/Tailscale issue | Verifica Tailscale connesso sul tuo device + Mac mini up |
| Chart vuoti | Keywords con 0 search volume in US | Verifica keyword in config — magari typo |
| Server riparte loop infinito | KeepAlive true + crash al boot | `launchctl list \| grep server` → se PID cambia ogni 2 sec, check err.log |

## Cost

- pytrends: gratis (rate-limited)
- Mac mini: già acceso
- Tailscale: già attivo
- **Totale: €0/mese aggiuntivi**

Se pytrends diventa fragile (rate limits frequenti, dati mancanti), upgrade a SerpApi Google Trends: ~€75/mese, API stabile. Cambia solo `fetch_trends.py` (sostituisci pytrends call con SerpApi requests).
