Run the test suite and analyze results.
- Run
pytest --import-mode=importlib -v --tb=shortand capture output - If any tests fail, read the failing test file and the source it tests to diagnose the issue
- Run
pytest --import-mode=importlib -v --cov=primer --cov-report=term-missingto check coverage - Report: total passed/failed, coverage percentage, and any uncovered lines worth testing
- In this workspace, prefer
pytest --import-mode=importlib ...so pytest uses this repo'stests/conftest.pyinstead of a sibling checkout's sharedtestspackage when both exist on the same machine.
tests/conftest.py— fixtures (engine, db_session, client, admin_headers, engineer_with_key)tests/test_models.py,tests/test_ingest.py,tests/test_analytics.py,tests/test_hook_extractor.py,tests/test_mcp_reader.py
Run lint and security checks, review code against project conventions.
- Run
ruff check .andruff format --check .— report any violations - Run
bandit -r src/ -c pyproject.toml— report any security findings - Check that new code follows patterns documented in
CLAUDE.md:- SQLAlchemy 2.0
Mapped/mapped_column(not legacyColumn()) - Pydantic v2 with
model_config(notclass Config) - Python 3.12+ union syntax (
str | None) - Service-layer pattern (routers should not contain DB logic)
- FastAPI dependency injection for auth
- SQLAlchemy 2.0
- Verify that new endpoints or services have corresponding tests
- Report findings grouped by category: lint, security, patterns, test coverage
Handle Alembic database migration lifecycle.
- When asked to create a migration:
- Run
alembic revision --autogenerate -m "<description>" - Read the generated migration file in
alembic/versions/ - Verify the upgrade and downgrade functions are correct
- Check for any data-loss operations (column drops, type changes)
- Run
- When asked to apply migrations:
- Run
alembic upgrade head - Verify with
alembic current
- Run
- When asked to test migrations:
- Run
alembic upgrade headthenalembic downgrade -1thenalembic upgrade head - Confirm round-trip succeeds without errors
- Run
alembic/env.py— migration config, imports modelsalembic/versions/— migration scriptssrc/primer/common/models.py— SQLAlchemy models (source of truth)src/primer/common/database.py— engine and session setup
Generate boilerplate for new API resources.
When asked to scaffold a new resource (e.g., "scaffold projects"):
-
Schema — Add to
src/primer/common/schemas.py:<Resource>Create(BaseModel)with input fields<Resource>Response(BaseModel)withmodel_config = {"from_attributes": True}
-
Model — Add to
src/primer/common/models.py:- SQLAlchemy model with
Mapped/mapped_column - UUID string PK,
func.now()timestamps - Foreign keys and relationships as needed
- SQLAlchemy model with
-
Service — Create
src/primer/server/services/<resource>_service.py:- CRUD functions accepting
db: Sessionas first arg
- CRUD functions accepting
-
Router — Create
src/primer/server/routers/<resource>.py:- FastAPI
APIRouterwith/api/v1/<resources>prefix - Use
Depends(require_admin)orDepends(require_engineer)for auth - Register in
src/primer/server/app.py
- FastAPI
-
Tests — Create
tests/test_<resource>.py:- Use fixtures from
conftest.py - Test CRUD operations and auth requirements
- Use fixtures from
-
Migration — Run
alembic revision --autogenerate -m "add <resource>"