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

124 lines
4.3 KiB
Markdown

# Phase 3: Build Standalone Server Backend
**Status**: In progress
**Parent**: [primary-plan.md](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