diff --git a/CLAUDE.md b/CLAUDE.md index 594d226..2f00ba5 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -18,8 +18,10 @@ From repo root: ```bash uv sync --all-packages -python -m compileall common/src backend/src runtime/src schedule/src +uv run python -m compileall common/src backend/src runtime/src schedule/src uv run --package backend alembic upgrade head +uv run --package backend pytest backend/tests -q +``` cp .env.example .env docker compose config @@ -49,6 +51,16 @@ pnpm build Hard-won lessons. Read the relevant bullet before touching the named area. +### Python runtime — always go through `uv run` + +- Repo is a uv workspace; `common` / `backend` / `runtime` / `schedule` / `migrations` share one `.venv`. Bare `python` / `pytest` / `alembic` resolves to system Python and **all `from backend.X import ...` / `from common.X import ...` fail with ModuleNotFoundError**, or worse: an out-of-date venv silently runs stale code. +- Always prefix with `uv run [--package ] `: + - `uv run --package backend pytest backend/tests -q` + - `uv run --package backend alembic upgrade head` / `downgrade -1` + - `uv run python -m compileall common/src backend/src runtime/src schedule/src` + - `uv run python -c "from backend.foo import bar"` for one-shot inspection +- Migration files use **plain** `op.drop_index` / `op.create_index` — MySQL 8.0 does not support `IF EXISTS` / `IF NOT EXISTS` on `DROP INDEX` / `CREATE INDEX`, even though Alembic exposes the flag. + ### Platform auth / soft-delete (`/api/v1/platform/employees`) - **Reuse `system_admin_context` + `_*_admins` helpers** in `backend/src/backend/platform.py`. Self-protection and the last-admin guard for `Users.platform_role_id` mirror the workspace pattern. `_count_active_system_admins(session, exclude_user_id=...)` is already there; do not reinvent the count in the handler.