Design playlist syncing for multiple media servers#193
Open
Conversation
This design document provides a complete architectural blueprint for implementing bidirectional playlist synchronization with Jellyfin, Emby, and Plex media servers. Key architectural components: - PlaylistSyncProvider interface for server-agnostic sync operations - PlaylistSyncCoordinator for managing sync lifecycle - Persistent sync queue with retry logic and priority handling - Conflict detection and resolution strategies - Repository interceptor pattern for change tracking The design follows Clean Architecture principles and maintains backward compatibility while providing a scalable, resilient foundation for bidirectional sync. Addresses: #102
Resolved all open questions from architecture review: 1. Default Conflict Resolution: Safe Auto-Merge - Union merge for additive operations (preserve all content) - User prompts only for destructive conflicts - Aligns with user expectation of not losing changes 2. Sync Frequency: Daily (user configurable) - Default: Daily background sync (battery-friendly) - Options: 15 min, hourly, 6 hours, daily, manual only - Manual "Sync Now" button for immediate sync 3. Sync Scope: Global per media server - Settings per server type (Jellyfin/Emby/Plex) - All playlists from enabled servers sync automatically - Simpler UX with less configuration overhead 4. Smart Playlists: No sync - Smart playlists are query-based and read-only - Focus sync effort on regular user playlists - Keep them local-only or read-only from server Additional enhancements: - Added detailed WorkManager configuration with constraints - Added PlaylistSyncPreferences structure for user settings - Expanded conflict resolution examples with scenarios - Added shouldSync() helper to exclude smart playlists - Updated document version to 1.1 with changelog Status: Ready for implementation Addresses: #102
This commit implements the foundational infrastructure for bidirectional playlist synchronization as outlined in PLAYLIST_SYNC_ARCHITECTURE.md. New Components: 1. Room Entities - SyncOperation: Persistent queue for sync operations - PlaylistSyncState: Tracks sync state and conflicts per playlist - Added enums: OperationType, SyncStatus, PlaylistSyncStatus 2. Database Layer - SyncOperationDao: CRUD operations for sync queue - PlaylistSyncStateDao: Sync state management - MIGRATION_40_41: Creates new tables with proper indexes and foreign keys - Updated Converters with Instant and enum type converters 3. Repository Layer - PlaylistSyncProvider: Interface for server-specific sync operations - SyncQueueRepository: Interface for sync queue management - LocalSyncQueueRepository: Room-based implementation 4. Dependency Injection - Added SyncQueueRepository to RepositoryModule - Database updated to version 41 with new entities Features: - Persistent sync queue survives app restarts - Priority-based operation ordering - Retry logic with configurable max retries - Conflict detection via content hashing - Foreign key constraints for data integrity - Comprehensive query support for sync status This establishes the foundation for: - Change tracking (Phase 3) - Background sync worker (Phase 4) - Conflict resolution (Phase 5) - Server-specific implementations (Phase 2, 7) Addresses: #102 Related: PLAYLIST_SYNC_ARCHITECTURE.md Phase 1
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.
📋 Overview
This PR introduces a comprehensive architecture design document for implementing bidirectional playlist synchronization between Shuttle2 and media servers (Jellyfin, Emby, Plex).
Addresses: #102 - Sync S2 playlist actions with Jellyfin server
🎯 Problem Statement
Currently, Shuttle2 supports one-way sync (pull playlists from media servers), but modifications made locally (adding/removing songs, renaming, deleting) don't sync back to the server. This creates:
Divergence between Shuttle2 and server state
Manual maintenance burden across multiple clients
Confusion when playlists differ between devices
✨ What's Included
Complete Architecture Document (PLAYLIST_SYNC_ARCHITECTURE.md)
A production-ready design covering:
Core Components
PlaylistSyncProvider interface for server-agnostic sync operations
PlaylistSyncCoordinator for managing sync lifecycle
SyncQueueRepository with persistent queue and retry logic
Repository interceptor pattern for non-invasive change tracking
Conflict Resolution Strategy
Safe Auto-Merge (default): Preserves all content when safe
User prompts only for destructive conflicts (renames, deletions)
Configurable preferences: Auto-merge, Always Local, Always Remote, Ask Me
Sync Configuration
Daily background sync (default, battery-friendly)
User configurable: 15 min, hourly, 6 hours, daily, or manual only
Global enable/disable per server type (Jellyfin/Emby/Plex)
Smart playlists excluded (query-based, read-only)
Media Server API Analysis
Jellyfin: Full CRUD support (with known bugs documented + workarounds)
Emby: Most stable API, excellent documentation
Plex: Comprehensive but different paradigm (URI-based)
Implementation Roadmap
8 phases over 12 weeks
Feature flags for gradual rollout
Backward compatible (no breaking changes)
Clear success criteria for each phase
🏗️ Architecture Highlights
Clean Architecture Principles
Presentation → Domain (Sync Coordinator) → Data (Repository + Providers) → Network
✅ SOLID principles throughout
✅ Repository pattern with reactive streams (Flow)
✅ Plugin architecture for media providers
✅ Offline-first with persistent sync queue
✅ Resilient error handling and conflict resolution
✅ Testable with clear component boundaries
Key Technical Decisions
| Decision | Choice | Rationale | |----------|--------|-----------| | Change Tracking | Repository Interceptor | Non-invasive, decorator pattern | | Sync Queue | Room database | Survives app restarts, queryable | | Conflict Detection | Content hashing | Efficient state comparison | | Background Sync | WorkManager | Battery-aware, constraint-based | | Scope | Global per server | Simple UX, less overhead |
📊 Design Decisions (Resolved)
All open questions have been answered:
✅ Conflict Resolution: Safe Auto-Merge (preserve content, minimize prompts)
✅ Sync Frequency: Daily default (user configurable)
✅ Sync Scope: Global per server type (Jellyfin/Emby/Plex toggles)
✅ Smart Playlists: No sync (query-based, read-only)
🚀 Next Steps
This PR contains architecture design only (no implementation code).
After merge:
Create implementation tickets for Phase 1 (Foundation)
Set up feature flags in build configuration
Begin database schema implementation
Follow the 8-phase rollout plan
📝 Document Details
Version: 1.1
Status: Ready for Implementation
Estimated Effort: 12 weeks (1 developer)
Priority: High (community requested)
Lines: ~1,230 lines of comprehensive documentation
🔍 Review Focus Areas
When reviewing, please pay attention to:
Architecture soundness - Does the component design follow best practices?
Scalability - Can this handle thousands of playlists across multiple servers?
User experience - Are the defaults sensible? Is conflict resolution intuitive?
Implementation feasibility - Is the phased approach realistic?
API compatibility - Are the server API capabilities accurately represented?