# Modulo Replay — Match Live TV

## Panoramica

Al termine di ogni diretta Premium, MediaMTX registra i segmenti. Sidekiq unisce i segmenti, genera thumbnail, carica su **Garage (S3-compatible)** e attiva i servizi di notifica, statistiche e (opzionale) republicazione YouTube.

## Piani e retention

| Piano | Registrazione | Retention | Download MP4 | YouTube VOD |
|-------|---------------|-----------|--------------|-------------|
| Free | No | — | No | No |
| Premium Light | Sì | 30 giorni | Sì | No |
| Premium Full | Sì | 90 giorni | Sì | Sì (auto se diretta YouTube) |

## Funzionalità implementate

### 1. Registrazione automatica
Pipeline: `Sessions::Stop` → `FinalizeSession` → `UploadJob` → storage.

### 2. Retention e purge
`Recordings::PurgeExpiredJob` / `rails recordings:purge_expired`

### 3. Archivio Replay
- Web: `/clubs/:id/replays` (gestione società)
- Pubblico: `/replay` con filtro società/squadra
- App: schermata Replay

### 4. Riproduzione
- Player MP4: `/replay/:id` + stream `/replay/:id/stream`
- Contatore visualizzazioni su ogni play (`view_count`)

### 5. Visibilità
Pubblico / Privato (unlisted), modificabile dall’admin società.

### 6. Eliminazione anticipata
`Recordings::Delete` — DB + video + thumbnail su storage.

### 7. Dashboard KPI
Replay disponibili, in scadenza (7 gg), spazio occupato, **visualizzazioni totali**.

### 8. Miglioramenti Premium

| Feature | Descrizione |
|---------|-------------|
| **Email replay pronto** | A owner e membri società quando status → `ready` |
| **Email scadenza** | 7 giorni prima di `expires_at` (`rails recordings:expiry_warnings`) |
| **Thumbnail** | Frame ffmpeg, URL `/replay/:id/thumbnail` |
| **Download MP4** | Premium, link presigned 15 min o `/replay/:id/download` |
| **Statistiche views** | `view_count` su ogni replay |
| **metadata JSONB** | `source_platform`, `auto_publish_youtube`, `ai: {}` per estensioni |
| **YouTube VOD** | Premium Full: upload automatico se diretta era su YouTube; manuale da archivio |

## Storage

```env
REPLAY_STORAGE_ENDPOINT=http://garage:3900
REPLAY_STORAGE_BUCKET=matchlivetv-replays
REPLAY_STORAGE_ACCESS_KEY_ID=...
REPLAY_STORAGE_SECRET_ACCESS_KEY=...
REPLAY_DOWNLOAD_URL_TTL_SECONDS=900
```

Senza endpoint S3: storage locale `/recordings/replays/`.

### Dev locale con Garage

```bash
cd infra
docker compose up -d          # include garage
bash scripts/setup_garage_replays.sh   # layout, bucket, chiave → .env
docker compose up -d rails sidekiq

# Verifica pipeline (segmento finto → Garage)
docker compose exec -T rails bundle exec rails replay:e2e_garage
```

**Credenziali in `.env`:** non compilarle a mano in `.env.example`. Lo script scrive in `infra/.env`:
- `REPLAY_STORAGE_ACCESS_KEY_ID` = Key ID Garage (es. `GK...`)
- `REPLAY_STORAGE_SECRET_ACCESS_KEY` = Secret mostrato una sola volta alla creazione chiave

## Cron consigliati (produzione)

```cron
0 3 * * *  cd /opt/matchlivetv/infra && docker compose exec -T rails bundle exec rails recordings:purge_expired
0 8 * * *  cd /opt/matchlivetv/infra && docker compose exec -T rails bundle exec rails recordings:expiry_warnings
```

## API mobile

- `GET /teams/:id/recordings` — lista con thumbnail, views, download_enabled
- `GET /recordings/:id/download` — URL download temporaneo
- `POST /recordings/:id/publish_youtube` — coda republicazione YouTube

## Estensioni future (metadata.ai)

Campo `metadata["ai"]` predisposto per:
- highlight automatici
- trascrizioni
- articoli generati
- clip / Shorts

Esempio aggiornamento via API:
```json
{ "recording": { "metadata": { "ai": { "transcript_status": "queued" } } } } }
```
