Skip to main content

## Module series_progress

Source
Expand description

Where a viewer is in a TV series.

This is domain policy, not presentation: it encodes what Jellyfin’s user-data means (“in progress”, “played”) and what Jellyfin’s season numbering means (season 0 is specials). The frontend asks for the current episode and renders it; it does not get to decide what “current” means.

Split into a pure half (`pick_current_episode`, `sort_series_order`) and an I/O half (`fetch_series_episodes`, `resolve_current_episode`) so the policy can be unit-tested without standing up a repository.

TRACES: UR-062 | DR-101, DR-264 | UT-239

## Constants§

MAX_PROGRESS_FRACTION 🔒
  Above this fraction watched, an episode is effectively finished; resuming it would drop the viewer into the closing credits.
MIN_PROGRESS_FRACTION 🔒
  Below this fraction watched, a position is a false start rather than progress — the same threshold the resume dialog uses.
SPECIALS_SEASON 🔒
  Jellyfin files specials under season 0.

## Functions§

belongs_to_series 🔒
fetch_series_episodes
  Every episode of a series, in series order.
is_episode 🔒
is_finished 🔒
  Has the viewer reached the end of this episode?
is_in_progress 🔒
  Is this episode genuinely part-watched (not a false start, not finished)?
is_played 🔒
is_season 🔒
list_options 🔒
pick_current_episode
  The episode a viewer should land on when they open `series_id`.
resolve_current_episode
  Resolve the current episode, fetching everything the policy needs.
season_rank 🔒
  Sort key for a season number. Specials sort after every numbered season: a viewer works through S1, S2, … and only then the extras, so season 0 must not lead just because `0 < 1`.
sort_series_order
  Order episodes as the series is watched: season ascending, then episode, specials last.