# My Library: Personal Book Collection Tracker Flask + React + PostgreSQL. Users catalog their books, track reading progress, keep a reading journal per book, and search/filter their library. Each user sees only their own data. ## Run (CoderPad) The pad starts Flask (`backend/app.py`, port 5000) and Vite automatically. The schema is created on startup. Optionally set `PASSWORD_PEPPER` (≥ 32 chars). Without it, a development pepper is generated into `backend/.pepper` and a warning is logged. ## Run (local) ```bash mise trust && mise install # Python 3.14, Node 24 docker compose up -d db # postgres:16 on 127.0.0.1:5432 docker compose exec -T db pg_isready -U postgres # repeat until it reports "accepting connections" mise exec -- python -m venv .venv && .venv/bin/pip install -r backend/requirements.txt mise exec -- npm install .venv/bin/python backend/app.py # API on :5000 mise exec -- npm run dev # UI; /api is proxied to Flask ``` ## Test ```bash .venv/bin/python -W error -m unittest discover -s backend/tests -t backend -v # real Postgres (books_test); run from repo root mise exec -- npm test && mise exec -- npm run typecheck ``` ## Design - **Feature slices.** One Flask Blueprint per feature: `auth.py`, `books.py` and `notes.py` each hold their routes, validation and SQL. `db.py` holds the pool and transactions; `validation.py` holds the shared input rules. - **Isolation in SQL.** Every query filters on the session's user (`AND user_id = %s`, or joins to `books` for notes). Another user's book and a missing book return the same 404. - **Passwords.** Peppered PBKDF2-HMAC-SHA256 (FIPS-approved, stdlib only). See [ADR-0001](docs/adr/0001-password-hashing-pbkdf2.md). - **Sessions.** Opaque tokens hashed at rest; 30-minute idle and 12-hour absolute expiry; real logout; CSRF handled by SameSite plus a JSON-only rule. See [ADR-0002](docs/adr/0002-server-side-sessions.md). - **Data rules in two places.** The API returns specific 400s, and Postgres CHECK and FK constraints backstop them. - **Frontend.** React Router (search and filter state lives in the URL), a small auth context, Tailwind. No state library. Full spec: [docs/superpowers/specs/2026-10-02-book-tracker-design.md](docs/superpowers/specs/2026-10-02-book-tracker-design.md) ## Known trade-offs | Not included | Add when | |---|---| | Pagination | libraries exceed a few hundred books | | Trigram/full-text index | ILIKE search slows (thousands of books) | | Login rate limiting | before production | | Migrations tool | schema changes after first deploy | | Pepper rotation | before production key management | A request that fails with 4xx rolls back its transaction, including the session idle-window slide, so failed requests don't extend the 30-minute idle timeout.