Skip to content

fix(jellyfin): include partial watchers in sw_watchers (#2559)#2646

Merged
enoch85 merged 5 commits into
developmentfrom
fix/jellyfin-sw-watchers-partial
Apr 10, 2026
Merged

fix(jellyfin): include partial watchers in sw_watchers (#2559)#2646
enoch85 merged 5 commits into
developmentfrom
fix/jellyfin-sw-watchers-partial

Conversation

@enoch85

@enoch85 enoch85 commented Apr 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

Closes #2559. Jellyfin sw_watchers was reading show-level watch history, but Jellyfin only marks a series as played when every episode is complete, so partial watchers were excluded.

This change:

  • uses per-user Episode descendant queries for show and season sw_watchers
  • keeps episode sw_watchers on direct item watch history
  • applies isCompletedWatch client-side so PlayedPercentage is still honored
  • excludes virtual episodes, matching fix(jellyfin): exclude virtual episodes from child queries #2624
  • simplifies the per-user batching helper without changing isWatched, viewCount, or other watch-history getters

Test plan

  • yarn workspace @maintainerr/server test --runTestsByPath src/modules/rules/getter/jellyfin-getter.service.spec.ts src/modules/api/media-server/jellyfin/jellyfin-adapter.service.spec.ts

enoch85 added 3 commits April 9, 2026 20:43
Jellyfin's series-level Played flag is an all-or-nothing aggregate,
so querying watch history at the show level only matched users who
finished every episode — making sw_watchers behaviourally identical
to sw_allEpisodesSeenBy.

Adds getDescendantEpisodeWatchers on the Jellyfin adapter, which
issues one getItems call per user (batched) scoped to Episode
descendants and applies isCompletedWatch client-side so the
configured PlayedPercentage threshold is honoured. This collapses
the naive fan-out from O(episodes × users) to O(users) per show.
Extract mapUsersBatched as the single per-user fan-out primitive.
getAllUserItemData (introduced in #2488 to centralise watch history /
favorited-by / play-count aggregation) and the new
getDescendantEpisodeWatchers now both route through it, removing the
duplicated batching loop from the previous commit.
@enoch85 enoch85 added this to the 3.6.0 milestone Apr 10, 2026
@enoch85 enoch85 merged commit a8f386a into development Apr 10, 2026
12 checks passed
@enoch85 enoch85 deleted the fix/jellyfin-sw-watchers-partial branch April 10, 2026 17:40
maintainerr-automation Bot added a commit that referenced this pull request Apr 10, 2026
* build(deps-dev): bump knip from 6.1.1 to 6.3.1 (#2650)

Bumps [knip](https://github.com/webpro-nl/knip/tree/HEAD/packages/knip) from 6.1.1 to 6.3.1.
- [Release notes](https://github.com/webpro-nl/knip/releases)
- [Commits](https://github.com/webpro-nl/knip/commits/knip@6.3.1/packages/knip)

---
updated-dependencies:
- dependency-name: knip
  dependency-version: 6.3.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps): bump @tanstack/react-query from 5.96.2 to 5.97.0 (#2652)

Bumps [@tanstack/react-query](https://github.com/TanStack/query/tree/HEAD/packages/react-query) from 5.96.2 to 5.97.0.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/react-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/react-query@5.97.0/packages/react-query)

---
updated-dependencies:
- dependency-name: "@tanstack/react-query"
  dependency-version: 5.97.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* build(deps-dev): bump @tanstack/eslint-plugin-query (#2651)

Bumps [@tanstack/eslint-plugin-query](https://github.com/TanStack/query/tree/HEAD/packages/eslint-plugin-query) from 5.96.2 to 5.97.0.
- [Release notes](https://github.com/TanStack/query/releases)
- [Changelog](https://github.com/TanStack/query/blob/main/packages/eslint-plugin-query/CHANGELOG.md)
- [Commits](https://github.com/TanStack/query/commits/@tanstack/eslint-plugin-query@5.97.0/packages/eslint-plugin-query)

---
updated-dependencies:
- dependency-name: "@tanstack/eslint-plugin-query"
  dependency-version: 5.97.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* fix: log plex native watch fallback details

* fix(metadata): resolve parent show IDs for season/episode image lookups

Seasons and episodes in media servers carry their own provider IDs which
differ from the parent show. Image endpoints were using these
season-level IDs directly against TMDB/TVDB show endpoints, causing
wrong or missing images.

Pass the media server item ID through to the metadata service. When the
item is a season or episode, follow the parent relationship to the show
and use its provider IDs for image resolution. Falls back to the
original IDs on failure.

Closes #2649

* fix(jellyfin): include partial watchers in sw_watchers (#2559) (#2646)

* fix(server): restore Sonarr episode fallback handling (#2653)

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: maintainerr-automation[bot] <261505141+maintainerr-automation[bot]@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: enoch85 <mailto@danielhansson.nu>
@maintainerr-automation

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 3.6.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Jellyfin.sw_watchers excludes partial watchers

1 participant