Finalize Jellyfin hardening for collections, search, and setup#2534
Closed
enoch85 wants to merge 34 commits into
Closed
Finalize Jellyfin hardening for collections, search, and setup#2534enoch85 wants to merge 34 commits into
enoch85 wants to merge 34 commits into
Conversation
PR #2396 - feat(settings): unify connection-test error handling across services - Added shared backend/frontend error helpers for connection tests - Reduced connection test timeout to 3s and parallelized tests - Normalized user-facing error messages across all service test endpoints PR #2429 - fix: emit collection notification events only after successful operations - Moved event emissions to after operations complete - Only emits events for items that were truly added/removed - Pass touchedMediaServerIds to prevent incorrect removals during sync PR #2436 - fix(server): resolve Seerr addUser returning NULL - Use username fields directly from Seerr API response instead of media server ID lookup - Use workspace-local typeorm migration cli - Use initial setup terminology for media server success log - Added 11 unit tests for addUser covering all user types and edge cases
PR #2438 - feat(rules): add rule Jellyfin favorited by including parents - Added Jellyfin favorited rule that checks parent items (series/seasons) - Includes unit tests for the new favorited-by-parents getter PR #2439 - fix: stop rule execution when rule group is deleted mid-run - Changed onRuleGroupDeleted to call stopProcessingRuleGroup instead of removeFromQueue - Fires abort signal for in-flight execution, preventing null reference crashes - Added unit test for delete-during-execution scenario PR #2442 - fix(server): reject null/undefined in numeric rule comparisons - Fixed null guard using proper nullish check (`firstVal != null`) - Preserves v2.27.0 null→0 coercion for BIGGER/SMALLER to avoid upgrade breakage - Logs warning when non-number values are encountered in numeric comparisons - Updated regression tests for numeric comparisons including null/undefined cases
Adds a secondary ORDER BY on `id` to prevent duplicate and missing items when paginating collection media. Items sharing the same `addDate` could appear on multiple pages or be skipped entirely due to SQLite's non-deterministic row ordering for equal sort values. Closes #2443
PR #2445 - fix: prevent false watchlist evaluation when plex.tv is unreachable - Guard PlexTvApi.getUsers() and getUser() against undefined responses from timed-out plex.tv requests - Detect missing UUIDs in getCorrectedUsers() and return null from watchlist getters - Rule comparator treats null as "unable to determine" and skips the comparison, preventing false deletions
PR #2444 - fix(ui): use ref-based guards in CollectionMediaPage to prevent duplicate fetches - Replace state-based fetch guards with refs to avoid React batching issues - Prevent duplicate API calls during pagination and collection media loading
PR #2444 - fix(ui): add fetchingRef guard in Overview to prevent concurrent page fetches - Add ref-based guard to Overview component to prevent concurrent page fetches - Mirrors the same pattern applied to CollectionMediaPage in previous commit
…, #2442, #2406, #2386, #2370 PR #2466 - fix: honor Jellyfin played threshold - Respect configured played percentage threshold for Jellyfin watch status PR #2461 - feat(rules): add ARR disk target path selection for disk space rules - Allow selecting specific disk target paths for Radarr/Sonarr disk space rules PR #2458 - feat: clean up empty ended shows in Sonarr after season actions - Automatically remove ended shows from Sonarr when all seasons are processed PR #2453 - fix: improve Plex viewCount reliability and add isWatched boolean - Use native Plex viewCount field with watch history fallback - Add new isWatched boolean rule property PR #2452 - build(deps): bump actions/download-artifact from 7 to 8 PR #2451 - build(deps): bump actions/upload-artifact from 6 to 7 PR #2442 - fix(server): reject null/undefined in numeric rule comparisons - Add getComparisonResult wrapper that fails closed on null/undefined operands - Strict type checking for BIGGER/SMALLER comparisons PR #2406 - Metadata provider abstraction layer with TVDB support - Add MetadataService as central metadata resolution layer - TVDB support as alternative metadata provider - Dynamic provider preference with fallback - Replace TmdbIdService with unified MetadataService PR #2386 - feat: missing_episode rules - Add missing episode count as a rule property for Sonarr PR #2370 - build(deps-dev): bump the eslint group with 2 updates
PR #2442 - fix(server): reject null/undefined in numeric rule comparisons - Treat missing last-view dates as stale - Raise missing-operand rule logs to warn - Normalize Plex provider rating slots
(cherry picked from commit 634e897)
…-closed (cherry picked from commit eeacbf9)
- Improve missing operand logging with watch state context - Add isWatchDateRule helper to constants service
This reverts commit 7d850d8.
# Conflicts: # apps/server/package.json # apps/ui/package.json # yarn.lock
PR #2453 - fix: improve Plex viewCount reliability and add isWatched boolean - Use native Plex viewCount field with watch history fallback - Add new isWatched boolean rule property - Share watched rule behavior across media servers - Use uncached Plex history for watched rules - Share Plex test fixtures
# Conflicts: # apps/server/package.json
PR #2488 - fix(server): improve Jellyfin watch data aggregation - Improve watch history aggregation with per-user UserData lookups - Honor Jellyfin played threshold (MaxResumePct) for watch status - Add getItemFavoritedBy and getTotalPlayCount methods - Address review feedback with debug logging and fallback handling
PR #2458 - feat: clean up empty Sonarr shows after season actions - Move ServarrAction enum to @maintainerr/contracts for shared use - Add SeerrApiService.hasRemainingSeasonRequests() for continuing show cleanup - Update deleteShowIfEmpty to handle continuing shows via Seerr state check - Exclude DELETE_SHOW_IF_EMPTY from Seerr request mutation in collection handler - Use ServarrAction enum constants in UI AddModal instead of magic numbers - Update force Seerr helper text to describe season-specific behavior - Add SeerrApiModule to ActionsModule for DI - Add comprehensive tests for all new Seerr-aware cleanup scenarios
PR #2492 - Fix Sonarr episode handling when media indexes are missing - Safely identify episodes via getEpisodeLookup (index or air date fallback) - Return boolean from action handlers to detect servarr update failures - Add airDate-based episode matching in Sonarr helper
PR #2461 - feat(rules): add ARR disk target path selection for disk space rules - Add Disk Target dropdown for Radarr/Sonarr disk space rules - Support Aggregate (default) or specific Arr-reported path - Fix Sonarr disk target (NFS/CIFS mounts not in /diskspace API) - Merge /rootfolder data into diskspace results for remaining-space rules - Move ArrDiskspaceResource + normalizeDiskPath to @maintainerr/contracts - Extract evaluateArrDiskspaceGiB() to eliminate copy-paste between getters - Add diskspace tests for both getter services
PR #2510 - fix: prevent crash when removing media from null Jellyfin collection - Guard removeFromCollection API call when mediaServerId is null - Move DB cleanup outside inner try block so items are always cleaned up - Update parameter type to string | null for type accuracy
PR #2511 - fix: resolve Jellyfin collection creation failure - Remove unnecessary re-fetch after creating a Jellyfin collection - Switch getCollection to use direct getUserLibraryApi().getItem() lookup instead of query-based getItemsApi().getItems() pipeline - Construct MediaCollection from known creation response data instead of re-querying
# Conflicts: # yarn.lock
PR #2488 - fix(server): revert Jellyfin getItemUserData to use getItems endpoint - Revert per-user data fetching from dedicated /UserItems/{itemId}/UserData endpoint back to getItems with enableUserData=true - The dedicated endpoint does not reliably return per-user data with API key auth on all Jellyfin versions - Fixes viewCount=0 and lastViewedAt=null regression reported in #2509 - Update test mocks to match reverted getItems call signature
PR #2453 - fix(server): fall back to native Plex viewCount for isWatched - Use native Plex viewCount as fallback for isWatched boolean when watch history is empty - Covers items marked watched without play events and purged history - Numeric viewCount still uses history only to preserve server-wide accuracy
PR #2494 - fix: added batch collection adding of media for Jellyfin - Batch collection add/remove using Jellyfin's native multi-id API support - New COLLECTION_CREATION_WITH_ITEMS feature flag to skip redundant resync - Batch methods return failed IDs so the service layer only persists DB rows for items that actually landed on the server - Create-with-items wired into createCollection: Jellyfin gets items at creation time, Plex and manual collections fall back to the sequential add path - Plex sequential fallback with per-item error handling and 404 tolerance on remove
PR #2511 - fix: resolve Jellyfin collection creation failure - avoid revalidating freshly reconciled collection links in the same rule run - preserve stale-link healing for normal collection add/remove paths - add focused rule executor coverage for Jellyfin resync and removal flows
Collaborator
Author
|
Can only be merged after the metadata PR. |
Collaborator
Author
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
This branch started as a fix for a few Jellyfin stability issues, then was extended to close the still-valid gaps that remained after the Jellyfin merge into 3.0.
What this PR fixes
media_server_typeinitialize()instead of returning a broken adapterWhy this is better
This makes Jellyfin behavior more predictable in the places that matter most:
Validation
This PR targets
jellyfin-devand is intended to be the final Jellyfin hardening pass for the remaining verified issues in that branch line.