Contributing

Who is this page for?

Developers changing GAME’s code or docs. The repository’s CONTRIBUTING.md is the quick reference for the contribution flow; this page is the canonical home for the test/coverage workflow and the architectural context behind it (the root TESTING.md is a thin pointer here).

Development setup

git clone https://github.com/fvergaracl/GAME.git
cd GAME
poetry install
cp .env.sample .env
poetry run alembic upgrade head
poetry run uvicorn app.main:app --reload   # http://localhost:8000

Read Architecture before your first non-trivial change - the layer boundaries are enforced socially, not by the compiler, so knowing which layer owns what is how reviews go smoothly.

Where code goes

Change

Lives in

New HTTP endpoint

app/api/v1/endpoints/ + register the router in app/api/v1/routes.py.

Business logic

app/services/ - never put it in an endpoint or repository.

New persistence query

app/repository/ - keep it free of domain decisions.

New table

app/model/ + an Alembic migration in migrations/.

Wire-format change

app/schema/ (Pydantic).

New scoring strategy

app/engine/ - subclass BaseStrategy and decorate with @register_strategy(id=...).

New dependency wiring

app/core/container.py.

Testing

GAME uses pytest with a layered suite under tests/ and one-command runners (they load .env for you):

Suite

Run it

Unit

./scripts/run_unit_tests.sh (--fail-fast, --cov, --file <path>). Fast, isolated, mock external dependencies.

E2E (controlled)

./scripts/run_e2e.sh - isolated SQLite, deterministic, no real infra.

E2E (real infra)

./scripts/run_e2e.sh --real - real HTTP + PostgreSQL + Keycloak.

Load (k6)

./scripts/run_load_test.sh --mode 100.

Or drive pytest directly:

poetry run pytest
poetry run pytest --cov=app --cov-branch --cov-report=html
poetry run pytest -k "test_assign_points"

Guidelines:

  • Every feature/fix ships with tests. Unit-test services in isolation; reserve real-infra E2E for integration behavior.

  • Because persistence is abstracted, services run against SQLite in tests and PostgreSQL in production - keep repository queries portable.

  • CI enforces quality gates on every PR: a lint job (ruff check, black --check, isort --check-only) and the test suite with a blocking coverage gate - pytest --cov-fail-under fails the build (and the PR) when coverage drops below the floor. The threshold is set in one place, .github/workflows/coverage.yml; it is a hard gate, not an aspiration. A separate Dashboard CI job covers the React frontend, and Codecov tracks the trend.

Code style

  • Python 3.12, PEP 8. Formatting/linting is handled by Ruff, Black and isort (isort uses the black profile so the two never disagree); the CI lint gate runs them in --check mode. Install the local hooks with pre-commit install to catch the same issues before you push.

  • Public functions and classes get Google-style docstrings - they are not decoration, they are the API reference (Codebase Reference) via napoleon.

  • Match the surrounding code: the codebase favors small, well-named functions, explicit dependencies, and comments that explain why (often referencing the sprint or the bug a guard prevents) rather than what.

Documentation

Docs are part of the product, not an afterthought. The information architecture follows the Diátaxis model - every page declares who it is for and stays in its lane:

Diátaxis type

Purpose

Examples here

Tutorial

Learning by doing

Getting Started

How-to

Task-oriented steps

Integrating with GAME, Operations

Explanation

Understanding

Overview, Architecture, The DSL Strategy Engine

Reference

Dry facts

Configuration Reference, REST API Reference, Codebase Reference

Where docs live

Location

Content

docs/source/*.rst

This Sphinx site (reStructuredText). Built to GitHub Pages on every push to main.

docs/source/api/

Auto-generated module reference (sphinx-apidoc + autodoc).

docs/dsl/

DSL block reference and runbook (linked from the editor).

docs/source/domain-model.rst

The domain model and its rendered entity-relationship diagram (docs/domain-model.md is now a thin pointer here).

Top-level *.md

README, SETUP, DEPLOYMENT, TESTING, KUBERNETES_SETUP - entry points and quick references.

Building the docs locally

# One-off build
poetry run sphinx-build -b html docs/source _build/html

# Live-reloading preview while you write
poetry run sphinx-autobuild docs/source _build/html

# Regenerate the module reference after adding/moving modules
.venv/bin/sphinx-apidoc -f -e -M -o docs/source/api app

Keep the build warning-clean: a broken cross-reference or an orphaned page is a bug. Add a one-line “Who is this page for?” admonition to every new page so its audience is explicit.

Submitting a change

  1. Branch: git checkout -b feature/your-feature-name.

  2. Make the change with tests and docstrings/docs.

  3. Run the relevant test suite and the docs build locally.

  4. Open a PR with a clear description and linked issues. CI runs tests, coverage, linting, pip-audit (make audit locally), and the docs build.

Report bugs and request features via GitHub Issues; discuss design in GitHub Discussions.