- new "Parties permanentes" tab (/static, sidebar + mobile sheet),
highlighted on a party's own page too; the home page no longer lists
static parties, and its live "Watch parties en cours" list leaves
their sessions out
- StaticPartyStore now writes data/static-parties/<id>.json - one file
per party, debounced per party, so a write only touches the party that
changed and a corrupt file only costs that party (moved aside to
.corrupt, the rest still load); leftover .tmp files are cleaned up;
deleting a party removes its file and cancels any pending save
- the first release's single static-parties.json is migrated once on
load, then kept as .migrated
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>