Local development (canonical)
Hard rules
- Do not run
docker compose upin this repo unless the user explicitly requests it. - Run the backend via
pdm run dev(host uvicorn), not via Compose.
PDM script map (most used)
- Backend:
pdm run dev/pdm run dev-logs(logs to.artifacts/dev-backend.log)pdm run dev-local(backend + SPA with log piping)pdm run kill-dev(kills host uvicorn; only when requested)
- Frontend (SPA):
pdm run fe-installpdm run fe-dev/pdm run fe-dev-logs(logs to.artifacts/dev-frontend.log)pdm run fe-build
- Quality gates:
pdm run format/pdm run lint/pdm run typecheck/pdm run testpdm run docs-validate
Quick start checklist (backend)
- Ensure
.envexists (copy from.env.example). - Ensure tool artifacts directory exists and is configured:
- Set
ARTIFACTS_ROOT=/tmp/skriptoteket/artifactsin.env - Run
mkdir -p /tmp/skriptoteket/artifacts
- Set
- Install Python deps:
pdm install -G monorepo-tools- If you need browser tooling locally:
pdm install -G monorepo-tools -G dev
- Run backend:
pdm run dev
Quick start checklist (frontend SPA)
- Install deps:
pdm run fe-install - Run SPA dev server:
pdm run fe-dev - When debugging API calls, check backend logs from the
pdm run devterminal (Vite proxies to127.0.0.1:8000).
Docker / containers (only when requested)
- DB-only dev:
docker compose up -d dbpdm run db-upgrade
- Full dev containers (long-running; don’t stop unless asked):
pdm run dev-start/pdm run dev-stop- Logs:
pdm run dev-containers-logs
- Destructive resets (explicit approval required):
pdm run dev-db-reset
Verification (local)
- Health:
curl -sSf http://127.0.0.1:8000/healthz >/dev/null - Tokenizer availability (Devstral/Tekken):
pdm run pytest -q tests/unit/infrastructure/llm/test_token_counter_resolver.py
Logging + correlation (local)
- Configure via
.env:LOG_FORMAT=json|console(default:json)LOG_LEVEL=INFO|DEBUG|...SERVICE_NAME/ENVIRONMENT(defaults:skriptoteket/development)
- For greppable backend logs:
pdm run dev-logs(writes.artifacts/dev-backend.log) - Verify correlation end-to-end (access logs + app logs):
curl -s -D - -o /dev/null -H 'X-Correlation-ID: <uuid>' http://127.0.0.1:8000/healthzrg '<uuid>' .artifacts/dev-backend.log(expects auvicorn.accessJSON line withcorrelation_id)
- Note: in our pinned Uvicorn (
0.40.0),uvicorn.accessis emitted onhttp.response.start(headers sent), so SSE/streaming logs appear when the stream begins. - If running the backend via container (only when requested), use:
docker logs -f skriptoteket_web | rg '<uuid>'
PDM groups/extras (avoid rebuild surprises)
Mental model
[project].dependenciesis always installed (prod + local).[dependency-groups]is for dev-only groups (lint/test/dev tooling). These are selected withpdm install -G <group>(and are incompatible with--prod).[project.optional-dependencies]is for extras (runtime feature toggles). These are selected withpdm install --prod -G <extra>in production-like installs.
Known pitfall
pdm install --prod -G <dependency-group>fails with:--prod is not allowed with dev groups.- Fix by moving that group to
[project.optional-dependencies]if it must be selectable in prod builds, or by removing--prodif it’s dev-only.
- Fix by moving that group to