# CLAUDE.md ## What this is A monorepo (M1) of an Immich photo-flow foundation + the `trip-cluster` app. See `docs/ROADMAP.md` for milestones and `docs/superpowers/specs/2026-06-27-immich-photo-flow-design.md` for the M1 design. ## Architecture map - `shared/photoflow/immich` — **the only** Immich client (`client.py`) + `_pipeline/` tag conventions (`pipeline.py`). - `shared/photoflow/core` — **the only** SQLite owner: `store.py` (data-access) + `models.py`. - `shared/photoflow/ui` — `base.html`, shared Jinja macros, `shared.js` grid+lightbox. - `apps/trip-cluster/app` — `config.py`, `cli.py` (ingest|cluster|serve|apply), `ingest.py`, `clustering.py` (pure), `coverage.py` (pure), `cluster_run.py`, `review.py`, `writeback.py`, `routes/`, `templates/`, `static/app.js`. ## Key invariants - **Immich is the source of truth**; SQLite is rebuildable. Only **applied** decisions survive loss of SQLite (via `_pipeline/processed` + `writeback_log`). - Content/trip tags are **never namespaced**; pipeline meta-tags nest under `_pipeline/`. - Trip detection is **timestamp-first, density-adaptive**, anchored by existing trip tags, refined by GPS. Existing trip tags are authoritative seeds. - Write-back is **idempotent** (`writeback_log`) and needs **explicit confirmation**. - Ingest is **scopeable** (`--from/--to`, `--tag`, `--subset`) and incremental (`updatedAfter`). - trip-cluster serves on **8084**. ## Dev commands ```bash .venv/bin/python -m pytest # unit + route (Immich mocked) .venv/bin/python -m pytest apps/trip-cluster/tests/ui # Playwright docker compose up # UI on :8084 ``` Write a failing test first (TDD). Mirrors the sibling apps in `/home/mischa/Projects/`.