summaryrefslogtreecommitdiff
path: root/CLAUDE.md
diff options
context:
space:
mode:
Diffstat (limited to 'CLAUDE.md')
-rw-r--r--CLAUDE.md22
1 files changed, 17 insertions, 5 deletions
diff --git a/CLAUDE.md b/CLAUDE.md
index a646370..ed960f2 100644
--- a/CLAUDE.md
+++ b/CLAUDE.md
@@ -3,7 +3,7 @@
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## What This Is
-Lumiere is a personal cinema diary — a server-rendered FastAPI web app backed by SQLite. Users track films across three shelves: `diary`, `queue`, and `abandoned`. TMDB enriches film metadata (posters, directors, runtime, countries).
+Lumière is a personal cinema diary — a server-rendered FastAPI web app backed by SQLite. A single owner logs in with a password; the `/tyler` public profile is read-only for guests. Films live on three shelves: `diary`, `queue`, and `abandoned`. TMDB enriches metadata (posters, directors, runtime, countries, cast, overview); OMDb supplies third-party ratings (IMDb, Rotten Tomatoes, Metacritic) on the detail page.
## Commands
@@ -22,22 +22,34 @@ python -m venv .venv
.venv/bin/pytest
```
-Requires a `.env` file with `TMDB_API_KEY=...`. App runs at `http://127.0.0.1:8000`.
+Requires a `.env` file with:
+```
+TMDB_API_KEY=...
+OMDB_API_KEY=... # for IMDb/RT/Metacritic ratings
+OWNER_PASSWORD_HASH=... # argon2 hash; generate with: python -c "from argon2 import PasswordHasher; print(PasswordHasher().hash('your-password'))"
+SESSION_SECRET=... # random secret for cookie signing
+```
+App runs at `http://127.0.0.1:8000`.
## Architecture
**Request flow:** Browser → FastAPI router → SQLAlchemy (SQLite) → Jinja2 template → HTML response. `static/app.js` handles star ratings (JSON PATCH) and TMDB search autocomplete without a build step.
**Key files:**
-- `main.py` — app entry, router registration
+- `main.py` — app entry, router registration, `AuthMiddleware` (session-based, password protected)
- `database.py` — SQLite engine, sessions, self-healing schema migration (no Alembic; renames old table on column mismatch and migrates data)
- `models.py` — single `Film` ORM model with a `shelf` column
-- `routers/films.py` — shelf listing, CRUD, director page, queue random pick, star rating API
+- `routers/films.py` — shelf listing, CRUD, director page, queue random pick, star rating API, infinite-scroll partial
- `routers/imports.py` — Letterboxd and watchlist CSV import, deduplication, enrichment
- `routers/stats.py` — all-time stats and year-in-review (pure Python aggregation, no SQL GROUP BY)
+- `routers/auth.py` — `/login` / `/logout` using argon2 password hashing
+- `routers/profile.py` — public `/tyler` profile page (no auth required)
+- `routers/about.py` — static about page
- `routers/tmdb.py` — `/tmdb/search?q=` proxy for JS autocomplete
-- `services/tmdb.py` — TMDB API client: search, detail fetch, metadata application
+- `services/tmdb.py` — TMDB API client: search, detail fetch, metadata application, director bio/image
+- `services/omdb.py` — OMDb API client: fetches IMDb/Rotten Tomatoes/Metacritic ratings for detail page
- `services/film_people.py` — director name normalization and URL slug helpers
+- `services/countries.py` — ISO numeric country code mapping for stats world map
**Patterns:**
- Route logic stays in `routers/`, shared service logic in `services/`