Dernière version de la Phase 7. Complète le module Live Streaming en ajoutant la fonctionnalité **Go Live** (démarrage de stream), actuellement bloquée par un toast "coming soon" dans la Navbar. Ajoute la **gestion de stream keys**, les endpoints **start/stop/schedule**, le **chat live connecté WebSocket**, et des **améliorations player** (vitesse de lecture, Media Session API).
---
## 2. État actuel (post-v0.702)
| Composant | État | Détail |
|-----------|------|--------|
| **LiveStream model** | ✅ Livré | `live_streams` table, GORM model avec StreamKey (json:"-") |
| **Playback speed** | ❌ Absent | Pas de contrôle 0.5x–2x |
| **Media Session API** | ❌ Absent | Pas de contrôles OS (notification area) |
---
## 3. Lots
### Lot GL1 — Go Live Backend
**Objectif** : Compléter l'API live streaming avec stream key, mise à jour, scheduling et VOD.
| # | Tâche | Fichiers impactés | Effort |
|---|-------|--------------------|--------|
| GL1-01 | Migration `117_live_streams_go_live.sql` — ajout colonnes `scheduled_at`, `stream_url`, `is_vod` ; update `stream_key` NOT NULL avec default UUID | `migrations/117_live_streams_go_live.sql` | S |
| GL1-02 | Mise à jour modèle `LiveStream` — ajout champs `ScheduledAt`, `StreamURL`, `IsVOD` | `internal/models/live_stream.go` | S |
| GL1-03 | `GenerateStreamKey` dans service — génère un UUID v4 unique pour stream_key lors du Create | `internal/services/live_stream_service.go` | S |
| GL1-04 | `GET /live/streams/me` — liste les streams de l'utilisateur authentifié (incluant stream_key) | `internal/handlers/live_stream_handler.go`, routes | M |
| GL1-05 | `GET /live/streams/me/key` — retourne la stream key de l'utilisateur (crée un stream draft si nécessaire) | `internal/handlers/live_stream_handler.go`, routes | S |
| GL1-06 | `POST /live/streams/me/key/regenerate` — régénère la stream key | `internal/handlers/live_stream_handler.go`, routes | S |
| GL1-07 | `PUT /live/streams/:id` — mise à jour titre/description/category/tags pendant ou avant le live | `internal/handlers/live_stream_handler.go`, routes | S |
| GL1-08 | `GET /live/streams?is_vod=true` — listing des streams terminés (VOD replays) | `internal/services/live_stream_service.go`, repository | S |
| GL2-02 | `GoLivePage` — wrapper avec fetch stream key, state management | `apps/web/src/features/live/pages/GoLivePage.tsx` (nouveau) | M |
| GL2-03 | Lazy export `LazyGoLive` — createLazyComponent pour GoLivePage | `apps/web/src/components/ui/lazy-component/lazyExports.ts` | S |
| GL2-04 | Route `/live/go-live` dans routeConfig — protégée auth | `apps/web/src/router/routeConfig.tsx` | S |
| GL2-05 | Navbar "Go Live" → navigate `/live/go-live` au lieu du toast | `apps/web/src/components/layout/Navbar.tsx` | S |
| GL2-06 | Service frontend `liveService` — `getMyStreams`, `getMyStreamKey`, `regenerateStreamKey`, `updateStream`, `createStream` | `apps/web/src/services/liveService.ts` (modifier) | M |
| GL2-07 | MSW handlers — mock GET /live/streams/me, GET /live/streams/me/key, POST regenerate, PUT :id | `apps/web/src/mocks/handlers-live.ts` (nouveau) | M |
| GL2-08 | Story `GoLiveView.stories.tsx` — états Default, Loading, Error, StreamKeyVisible | `apps/web/src/features/live/pages/go-live-page/GoLiveView.stories.tsx` (nouveau) | M |
### Lot GL3 — Live Chat & Interaction
**Objectif** : Connecter le chat live aux WebSocket existants pour un chat temps réel par stream.
| # | Tâche | Fichiers impactés | Effort |
|---|-------|--------------------|--------|
| GL3-01 | Chat room par stream — utiliser le système de conversation WebSocket existant (JoinConversation avec stream_id comme room) | `internal/websocket/chat/handlers.go` | M |
| GL3-02 | `LiveViewChat` connecté WebSocket — remplacer les données mock par le hook useChat existant | `apps/web/src/features/live/pages/live-page/LiveViewChat.tsx` | M |
| GL3-03 | Viewer count temps réel — écouter les events `listener_joined`/`listener_left` via WebSocket | `apps/web/src/features/live/pages/live-page/LiveViewPlayer.tsx` | S |
**Objectif** : Vitesse de lecture et intégration Media Session API pour contrôles OS.
| # | Tâche | Fichiers impactés | Effort |
|---|-------|--------------------|--------|
| GL4-01 | Playback speed control — bouton 0.5x, 0.75x, 1x, 1.25x, 1.5x, 2x dans le player | `apps/web/src/features/player/components/audio-player/` | M |
| GL4-02 | Media Session API — navigator.mediaSession avec metadata (title, artist, artwork), action handlers (play, pause, seekbackward, seekforward, previoustrack, nexttrack) | `apps/web/src/features/player/hooks/` | M |
| GL4-03 | Tests — playback speed persistence, media session metadata update | Tests | S |
### Lot QA1 — Tests & Release
| # | Tâche | Fichiers impactés | Effort |
|---|-------|--------------------|--------|
| QA1-01 | Smoke test v0.703 — checklist complète | `docs/SMOKE_TEST_V0703.md` | S |
| QA1-02 | Mise à jour PROJECT_STATE, FEATURE_STATUS, CHANGELOG | `docs/` | S |
| QA1-03 | Rétrospective v0.703, archivage scope, placeholder v0.801, tag | `docs/`, Git | S |
RespondWithAppError(c, apperrors.Wrap(apperrors.ErrCodeInternal, "Failed to create stream", err))
return
}
streamKey = created.StreamKey
}
RespondSuccess(c, http.StatusOK, gin.H{
"stream_key": streamKey,
"rtmp_url": "rtmp://stream.veza.app/live",
})
}
```
### 5.5 VOD — Streams terminés
Quand `SetIsLive(false)` est appelé (stream_ended event), le stream reste en DB avec `ended_at` set. On ajoute un filtre `is_vod` qui retourne les streams avec `ended_at IS NOT NULL AND is_live = false`.
### 5.6 Scheduled Streams
Le champ `scheduled_at` permet de planifier un stream futur. L'endpoint `POST /live/streams` accepte `scheduled_at` dans le body. Le frontend affiche les streams planifiés avec un badge "Scheduled" et un countdown.