Add static (persistent) watch parties #27

Merged
kyuno merged 1 commit from feat/static-watch-party into master 2026-09-24 19:07:39 +02:00
Owner

Résumé

Watch party statique / permanente : on la crée depuis une série ou une playlist vidéo. Elle garde en mémoire l'avancement du groupe et celui de chaque personne. Une personne qui revient ou rejoint en cours de route voit la liste de ce qu'elle a manqué, et peut :

  • le regarder en solo,
  • lancer une watch party de rattrapage,
  • le marquer comme vu.

Le design complet est dans spec/static-watch-party.md.

Serveur

  • StaticPartyService gère les parties statiques, StaticPartyStore les persiste.
    • C'est le premier état écrit sur disque : un fichier JSON sous DATA_DIR.
    • L'écriture est atomique et debouncée, et elle est flushée sur SIGTERM.
    • Si le fichier est corrompu, il est mis de côté et le serveur démarre quand même.
  • Une séance est une Party ordinaire, liée via party.staticLink en mode group ou catchUp. Le lecteur, la sync, le flux partagé et le lobby sont réutilisés tels quels.
  • PartyService.completeCurrentItem centralise le « item terminé » : flag Played Emby + progression statique.
    • Il y a un nouvel event socket itemEnded, réservé à l'hôte, pour le dernier item de la file. Avant, ce dernier item n'était jamais marqué Played.
  • Éléments manqués = items terminés par le groupe − items vus dans l'app − items Played côté Emby.
  • Reprise : le sweep des 20 s enregistre la position. La séance suivante démarre à cette position.
  • Les séances de rattrapage solo sont masquées du lobby.
  • Docker : volume /data (docker-compose + Dockerfile + README).

Client

  • Nouvelle vue /static/:id : progression du groupe, section « Tu as manqué », membres, liste des items.
  • Bouton « Créer une watch party permanente » sur les pages série et playlist (vidéo uniquement).
  • Accueil : nouvelle section « Watch parties permanentes » avec un badge « N manqués ». Le lien ↻ sur les cartes live renvoie vers la watch party permanente.

Vérification

  • typecheck + build des deux projets. Tests serveur : 175/175, dont un nouveau staticPartyService.test.ts.
  • Parcours de bout en bout contre un faux serveur Emby local, dans le navigateur :
    • création depuis une série,
    • séance du groupe (2 épisodes),
    • un 2e utilisateur voit ses 2 manqués (et un épisode déjà Played dans Emby compte comme vu),
    • rejoindre, marquer comme vu, rattrapage solo (absent du lobby, groupe inchangé),
    • badge dans le lobby,
    • redémarrage du serveur → données conservées et reprise à la bonne position.
  • Non vérifié : la lecture vidéo réelle, faute de vrai serveur Emby.

Écarts à noter

  • Le plan prévoyait 3 PR successives. Tout est livré en une seule PR, parce que chaque étape dépendait du merge de la précédente.
  • Le code suit le style existant (indentation 2 espaces), pas « 2 tabulations » comme demandé dans CLAUDE.md. Biome n'est pas configuré dans le repo : hors scope ici.

🤖 Generated with Claude Code

## Résumé Watch party **statique / permanente** : on la crée depuis une série ou une playlist vidéo. Elle garde en mémoire l'avancement du groupe **et** celui de chaque personne. Une personne qui revient ou rejoint en cours de route voit la liste de ce qu'elle a **manqué**, et peut : - le regarder en solo, - lancer une watch party de rattrapage, - le marquer comme vu. Le design complet est dans `spec/static-watch-party.md`. ## Serveur - `StaticPartyService` gère les parties statiques, `StaticPartyStore` les persiste. - C'est le premier état écrit sur disque : un fichier JSON sous `DATA_DIR`. - L'écriture est atomique et debouncée, et elle est flushée sur SIGTERM. - Si le fichier est corrompu, il est mis de côté et le serveur démarre quand même. - Une séance est une `Party` ordinaire, liée via `party.staticLink` en mode `group` ou `catchUp`. Le lecteur, la sync, le flux partagé et le lobby sont réutilisés tels quels. - `PartyService.completeCurrentItem` centralise le « item terminé » : flag Played Emby + progression statique. - Il y a un nouvel event socket `itemEnded`, réservé à l'hôte, pour le dernier item de la file. Avant, ce dernier item n'était jamais marqué Played. - Éléments manqués = items terminés par le groupe − items vus dans l'app − items `Played` côté Emby. - Reprise : le sweep des 20 s enregistre la position. La séance suivante démarre à cette position. - Les séances de rattrapage solo sont masquées du lobby. - Docker : volume `/data` (docker-compose + Dockerfile + README). ## Client - Nouvelle vue `/static/:id` : progression du groupe, section « Tu as manqué », membres, liste des items. - Bouton « Créer une watch party permanente » sur les pages série et playlist (vidéo uniquement). - Accueil : nouvelle section « Watch parties permanentes » avec un badge « N manqués ». Le lien `↻` sur les cartes live renvoie vers la watch party permanente. ## Vérification - typecheck + build des deux projets. Tests serveur : 175/175, dont un nouveau `staticPartyService.test.ts`. - Parcours de bout en bout contre un faux serveur Emby local, dans le navigateur : - création depuis une série, - séance du groupe (2 épisodes), - un 2e utilisateur voit ses 2 manqués (et un épisode déjà Played dans Emby compte comme vu), - rejoindre, marquer comme vu, rattrapage solo (absent du lobby, groupe inchangé), - badge dans le lobby, - redémarrage du serveur → données conservées et reprise à la bonne position. - Non vérifié : la lecture vidéo réelle, faute de vrai serveur Emby. ## Écarts à noter - Le plan prévoyait 3 PR successives. Tout est livré en **une seule PR**, parce que chaque étape dépendait du merge de la précédente. - Le code suit le style existant (indentation 2 espaces), pas « 2 tabulations » comme demandé dans `CLAUDE.md`. Biome n'est pas configuré dans le repo : hors scope ici. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
kyuno added 1 commit 2026-09-24 18:55:07 +02:00
Add static (persistent) watch parties
Some checks failed
Publier l'image Docker / test (pull_request) Failing after 4s
Publier l'image Docker / publish (pull_request) Has been skipped
5182def5c9
A watch party built from a whole series or video playlist that remembers
the group's progress and each member's, so someone coming back or joining
late sees the items they missed and can catch up (solo, as a catch-up
watch party, or by marking items watched).

- StaticPartyService + StaticPartyStore: first on-disk state (JSON file
  under DATA_DIR, atomic debounced writes, flushed on SIGTERM)
- each session is an ordinary Party linked via party.staticLink; group
  position is saved by the 20s sweep and resumed on the next session
- PartyService.completeCurrentItem centralizes "item done" (Emby Played +
  static progress); new host-only "itemEnded" socket event covers the
  last queued item, which was never marked Played before
- missed = group-completed minus watched in-app minus Emby Played
- /static/:id view, create buttons on series/playlist pages, home section
- Docker volume for /data, spec/static-watch-party.md

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kyuno merged commit 2de375ac62 into master 2026-09-24 19:07:39 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: kyuno/watchparty#27
No description provided.