Files
haos-hacs-immich-album-watcher/plans/phase-3-server-backend.md
alexei.dolgolyov 58b2281dc6
Some checks failed
Validate / Hassfest (push) Has been cancelled
Add standalone FastAPI server backend (Phase 3)
Build a complete standalone web server for Immich album change
notifications, independent of Home Assistant. Uses the shared
core library from Phase 1.

Server features:
- FastAPI with async SQLite (SQLModel + aiosqlite)
- Multi-user auth with JWT (admin/user roles, setup wizard)
- CRUD APIs: Immich servers, album trackers, message templates,
  notification targets (Telegram + webhook), user management
- APScheduler background polling per tracker
- Jinja2 template rendering with live preview
- Album browser proxied from Immich API
- Event logging and dashboard status endpoint
- Docker deployment (single container, SQLite in volume)

39 API routes, 14 integration tests passing.

Also adds Phase 6 (Claude AI Telegram bot enhancement) to the
primary plan as an optional future phase.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 12:56:22 +03:00

4.3 KiB

Phase 3: Build Standalone Server Backend

Status: In progress Parent: primary-plan.md


Goal

Build a standalone FastAPI web server that provides Immich album change notifications without Home Assistant, using the shared core library from Phase 1.


Tech Stack

  • Framework: FastAPI (async-native, OpenAPI docs)
  • Database: SQLite via SQLModel (SQLAlchemy + Pydantic)
  • Auth: bcrypt + JWT (multi-user, admin/user roles)
  • Scheduler: APScheduler (async jobs per tracker)
  • Notifications: Core TelegramClient + new WebhookClient
  • Templates: Jinja2 (same syntax as HA blueprint)
  • Deployment: Docker (single container, SQLite in volume)

Directory Structure

packages/server/
  pyproject.toml
  src/immich_watcher_server/
    __init__.py
    main.py              # FastAPI app, lifespan, static mount
    config.py            # Settings from env vars
    database/
      __init__.py
      models.py          # SQLModel table definitions
      engine.py          # Engine creation, session factory
    auth/
      __init__.py
      jwt.py             # JWT token creation/validation
      dependencies.py    # FastAPI dependency for current_user
      routes.py          # /api/auth/* endpoints
    api/
      __init__.py
      servers.py         # CRUD /api/servers/*
      trackers.py        # CRUD /api/trackers/*
      templates.py       # CRUD /api/templates/*
      targets.py         # CRUD /api/targets/*
      users.py           # CRUD /api/users/* (admin)
      status.py          # GET /api/status
    services/
      __init__.py
      scheduler.py       # APScheduler setup, job management
      watcher.py         # Album polling + change detection
      notifier.py        # Dispatch notifications (Telegram/webhook)
    webhook/
      __init__.py
      client.py          # Generic webhook POST JSON
  Dockerfile
  docker-compose.yml

Tasks

1. Package setup [ ]

  • pyproject.toml with deps: fastapi, uvicorn, sqlmodel, pyjwt, bcrypt, apscheduler, jinja2, immich-watcher-core

2. Database models [ ]

  • User: id, username, hashed_password, role (admin/user), created_at
  • ImmichServer: id, user_id, name, url, api_key, external_domain, created_at
  • NotificationTarget: id, user_id, type (telegram/webhook), name, config JSON, created_at
  • MessageTemplate: id, user_id, name, body (Jinja2), is_default, created_at
  • AlbumTracker: id, user_id, server_id FK, name, album_ids JSON, event_types JSON, target_ids JSON, template_id FK (nullable), scan_interval, enabled, quiet_hours_start, quiet_hours_end, created_at
  • AlbumState: id, tracker_id FK, album_id, asset_ids JSON, last_updated
  • EventLog: id, tracker_id FK, event_type, album_name, details JSON, created_at

3. Auth [ ]

  • POST /api/auth/setup (create first admin, only when no users exist)
  • POST /api/auth/login (returns JWT access + refresh tokens)
  • GET /api/auth/me (current user info)
  • JWT dependency for all protected routes

4. API endpoints [ ]

  • CRUD for servers, trackers, templates, targets
  • GET /api/servers/{id}/albums (proxy to Immich)
  • POST /api/templates/{id}/preview (render with sample data)
  • POST /api/targets/{id}/test (send test notification)
  • POST /api/trackers/{id}/trigger (force check)
  • GET /api/trackers/{id}/history (recent events)
  • GET /api/status (dashboard data)
  • CRUD /api/users (admin only)

5. Background scheduler [ ]

  • APScheduler with AsyncIOScheduler
  • One job per enabled tracker at its scan_interval
  • Job: fetch album -> detect changes -> render template -> notify
  • Start/stop jobs when trackers are created/updated/deleted

6. Notification dispatch [ ]

  • TelegramClient from core (reuse)
  • WebhookClient: POST JSON to configured URL with event data
  • Jinja2 template rendering with same variables as blueprint

7. Docker [ ]

  • Multi-stage Dockerfile (build frontend -> Python runtime)
  • docker-compose.yml for standalone deployment

Acceptance Criteria

  • Server starts, creates SQLite DB on first run
  • First-run setup creates admin account
  • Can add Immich server, browse albums
  • Can create tracker, template, and notification target
  • Scheduler polls albums and detects changes
  • Telegram notifications sent on album changes
  • Webhook notifications sent on album changes
  • JWT auth protects all endpoints
  • Docker build works