nextav/docs/active/library-clusters/LIBRARY_CLUSTER_ARCHITECTUR...

8.9 KiB

Library Cluster Architecture

System Architecture Diagram

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

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

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

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

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

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

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

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

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

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)

-- 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)

-- 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