This file provides guidance to coding agents when working with code in this repository.
- Local development:
docker compose up(starts all services) - Run tests:
cd backend && uv run pytestorDJANGO_SETTINGS_MODULE=pycon.settings.test uv run pytest - Single test:
cd backend && uv run pytest path/to/test_file.py::test_function - Lint/format:
cd backend && uv run ruff checkanduv run ruff format - Type checking:
cd backend && uv run mypy . - Django management:
cd backend && uv run python manage.py <command> - Migrations:
cd backend && uv run python manage.py makemigrationsanduv run python manage.py migrate
- Local development:
cd frontend && pnpm dev(or via docker compose) - Build:
cd frontend && pnpm build - Tests:
cd frontend && pnpm test - GraphQL codegen:
cd frontend && pnpm codegen(orpnpm codegen:watch) - Lint/format: Use Biome via
npx @biomejs/biome checkandnpx @biomejs/biome format
This is a monorepo for PyCon Italia's website with:
- API Layer: GraphQL API using Strawberry at
/backend/api/ - Django Apps: Modular apps in
/backend/including:conferences/- Conference management and configurationsubmissions/- Talk/proposal submissionsusers/- User management and authenticationschedule/- Event scheduling and video uploadssponsors/- Sponsor managementgrants/- Financial assistance programblog/- Blog posts and newscms/- Content management via Wagtailapi/- GraphQL schema and resolvers
- Database: PostgreSQL with migrations in each app's
migrations/folder - Task Queue: Celery with Redis backend for async processing
- Storage: Configurable (filesystem local, cloud for production)
- Framework: Next.js
- Styling: Tailwind CSS with custom design system
- State Management: Apollo Client for GraphQL
- Type Safety: Full TypeScript with generated types from GraphQL schema
- Location:
/frontend/src/contains pages, components, and utilities
- Pretix: Ticketing system integration for event registration
- Stripe: Payment processing
- ClamAV: File scanning for security
- Wagtail: CMS for page content management
- Google APIs: For YouTube video management and calendar integration
The project uses Docker Compose for local development with services:
- backend: Django API server (port 8000)
- frontend: Next.js dev server (port 3000)
- custom-admin: Admin interface (ports 3002-3003)
- backend-db: PostgreSQL database (port 15501)
- redis: Caching and task queue
- clamav: File virus scanning
- Python version: 3.14.7+ (specified in pyproject.toml)
- Uses
uvfor Python package management - Uses
pnpmfor Node.js package management - GraphQL schema auto-generation from Django backend to frontend
- Test configuration uses separate settings (
pycon.settings.test) - Ruff handles both linting and formatting for Python code
- Biome handles linting and formatting for JavaScript/TypeScript
When working in backend/api:
- Name Strawberry GraphQL classes after their GraphQL schema types, without a
Typesuffix. - Import Django model modules and access models through the module namespace,
for example
from job_board import modelsandmodels.JobListing. - If a file needs models from multiple Django apps, alias the modules, for
example
job_board_modelsandconference_models. - Do not alias individual Django models with a
Modelsuffix or GraphQL types with aTypesuffix solely to avoid naming conflicts. - Use
strawberry.autoinstead of importingautodirectly from Strawberry. - Use
strawberry.IDinstead of importingIDdirectly from Strawberry. - Preserve existing GraphQL schema names when migrating types to Strawberry Django.
IMPORTANT: When running locally, all Python/Django commands must run inside Docker. The local virtual environment will not work.
- Start services:
docker compose up(starts all services) - Run tests:
docker compose exec backend uv run pytest -l -s -vvv - Single test:
docker compose exec backend uv run pytest path/to/test_file.py::test_function -l -s -vvv - Lint/format:
docker compose exec backend uv run ruff checkanddocker compose exec backend uv run ruff format - Type checking:
docker compose exec backend uv run mypy . - Django management:
docker compose exec backend uv run python manage.py <command> - Migrations:
docker compose exec backend uv run python manage.py makemigrationsanddocker compose exec backend uv run python manage.py migrate
Troubleshooting: If the backend container is not working:
- Restart container:
docker compose restart backend - If dependencies changed: Remove
backend/.venvand rebuild withdocker compose build --no-cache && docker compose up
- A comment states a constraint the code cannot express and a reader would otherwise undo: an external quirk (GraphQL, a library), a non-obvious invariant, a reason not to take the obvious shortcut. Nothing else.
- Never describe what the code did before, why it changed, or what it replaces. If the comment only makes sense to someone who saw the old code, delete it. It belongs in the commit message. Self-check before finishing: grep the diff for
used to|previously|before|no longer|already|now|instead of|pinned|this PRin comment lines and delete or rewrite every hit. - No ticket IDs, PR numbers, spec or plan file names in code or comments.
- One or two lines. A longer comment means the code or the name needs work.
- No section-divider comments (
# -- foo ---), no narration (# increment count), no docstring that restates the function or class name. - Docstrings only on public interfaces: API views, serializers used by the FE, functions exported for other apps. Private helpers get a name, not a docstring.
- No comments and no docstrings in test files. The test name is the documentation. If a fixture needs explaining, rename the variable; if a class needs a docstring, split it or rename it.
- Test behaviour, never structure.
- A test earns its place only if a plausible bug would fail it and no other test. Before adding one, name that bug. Delete tests that are implied by another test (
x is not Nonewhen another test dereferencesx; "is accepted" when another test already gets results through the same path). - Assert complements together.
exists: trueandexists: false, or any pair of opposite directions, share fixtures and live in one test. - Use
pytest.mark.parametrizefor cases that differ only in inputs. Do not write near-identical test methods. - Do not add guard tests for pre-existing behaviour the change cannot affect.
- Extend the existing test module for a feature. Do not create a parallel
*_edge_casesmodule or "pin" a test file as unmodifiable.