eadfbeab35
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
3.5 KiB
3.5 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Stack
| Layer | Tech |
|---|---|
| Backend | FastAPI (async), SQLAlchemy 2 (async), Alembic, PostgreSQL |
| Auth | JWT via python-jose, bcrypt via passlib |
| Frontend | React 18, TypeScript, Vite, React Router v6, TanStack Query, Axios |
| Dev DB | PostgreSQL 16 via Docker Compose |
Commands
Backend (run from backend/)
# Install
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
# Run dev server
uvicorn app.main:app --reload
# Lint / format
ruff check . && ruff format .
# Tests
pytest
pytest tests/test_auth.py # single file
# Migrations
alembic revision --autogenerate -m "describe change"
alembic upgrade head
alembic downgrade -1
Frontend (run from frontend/)
npm install
npm run dev # Vite dev server at :5173, proxies /api → :8000
npm run build
npm run typecheck
npm run lint
Full stack via Docker
cp .env.example backend/.env
docker compose up --build
Architecture
Request flow
Browser → Vite dev server (:5173)
/api/* → proxy → FastAPI (:8000)
→ router → dependency injection (get_db, get_current_user)
→ SQLAlchemy async session → PostgreSQL
Backend layout
app/main.py— FastAPI app, CORS, router registrationapp/core/config.py— all settings viapydantic-settings(reads.env)app/core/security.py— password hashing and JWT encode/decodeapp/database.py— async engine,AsyncSessionLocal,Base(all models inherit from here)app/models/— SQLAlchemy ORM models; import them all in__init__.pyso Alembic detects themapp/schemas/— Pydantic request/response models (separate from ORM models)app/routers/— one file per resource; mount inmain.pyapp/deps.py— FastAPI dependencies:get_current_uservalidates JWT and returnsUser
Frontend layout
src/api/client.ts— single Axios instance; all API calls live here, token injected via interceptorsrc/hooks/useAuth.ts— token state (localStorage),login,logout; consumed by pages andApp.tsxsrc/pages/— one file per route; data fetching via TanStack Querysrc/App.tsx— route tree;PrivateRoutewrapper redirects to/loginwhen no token
Auth flow
POST /api/auth/loginreturns a JWT bearer token- Token stored in
localStorage, attached to every request by the Axios interceptor - Protected routes call
GET /api/users/me;get_current_userdep validates the token on the server
Changelog convention
Every time files are added or modified, append an entry to the relevant file in changelog/ (one file per date, named YYYY-MM-DD_<slug>.md). If a file for today already exists, append to it rather than creating a new one.
Each entry must include:
- A heading with the date and a short description
**Timestamp:**in ISO-8601 format- A Summary sentence
- A Files Added / Modified / Deleted list with one-line descriptions
The README.md Current State section should be kept up to date whenever significant features are added or removed.
Adding a new resource
- Add ORM model in
app/models/, import it inapp/models/__init__.py - Run
alembic revision --autogenerate -m "add <resource>"+alembic upgrade head - Add Pydantic schemas in
app/schemas/ - Add router in
app/routers/, mount it inapp/main.py - Add API function(s) to
src/api/client.ts, add page/component, register route inApp.tsx