This file guides automated agents and contributors working in this repository. It mirrors CLAUDE.md and reflects current codebase practices.
PingPong is app to support the PingPong College RCT study with:
- Backend: FastAPI (Python 3.11+), async SQLAlchemy, Pydantic v2, PyAirtable
- Frontend: SvelteKit with TypeScript
web/study(Svelte 5, Tailwind v4, bits-ui)
- Authorization: PyAirtable
- Authentication: JWT (magic links)
pingpong/FastAPI app, models, schemas, authz, integrationsweb/study/study dashboard UI (Svelte 5)scripts/one-off scripts and CLI helpersconfig.tomlconfiguration defaults
uv sync
CONFIG_PATH=config.local.toml uv run fastapi dev pingpong --port 8000 --host 0.0.0.0 --reloadpnpm install
pnpm dev
pnpm check
pnpm lint
pnpm format./start-dev-docker.sh- Request middleware order: session parsing -> authz session -> DB session -> logging. Access
request.state.db,request.state.authz,request.state.session. - Authorization uses composable expressions in
pingpong/permission.py(Authz,LoggedIn,InstitutionAdmin). - Schemas live in
pingpong/schemas.py(Pydantic v2). Return schemas directly from endpoints. - Central config is
pingpong/config.pyviaBaseSettingsand TOML (CONFIG_PATH=config.local.toml).
- Svelte 5 runes and
.svelte.tsmodules appear throughout; follow those patterns. - UI uses Tailwind v4, bits-ui, and components under
src/lib/components/src/lib/components/ui.
- Follow existing async-first patterns and type hints.
- Keep imports grouped: stdlib, third-party, local.
- Use logging via
logging.getLogger(__name__)and raiseHTTPExceptionfor HTTP errors. - Prefer Pydantic models for request/response shapes instead of raw dicts.
web/study:
- Prettier uses tabs, single quotes, no trailing commas, print width 100.
- ESLint flat config; keep formatting consistent with existing files.
- Add route handlers in
pingpong/server.pyalongside related endpoints. - Add/extend Pydantic schemas in
pingpong/schemas.py. - Apply permission expressions via PyAirtable.
- Implement client call in
web/study/src/lib/api.ts.
- Dev email uses the mock sender; check API console output for magic links.