Files
immish/docs/architecture.md

6.8 KiB

Architecture Overview

This document describes the high-level architecture of the Immich mobile application.

Architecture Pattern

The app follows a layered architecture with clear separation of concerns:

┌─────────────────────────────────────────────────────────┐
│                    UI Layer (Pages/Widgets)             │
├─────────────────────────────────────────────────────────┤
│                    State Management (Providers)          │
├─────────────────────────────────────────────────────────┤
│                    Services (Business Logic)             │
├─────────────────────────────────────────────────────────┤
│                    Repositories (Data Access)            │
├─────────────────────────────────────────────────────────┤
│          Infrastructure (Database, API, Platform)        │
└─────────────────────────────────────────────────────────┘

Layer Descriptions

1. UI Layer

  • Pages: Full-screen views/routes (e.g., LoginPage, PhotosPage)
  • Widgets: Reusable UI components (e.g., AssetGrid, AlbumCard)
  • Responsible for rendering and user interaction
  • Should contain minimal logic

2. State Management Layer

  • Uses reactive state management pattern
  • Providers: Expose state and actions to the UI
  • Handle state changes and notify listeners
  • Examples: authProvider, assetProvider, albumProvider

3. Services Layer

  • Contains business logic
  • Orchestrates operations between repositories
  • Examples:
    • AuthService: Login, logout, session management
    • BackupService: Photo upload logic
    • AlbumService: Album CRUD operations
    • SearchService: Search functionality

4. Repository Layer

  • Data access abstraction
  • Two types:
    • API Repositories: Server communication
    • Local Repositories: Database access
  • Examples: AssetRepository, AlbumRepository, AuthApiRepository

5. Infrastructure Layer

  • Database: Local data persistence (relational database)
  • API Client: HTTP communication with server
  • Platform APIs: Native device features (camera, gallery, notifications)

Data Flow

Read Operation Example (Loading Albums)

UI (AlbumsPage)
    │
    ▼
Provider (albumProvider)
    │
    ▼
Service (AlbumService.refreshRemoteAlbums)
    │
    ├──► API Repository (fetch from server)
    │
    └──► Local Repository (cache to database)
    │
    ▼
Provider updates state
    │
    ▼
UI rebuilds with new data

Write Operation Example (Creating Album)

UI (CreateAlbumPage)
    │
    ▼
Provider (albumProvider.createAlbum)
    │
    ▼
Service (AlbumService.createAlbum)
    │
    ├──► API Repository (POST to server)
    │
    └──► Local Repository (save to database)
    │
    ▼
Provider updates state
    │
    ▼
UI navigates to new album

Key Architectural Decisions

1. Offline-First Approach

  • Assets are cached locally in the database
  • App works offline with cached data
  • Syncs with server when connection is available

2. Dual Asset States

Assets can exist in three states:

  • Local Only: On device, not uploaded
  • Remote Only: On server, not downloaded
  • Merged: Exists both locally and on server

3. Background Processing

  • Background backup runs independently
  • Uses platform-specific background task APIs
  • Maintains separate execution context

4. Reactive Updates

  • WebSocket connection for real-time server updates
  • Local changes propagate through state management
  • UI automatically updates on state changes

Component Relationships

┌──────────────────────────────────────────────────────────────┐
│                         App Entry                             │
│  - Initialize databases                                       │
│  - Set up dependency injection                                │
│  - Configure routing                                          │
└──────────────────────────────────────────────────────────────┘
                              │
                              ▼
┌──────────────────────────────────────────────────────────────┐
│                      Router/Navigation                        │
│  - Route definitions                                          │
│  - Auth guards                                                │
│  - Deep link handling                                         │
└──────────────────────────────────────────────────────────────┘
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
        ┌──────────┐    ┌──────────┐    ┌──────────┐
        │  Photos  │    │  Search  │    │  Library │
        │   Tab    │    │   Tab    │    │   Tab    │
        └──────────┘    └──────────┘    └──────────┘

Dependency Injection

The app uses a dependency injection container to manage:

  • Service instances
  • Repository instances
  • Database connections
  • API client configuration

All dependencies are:

  • Lazily initialized
  • Scoped appropriately (singleton vs per-use)
  • Easily mockable for testing

Error Handling Strategy

  1. API Errors: Caught at repository level, wrapped in custom exceptions
  2. Service Errors: Logged and propagated to UI
  3. UI Errors: Display user-friendly messages via toasts/dialogs
  4. Fatal Errors: Show error screen with recovery options

Previous: README | Next: Project Structure