# Library Cluster Architecture ## System Architecture Diagram ```mermaid graph TB subgraph "Frontend Layer" A[Settings Page] --> B[Cluster Management UI] C[Sidebar] --> D[Cluster Navigation] E[Cluster View Page] --> F[Media Grid] end subgraph "API Layer" G[/api/clusters] H[/api/clusters/id] I[/api/clusters/id/libraries] J[/api/clusters/id/videos] K[/api/clusters/id/stats] end subgraph "Database Layer" L[(clusters)] M[(library_cluster_mapping)] N[(libraries)] O[(media)] end B --> G B --> H B --> I D --> G F --> J F --> K G --> L H --> L I --> M J --> O K --> O M --> L M --> N O --> N ``` ## Data Model Relationships ```mermaid erDiagram CLUSTERS ||--o{ LIBRARY_CLUSTER_MAPPING : contains LIBRARIES ||--o{ LIBRARY_CLUSTER_MAPPING : belongs_to LIBRARIES ||--o{ MEDIA : contains CLUSTERS { int id PK string name UK string description string color string icon datetime created_at datetime updated_at } LIBRARY_CLUSTER_MAPPING { int id PK int library_id FK int cluster_id FK datetime created_at } LIBRARIES { int id PK string path UK } MEDIA { int id PK int library_id FK string path string type string title int size } ``` ## User Flow: Creating and Using a Cluster ```mermaid graph TD A[User opens Settings] --> B[Navigate to Clusters section] B --> C[Click Create Cluster] C --> D[Enter cluster details] D --> E{Name valid?} E -->|No| D E -->|Yes| F[Select color and icon] F --> G[Click Save] G --> H[Cluster created] H --> I[Assign libraries to cluster] I --> J[Select libraries from list] J --> K[Confirm assignment] K --> L[Cluster ready to use] L --> M[Navigate via sidebar] M --> N[View unified media from all libraries] ``` ## API Request Flow ```mermaid sequenceDiagram participant User participant Frontend participant API participant Database User->>Frontend: Click cluster in sidebar Frontend->>API: GET /api/clusters/123/videos API->>Database: SELECT media WHERE library_id IN (cluster_libraries) Database-->>API: Return media records API-->>Frontend: JSON response with videos Frontend->>Frontend: Render virtual grid Frontend-->>User: Display unified media view ``` ## Component Hierarchy ``` App ├── Layout │ ├── Sidebar │ │ ├── Navigation │ │ └── Clusters Section │ │ ├── Cluster Item (Movies) │ │ ├── Cluster Item (TV Shows) │ │ └── Cluster Item (Anime) │ │ │ └── Main Content Area │ ├── Settings Page │ │ ├── Library Management │ │ └── Cluster Management │ │ ├── Cluster List │ │ ├── Create Cluster Form │ │ └── Library Assignment UI │ │ │ └── Cluster View Page │ ├── Cluster Header │ ├── Stats Cards │ ├── Tab Navigation │ └── Media Grid (Virtualized) ``` ## Database Query Patterns ### Pattern 1: Get all clusters with library counts ```sql SELECT c.*, COUNT(DISTINCT lcm.library_id) as library_count, COUNT(DISTINCT m.id) as media_count FROM clusters c LEFT JOIN library_cluster_mapping lcm ON c.id = lcm.cluster_id LEFT JOIN libraries l ON lcm.library_id = l.id LEFT JOIN media m ON l.id = m.library_id GROUP BY c.id ORDER BY c.name; ``` ### Pattern 2: Get all media for a cluster ```sql SELECT m.*, l.path as library_path FROM media m INNER JOIN libraries l ON m.library_id = l.id INNER JOIN library_cluster_mapping lcm ON l.id = lcm.library_id WHERE lcm.cluster_id = ? AND m.type = ? ORDER BY m.created_at DESC LIMIT ? OFFSET ?; ``` ### Pattern 3: Get cluster statistics ```sql SELECT COUNT(CASE WHEN m.type = 'video' THEN 1 END) as video_count, COUNT(CASE WHEN m.type = 'photo' THEN 1 END) as photo_count, COUNT(CASE WHEN m.type = 'text' THEN 1 END) as text_count, SUM(m.size) as total_size, COUNT(DISTINCT l.id) as library_count FROM media m INNER JOIN libraries l ON m.library_id = l.id INNER JOIN library_cluster_mapping lcm ON l.id = lcm.library_id WHERE lcm.cluster_id = ?; ``` ## State Management ### Cluster State ```typescript interface ClusterState { clusters: Cluster[]; selectedCluster: Cluster | null; loading: boolean; error: string | null; } interface Cluster { id: number; name: string; description?: string; color: string; icon: string; library_count?: number; media_count?: number; created_at: string; updated_at: string; } ``` ### Library-Cluster Mapping State ```typescript interface ClusterMapping { clusterId: number; libraryIds: number[]; } interface LibraryWithClusters extends Library { clusters: Cluster[]; } ``` ## Performance Optimization Strategy ### 1. Database Level - Composite indexes on `(cluster_id, library_id, type, created_at)` - Materialized views for cluster statistics - Connection pooling for concurrent queries ### 2. API Level - Response caching with Redis (TTL: 5 minutes) - Pagination for large result sets - Batch operations for library assignments ### 3. Frontend Level - Virtual scrolling for large media grids - Lazy loading of cluster details - Client-side caching of cluster metadata - Optimistic UI updates ## Security Considerations ### Access Control Flow ```mermaid graph LR A[User Request] --> B{Authenticated?} B -->|No| C[401 Unauthorized] B -->|Yes| D{Has Library Access?} D -->|No| E[403 Forbidden] D -->|Yes| F{Cluster Exists?} F -->|No| G[404 Not Found] F -->|Yes| H[Return Data] ``` ### Validation Rules 1. Cluster name: 1-100 characters, alphanumeric + spaces 2. Color: Valid hex color format (#RRGGBB) 3. Icon: From predefined list 4. Library assignments: Only existing library IDs 5. Prevent circular references 6. Rate limiting: 100 requests/minute per user ## Migration Strategy ### Phase 1: Schema Migration (No Downtime) ```sql -- Add new tables without affecting existing ones -- All existing functionality continues to work ``` ### Phase 2: Gradual Rollout 1. Deploy backend with new tables (inactive) 2. Deploy UI with cluster management (opt-in) 3. Monitor performance and gather feedback 4. Promote feature to all users ### Phase 3: Data Backfill (Optional) - Auto-create clusters based on library naming patterns - Suggest cluster assignments using ML/heuristics - Allow users to accept/reject suggestions ## Monitoring and Metrics ### Key Metrics to Track 1. **Usage Metrics** - Number of clusters created - Average libraries per cluster - Most popular cluster types 2. **Performance Metrics** - Cluster query response time - Media aggregation performance - Database query execution time 3. **User Engagement** - Cluster view page visits - Time spent on cluster views - Feature adoption rate ## Error Handling ### Common Error Scenarios 1. **Duplicate Cluster Name**: Return 409 Conflict 2. **Library Not Found**: Return 404 Not Found 3. **Invalid Mapping**: Return 400 Bad Request 4. **Database Error**: Return 500 Internal Server Error 5. **Concurrent Modification**: Use optimistic locking ## Testing Checklist ### Unit Tests - [ ] Cluster CRUD operations - [ ] Library-cluster mapping - [ ] Media queries by cluster - [ ] Statistics calculation - [ ] Validation rules ### Integration Tests - [ ] End-to-end cluster creation - [ ] Multi-library media aggregation - [ ] Pagination with large datasets - [ ] Concurrent user access ### Performance Tests - [ ] 1000+ media items per cluster - [ ] 10+ libraries per cluster - [ ] 50+ concurrent cluster queries - [ ] Database index effectiveness ### UI/UX Tests - [ ] Responsive design - [ ] Accessibility (WCAG 2.1) - [ ] Browser compatibility - [ ] Mobile experience ## Rollback Plan ### If Issues Occur 1. **Minor Issues**: Hot-fix and redeploy 2. **Major Issues**: - Disable cluster UI features - Keep database tables (no data loss) - Investigate and fix - Re-enable when stable ### Database Rollback (If Needed) ```sql -- Only if absolutely necessary DROP TABLE library_cluster_mapping; DROP TABLE clusters; -- Application continues to work without cluster features ``` ## Future Enhancements Roadmap ### Q1 2026 - Smart auto-categorization - Cluster templates - Import/export configurations ### Q2 2026 - Cross-cluster search - Advanced analytics - Cluster sharing between users ### Q3 2026 - AI-powered recommendations - Cluster-based permissions - Scheduled scanning per cluster --- **Document Version**: 1.0 **Last Updated**: 2025-10-11 **Related Documents**: LIBRARY_CLUSTER_FEATURE.md