Add support for Jellyfin#24
Closed
benscobie wants to merge 203 commits into
Closed
Conversation
- Create jellyfin development branch for Maintainerr 3.0 - Add GitHub Action to sync jellyfin branch with main daily - On conflict, creates PR for manual resolution (preserves both sides) - Include implementation plan documentation
- Phase A: Foundation (abstraction layer, database schema, MediaServerModule) - Phase B: Jellyfin Service (SDK integration, API methods) - Phase C: Rules Engine (JellyfinGetterService, add jellyfin as application) - Phase D: Collections (service updates, graceful handling) - Phase E: UI Integration (settings, media server selector) - Phase F: Testing & Documentation Updated per maintainer feedback: - Add jellyfin as application in RuleConstants (not availability flags) - No migration path support (users start fresh to switch servers) - Removed UI noise/warnings about feature limitations
Phase A establishes the abstraction layer for multi-media-server support: Contracts Package (@maintainerr/contracts): - Add EMediaServerType enum (plex, jellyfin) - Add EMediaDataType enum (movies, shows, seasons, episodes) - Add EMediaServerFeature enum for feature detection - Add MediaItem, MediaLibrary, MediaUser, WatchRecord types - Add MediaCollection, MediaServerStatus types - Export all from media-server package Database Migration: - Add media_server_type column (default: 'plex') - Add jellyfin_url, jellyfin_api_key columns - Add jellyfin_user_id, jellyfin_server_name columns MediaServer Module: - IMediaServerService interface (~25 methods) - MediaServerFactory for runtime service selection - MEDIA_SERVER_FEATURES constant for feature support matrix - MediaServerModule NestJS module Plex Adapter: - PlexAdapterService implementing IMediaServerService - Wraps existing PlexApiService for compatibility - PlexMapper for type conversions with full test coverage Tests: - 35 unit tests for PlexMapper covering all mapping functions - All 269 existing tests continue to pass Ref: jellyfin-dev-documents/PHASE_A_FOUNDATION.md
…nsibility docs
Media Server Switch (Halfway House Solution):
- Add SwitchMediaServerRequestDto, SwitchMediaServerResponseDto, MediaServerSwitchPreviewDto
- Implement switchMediaServer() method in SettingsService
- Implement previewMediaServerSwitch() to show what will be cleared/kept
- Add endpoints: GET /api/settings/media-server/switch/preview/:targetServerType
POST /api/settings/media-server/switch
When switching servers:
- CLEARS: collections, collection_media, exclusions, collection_logs, old server credentials
- KEEPS: general settings, radarr/sonarr settings, overseerr/jellyseerr, tautulli, notifications
Documentation Updates:
- Add future extensibility notes for multi-server support (per-rule server selection)
- Document media server switch API in PHASE_A_FOUNDATION.md
- Add notes to PHASE_C and PHASE_D about future per-rule server support
- Update main IMPLEMENTATION_PLAN.md with switch functionality details
Ref: Discord discussion with Scoob about migration approach
Implements JellyfinService with full API coverage using @jellyfin/sdk. - Add @jellyfin/sdk dependency (v0.13.0) - Create JellyfinService implementing IMediaServerService - Create JellyfinMapper for SDK to Maintainerr type conversion - Add constants, types, and module files - Update MediaServerModule and MediaServerFactory for Jellyfin - Add jellyfin cache to cacheManager - Add unit tests for mapper and service - Add dev-setup.sh script for development environment API methods: initialize, getStatus, getUsers, getLibraries, getLibraryContents, getMetadata, searchContent, getWatchHistory, getCollections, createCollection, deleteCollection, playlists, etc.
- Add @jellyfin/sdk to Jest transform patterns for ESM compatibility - Update transform pattern to handle both .ts and .js files - Fix JellyfinMapper test data to use proper type assertions - Refactor JellyfinService tests to use @suites/unit TestBed pattern - Add DateLastSaved field to mapper test data - All 332 tests passing
- Add JellyfinGetterService with property getters for Jellyfin items - Add JELLYFIN = 6 to Application enum in rules constants - Add comprehensive Jellyfin properties for rule builder: - Basic properties: addDate, releaseDate, ratings, genres, labels - Viewing metrics: seenBy, viewCount, lastViewedAt - File properties: resolution, bitrate, codec - Show/season properties: episodeSeenBy, episodeAirDate, lastEpisodeAddedAt - People and collections - Update GetterService to dispatch JELLYFIN rules to JellyfinGetterService - Add unit tests for JellyfinGetterService (25 tests) Phase C of Jellyfin integration - enables rule creation for Jellyfin libraries
…layer - Rename plexId to mediaServerId throughout entities and DTOs - Add mediaServerType column to Collection entity - Update CollectionHandler, RadarrActionHandler, SonarrActionHandler to use MediaServerFactory - Migrate MediaIdFinder to use abstraction layer for metadata lookups - Add CollectionMediaWithMetadata type (deprecate CollectionMediaWithPlexData) - Update exclusion.entities.ts with mediaData field - Migrate getter services to use EMediaDataType - Update RulesDto.dataType and IAlterableMediaDto.type to EMediaDataType - Add createMediaLibrary/createMediaLibraries test helpers - Fix test utilities for collection type detection - Add database migration for plexId -> mediaServerId rename - Document remaining services needing migration in PHASE_D_COLLECTIONS.md BREAKING CHANGE: plexId renamed to mediaServerId in Collection and CollectionMedia entities
…ebase - Updated rules.constants.ts to use EMediaDataType for showType filtering. - Refactored getter services (jellyseerr, overseerr, sonarr, tautulli) to utilize MediaServerFactory for metadata operations. - Adjusted exclusion-corrector.service.ts to fetch metadata using the new media server abstraction. - Modified rule-executor.service.ts to replace PlexApiService calls with MediaServerFactory methods. - Enhanced yaml.service.ts to use EMediaDataType and MediaDataTypeStrings for YAML serialization. - Updated contracts to include MediaDataTypeStrings for better integration with YAML. - Ensured all references to plexId are replaced with mediaServerId throughout the codebase. - Verified that existing Plex collections and functionalities remain intact post-migration.
- Add Jellyfin settings page with connection test, save, and delete - Add MediaServerSelector component for choosing between Plex/Jellyfin - Add useMediaServerType hook for conditional UI rendering - Update NavBar to show 'Box Sets' for Jellyfin, 'Collections' for Plex - Update AddModal with dynamic terminology (box set vs collection) - Hide Plex-only visibility options (showHome, showRecommended) for Jellyfin - Update SettingsWrapper to show appropriate media server tabs - Update Layout redirect logic based on media server type - Add Jellyfin API hooks (useTestJellyfin, useSaveJellyfinSettings, etc.) - Add Jellyfin settings endpoints to backend controller/service - Add Jellyfin settings DTO and Zod schema in contracts package - Update migration to not default media_server_type (null until chosen) - Add Jellyfin logo SVG - Reorganize contracts: move plex types under media-server/plex Part of Jellyfin integration - Phase E (UI Integration)
Jellyfin's user-facing GUI calls them 'Collections', not 'Box Sets'. The 'BoxSet' is just the internal API type (BaseItemKind.BoxSet). Keep the configurable variable infrastructure for potential future customization, but set both Plex and Jellyfin to use 'Collections'.
Implements rule migration when switching between media servers: - New RuleMigrationService for analyzing and migrating rules - Preview migration before switching to show compatible/incompatible rules - Skip rules using Plex-only properties (watchlist, IMDB ratings, smart collections) - UI checkbox to opt-in to rule migration during server switch - Updates settings service to integrate rule migration - Fixes PLEX_ONLY_PROPERTIES to include IDs 36-42 Also includes: - Code formatting with Prettier - Docker test environment for branch testing (jellyfin-dev-documents/docker/)
Moved from jellyfin-dev-documents/docker/ to docker/dev/ for proper version control tracking.
- Remove obsolete 'version' attribute
- Escape shell variables ($${ep}) to prevent Docker Compose interpolation
- Default to enoch85/Maintainerr fork where jellyfin branches exist
- Use named volume instead of bind mount for proper ownership - Add init-permissions container to set correct permissions - Explicitly set user: 1000:1000 to match Dockerfile - Default branch now jellyfin-rule-migration
- Use named volumes for all services (fixes permission issues) - Remove media-generator (mount your own media) - Add comments showing how to mount media directories - Streamline documentation
- Move dev files from docker/dev/ to docker/ - Remove nginx-reverse-subfolder (not needed for local testing)
- Remove PlexSetupGuard from plex-api controller to allow fresh installations - Add new MediaServerSetupGuard that checks if any media server is configured - Fix ServeStaticModule configuration for proper SPA routing - Apply code formatting with prettier (semi: false for contracts)
Changed innerJoinAndSelect to leftJoinAndSelect for collection relationship in getRuleGroups, getRuleGroupsByIds, and getRuleGroup queries. After rule migration, rules have collectionId=null since collections are cleared. The inner join was filtering out these migrated rules, making them invisible in the UI.
When rules are migrated, they have collectionId=null. The updateRules method was failing with 'Cannot read properties of null' when trying to access dbCollection.manualCollection. Now we check if dbCollection exists before comparing its properties.
Changed from ICollection to using collectionId directly to avoid type mismatch between createCollection and updateCollection return types.
The validation logic was using array index (apps[appId]) to look up applications, which worked coincidentally because Application enum values matched their array positions. Changed to use apps.find() for more robust application lookup by ID. This may help fix issues with community rules showing empty values in dropdowns after import.
- Add isPlexSetup() checks to getUsers() and getUser() methods to prevent errors when Plex isn't configured but API is called - Ensure rules array is always defined in getRuleGroup, getRuleGroups, and getRuleGroupsByIds methods - Add Array.isArray() checks in UI components when accessing rules to prevent 'r.map is not a function' errors after migration
benscobie
commented
Jan 7, 2026
benscobie
commented
Jan 7, 2026
benscobie
commented
Jan 7, 2026
benscobie
commented
Jan 7, 2026
…ionId - Changed mediaId parameter from number to string (it was always toString()'d) - Removed unnecessary toString() calls - Use ParseIntPipe with optional:true for collectionId query param - Follows NestJS best practices for parameter validation Addresses PR review comments on collections.controller.ts lines 118, 133, 136
- collections.controller.ts: Add ParseIntPipe to all @Param and @query with number types - tmdb.controller.ts: Fix imdbId to be string type (IMDB IDs are strings like 'tt1234567') - Use ParseIntPipe({ optional: true }) for optional numeric query params - Consistent with NestJS best practices for parameter validation
7e7720e to
d468b03
Compare
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.
To everyone coming here and want to test. Work continues here: Maintainerr#2266