Local development setup¶
This is the canonical onboarding guide for a clean checkout of the Sport Analytics Tool.
Component getting-started audit¶
Each independently developed or operated part of the monorepo has a repository entry point:
| Component / location | Getting-started README | Responsibility |
|---|---|---|
| Repository root | README.md | Overall project setup, architecture boundaries and links to specialist guides. |
apps/frontend/ |
apps/frontend/README.md | React/Vite application setup, environment, run, test and build guidance. |
apps/backend/ |
apps/backend/README.md | Express API setup, environment, database access, run, test and build guidance. |
database/ |
database/README.md | PostgreSQL migrations, development connection, seeding and database testing. |
packages/contracts/ |
packages/contracts/README.md | Shared Zod/TypeScript contract build, test and usage boundaries. |
docs/ |
docs/README.md | MkDocs prerequisites, local serve/build and deployment guidance. |
tests/ |
tests/README.md | Unit, API, database, E2E, accessibility, performance and coverage entry points. |
infra/ |
infra/README.md | Infrastructure/deployment boundaries and Azure-specific guidance. |
scripts/ |
scripts/README.md | Developer-facing repository scripts, prerequisites and safe usage. |
evidence/ |
evidence/README.md | Evidence artefact purpose, locations and integrity rules. |
Each listed README is the component's getting-started entry point. Separate GETTING_STARTED.md files are intentionally not created because they would duplicate the same setup instructions.
1. Required software¶
| Tool | Project requirement | Why it is needed |
|---|---|---|
| Git | Git 2.x | Clone, branch, commit and Pull Request workflow. |
| Node.js | 20.19+ (20.x) or 22.12+ | Backend runtime and all JavaScript/TypeScript tooling. Vite 7 sets this floor; Azure and hosted CI use Node.js 22 LTS. |
| npm | 10 or later | Workspace installation and repository scripts. |
| Python | 3.10 or later | MkDocs documentation and the Cricsheet downloader. |
| Docker | Docker Desktop or compatible Docker runtime with Compose | Optional explicit PostgreSQL integration-test workflow. |
Optional:
- the Supabase CLI/local Supabase stack, only if the team deliberately chooses to use it;
- an editor/IDE of your choice. The repository does not require VS Code, Qoder or any other editor.
Docker is not required to run the application, npm run test, or npm run check. It is required
only for the explicit npm run test:database:local alternative.
Record the exact versions used during onboarding:
git --version
node --version
npm --version
python --version
On Windows, py --version may be used if python is not on PATH.
Windows PowerShell: Commands in this guide use portable
npm/npxsyntax. If PowerShell attempts to runnpm.ps1ornpx.ps1and blocks it, usenpm.cmdornpx.cmdinstead. For this repository's Docker database verification, usenpm.cmd run test:database:local.
2. Clean clone and reproducible install¶
Clone the repository and install exactly the dependency graph recorded in package-lock.json.
git clone https://sdp.ms.wits.ac.za/git-push-pray/Sport-Analytics-Tool.git
cd Sport-Analytics-Tool
npm ci
When verifying an unmerged Pull Request from a clean clone, fetch the remote and switch to the branch named by that Pull Request before following the rest of this guide:
git fetch origin
git switch <pull-request-branch>
Use npm ci rather than npm install for clean-clone verification. npm ci fails if the lock file and package manifests do not agree, which is useful evidence that the repository can be installed reproducibly.
3. Create local environment files¶
Real .env files are ignored and must never be committed.
Windows PowerShell¶
Copy-Item apps/backend/.env.example apps/backend/.env
Copy-Item apps/frontend/.env.example apps/frontend/.env
macOS / Linux / Git Bash¶
cp apps/backend/.env.example apps/backend/.env
cp apps/frontend/.env.example apps/frontend/.env
Populate the required values using the shared development configuration. See Environment Variables for the authoritative variable list.
4. Backend database connection¶
The application database is hosted on PostgreSQL through Supabase. Use the session pooler on port 5432. ADR-003 records why the direct connection and transaction-mode pooler were rejected for this project.
A typical development value has the form:
DATABASE_URL=postgresql://postgres.<project-ref>:<password>@<pooler-host>:5432/postgres
Use the current connection string supplied through the team's secret-sharing process rather than copying a host from an old document. Percent-encode reserved URL characters in the password.
TLS certificate verification uses the committed authority certificate:
apps/backend/certs/supabase-ca.crt
Do not disable certificate verification to bypass a connection error.
Verify the configured database connection:
npm run db:check --workspace=@sport-analytics/backend
A successful run reports the database name and server version and confirms prepared-statement support.
5. Supabase Auth configuration¶
The frontend needs:
VITE_SUPABASE_URL=https://your-project-ref.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=your-supabase-publishable-key
The backend needs:
SUPABASE_URL=https://your-project-ref.supabase.co
SUPABASE_PUBLISHABLE_KEY=your-supabase-publishable-key
# Optional locally; required to exercise account deletion.
# SUPABASE_SECRET_KEY=your-server-only-supabase-secret-key
The URL and publishable key are public project values. The optional secret key is backend-only and
must remain in the ignored environment file or deployment secret store. Never commit database
passwords, OAuth client secrets, user access tokens, Supabase secret keys or legacy service_role
keys.
Google OAuth is configured in the Google and Supabase dashboards. Its client secret remains outside the repository.
6. Build shared contracts¶
The frontend and backend both import @sport-analytics/contracts.
The complete root check builds contracts before repository-wide type-checking, but when running an isolated workspace check on a fresh installation it is safe to build contracts first:
npm run build --workspace=@sport-analytics/contracts
7. Run the applications¶
Start the backend in one terminal:
npm run dev:backend
Start the frontend in a second terminal:
npm run dev:frontend
The root dispatcher also supports npm run dev backend and
npm run dev frontend. Arguments after -- are forwarded to the selected
application, such as npm run dev frontend -- --host 0.0.0.0.
Default local endpoints:
- frontend:
http://localhost:5173 - backend health:
http://localhost:3000/api/v1/health - current user profile:
http://localhost:3000/api/v1/auth/me
A basic local smoke test is successful when the frontend loads and the backend health endpoint responds without a server error.
8. Repository checks¶
The normal pre-Pull-Request gate is:
npm run check
It currently runs, in order:
- required-file structure check;
- Prettier formatting check;
- ESLint;
- shared-contract build;
- TypeScript type-checking;
- unit/frontend/API/contract/deployment-helper tests;
- OpenAPI linting; and
- production builds for contracts, backend and frontend.
Useful individual commands:
npm run structure:check
npm run format:check
npm run lint
npm run typecheck
npm run test
npm run test:backend
npm run openapi:lint
npm run build
npm run test:backend runs all backend unit, API, and PostgreSQL integration tests with the
default disposable database runtime. Use npm run test:backend:local to run the same complete
backend workflow with Docker. The normal npm run test and npm run check commands remain
database-independent.
The extended CI/testing suite also includes Playwright browser/accessibility tests and coverage generation. See Testing.
9. Local PostgreSQL integration tests¶
Database integration tests exercise the application against a real PostgreSQL database. The default
npm run test:database command provisions a disposable PostgreSQL 16 cluster without Docker. The
steps below describe the optional Docker Compose workflow, which is useful for parity with CI.
From the repository root, run the default workflow with:
npm run test:database
The runner chooses an available loopback port, applies migrations and deterministic seed data, runs the database suite, and removes its temporary cluster after the tests finish.
Optional Docker workflow¶
Start Docker Desktop before using npm run test:database:local.
On Windows:
- Open Docker Desktop from the Start menu.
- Wait until Docker Desktop reports that the Docker engine is running.
- Open PowerShell in the repository and verify:
docker --version
docker compose version
docker info
On macOS, start Docker Desktop from Applications and wait for the engine to become available before running the same verification commands.
A different Docker-compatible runtime may be used if it provides the docker compose command used
by the repository.
Run the database integration suite¶
From the repository root:
npm run test:database:local
The command automatically:
- starts the repository-managed PostgreSQL 16 test container;
- waits until PostgreSQL is healthy;
- supplies
NODE_ENV=test; - supplies the local
DATABASE_URL_TEST; - resets the test schema;
- applies all migrations;
- loads the deterministic test seed; and
- runs the complete PostgreSQL integration suite.
No manual NODE_ENV change, .env.test file, hosted test database, Supabase test project or
shared database password is required for this normal workflow.
The local test database is:
postgresql://test_user:test_password@127.0.0.1:55432/sport_analytics_test
These are repository-defined test-only local credentials, not application secrets. Port
55432 is intentionally different from PostgreSQL's common 5432 port to reduce conflicts with
an existing local installation.
Development database versus test database¶
DATABASE_URL is the normal application development database connection. In the team's current
configuration it points to the Supabase-hosted PostgreSQL development database.
DATABASE_URL_TEST is used only by PostgreSQL integration tests and destructive test-database
commands.
The disposable Docker workflow supplies DATABASE_URL_TEST itself. It does not replace, reset or
modify DATABASE_URL.
The database safety guard requires NODE_ENV=test, requires the target database name to identify it
as a test database, and rejects a test connection that resolves to the same PostgreSQL host, port and
database as the configured development connection.
Statement execution bound¶
DATABASE_STATEMENT_TIMEOUT_MS bounds how long one PostgreSQL statement may run before the server
cancels it. It is optional: the backend defaults to 15000 milliseconds and the asynchronous worker
declares the same variable in its own configuration with a default of 60000. Both accept 1000 to
120000 milliseconds, and a value outside that range fails startup with the other environment
validation. It is a bound rather than a credential, so it belongs in .env and in deployment
configuration as a plain value.
The bound applies only to the application pools. Committed migrations, the operator scripts under
apps/backend/scripts/, and the PostgreSQL integration tests each open their own connections and
remain unbounded, because a corpus import or an index build legitimately runs far longer than any
application statement.
A cancelled statement returns 503 with the error code DATABASE_STATEMENT_TIMEOUT. The condition
is temporary and the request may be retried. The full contract is recorded in
database access.
Stop or remove the local test database¶
The container may remain running between test runs. Each local database-test run resets the schema, so tests do not depend on data left by the previous run.
Stop the container while keeping its disposable volume:
docker compose -f compose.test.yml down
Stop it and remove all local test-database data:
docker compose -f compose.test.yml down --volumes
The next npm run test:database:local command recreates the environment automatically.
Using a different test database¶
A manually managed database is another alternative to the default embedded and explicit Docker workflows.
A developer who already has a dedicated PostgreSQL test database may supply a safe
DATABASE_URL_TEST and run:
npm run db:test:reset --workspace=@sport-analytics/backend
npm run db:test:migrate --workspace=@sport-analytics/backend
npm run db:test:seed --workspace=@sport-analytics/backend
npm run test:database
The supported npm commands set NODE_ENV=test automatically.
See apps/backend/.env.test.example for the expected test configuration shape. Never use the
application development or production database for this workflow.
10. Documentation site¶
Create a Python virtual environment and install the documentation requirements.
Windows PowerShell¶
python -m venv .venv
.\.venv\Scripts\Activate.ps1
python -m pip install -r requirements-docs.txt
python -m mkdocs serve
macOS / Linux / Git Bash¶
python -m venv .venv
source .venv/bin/activate
python -m pip install -r requirements-docs.txt
python -m mkdocs serve
Preview URL:
http://127.0.0.1:8000
Before a documentation Pull Request, also run:
python -m mkdocs build --strict
The generated site/ directory is build output and must not be committed as part of normal documentation changes.
11. Optional Cricsheet data download¶
Historical T20/IT20 source data is acquired with the committed Python script:
python scripts/download_cricsheet_t20.py
On Windows, py scripts/download_cricsheet_t20.py is also valid.
The downloader uses the Python standard library and requires internet access. Downloaded archives, extracted match data and generated manifests are ignored by Git. See Cricsheet T20 data.
12. Importing the dataset¶
Once the source data has been downloaded, it is imported with:
npm run db:import --workspace=@sport-analytics/backend -- ../../data/cricsheet/matches
The path is relative to apps/backend, because npm runs a workspace script from that directory.
Options¶
| Flag | Effect |
|---|---|
--dry-run |
Reports how many match files would be imported and writes nothing. Reads every file, so it takes about a minute over the full corpus. |
--limit N |
Imports at most N matches, in the same stable order. Useful for a first run against a new database. |
What the importer does¶
Each match is ingested in its own transaction. A file that cannot be ingested rolls back on its own and the run continues; its reason is printed as it happens and summarised at the end, so a rejected file is never silently discarded.
Ingestion is idempotent. A match already present is recognised and skipped, so an interrupted run is resumed by issuing the same command again. Re-scanning matches already imported is fast.
A live progress line reports the count, the rate and an estimate of the time remaining. On completion the importer prints the number of files considered, imported, already present and rejected, and the resulting database totals.
Expected duration¶
The full corpus of 13,953 matches takes approximately twelve hours at roughly 0.3 matches per second. Most of that is round-trip latency to the hosted database rather than work; see issue #105.
A machine running the import must be prevented from sleeping, or the run stops silently while the clock continues. On Windows:
powercfg /change standby-timeout-ac 0
powercfg /change hibernate-timeout-ac 0
Restore these afterwards.
Before importing to a shared database¶
The importer writes to whatever DATABASE_URL points at. Before a full import against the shared development database, confirm with the team that the storage and the scope are agreed: the corpus is approximately 3.2 million deliveries.
For local development the smaller deterministic seed is usually what you want instead:
npm run db:seed --workspace=@sport-analytics/backend
That loads four fixtures chosen to exercise the awkward cases, and is described in database/seeds/README.md.
13. Optional local Supabase stack¶
A local Supabase stack is not required for normal onboarding. If the team deliberately chooses to use it, the Supabase CLI requires a Docker-compatible runtime and the work must be coordinated with the database workstream. Do not initialize or reset a shared environment without team agreement.
14. Common setup problems¶
npm ci fails because Node/npm is too old¶
Check:
node --version
npm --version
Use Node.js 20.19+ (20.x) or Node.js 22.12+ and npm 10+.
PowerShell blocks virtual-environment activation¶
You may run MkDocs without activating the environment by calling the environment's Python executable directly, or use a shell configuration permitted by your machine policy. Do not weaken organisation security controls merely to follow this guide.
Cannot find module '@sport-analytics/contracts'¶
Build the contracts workspace:
npm run build --workspace=@sport-analytics/contracts
The root npm run check already performs this build before type-checking.
Frontend reports missing Supabase variables¶
Populate VITE_SUPABASE_URL and VITE_SUPABASE_PUBLISHABLE_KEY in apps/frontend/.env.
Backend fails with invalid environment configuration¶
Populate SUPABASE_URL and SUPABASE_PUBLISHABLE_KEY in apps/backend/.env. The backend validates these at startup.
DATABASE_URL is not configured¶
Populate the current hosted PostgreSQL session-pooler connection string in apps/backend/.env.
Database hostname/connection fails¶
Use the current session pooler connection string rather than the direct database host. Do not copy a stale region-specific host from old notes.
self-signed certificate in certificate chain¶
Confirm that apps/backend/certs/supabase-ca.crt exists and that the documented migration/connection command is being used. Do not disable TLS verification.
Browser requests fail with CORS errors¶
The backend currently reads CORS_ORIGINS, not CORS_ALLOWED_ORIGINS. For local development, the default is http://localhost:5173.
npm run check reports formatting failures¶
Run:
npm run format
npm run format:check
Review the resulting diff before committing. Formatting should not be used to hide unrelated changes.
Docker command is not found¶
If PowerShell reports that docker is not recognised as a command, Docker Desktop is either not
installed or is not yet available on PATH.
Install Docker Desktop using the official Docker Desktop installation guide: https://docs.docker.com/desktop/
After installation, open a new terminal and verify:
docker --version
docker compose version
If Docker Desktop is already installed, start it and wait until the Docker engine is running.
Docker is required only for the explicit npm run test:database:local workflow. The default
npm run test:database workflow does not require Docker.
Docker cannot connect to the engine¶
Start Docker Desktop and wait until the Docker engine is running. Then verify:
docker info
Retry npm run test:database:local only after docker info succeeds.
Port 55432 is already in use¶
The repository deliberately uses port 55432 rather than the usual PostgreSQL port 5432.
If another process already uses 55432, stop that process before running the local database
workflow. Do not change the test workflow to point at an unknown existing database.
Database test safety check fails¶
Do not bypass the safety check. Confirm that the command is using a dedicated test database and that
DATABASE_URL_TEST does not resolve to the same PostgreSQL database as DATABASE_URL.
For the Docker workflow, do not manually set DATABASE_URL_TEST; run:
npm run test:database:local
Playwright cannot find a browser¶
Playwright requires its managed Chromium browser for the local end-to-end suite. On a fresh development environment, or after a Playwright upgrade, install it with:
npx playwright install chromium
On Windows PowerShell, use npx.cmd playwright install chromium if script execution blocks npx.
Then rerun:
npm run test:e2e
CI installs Chromium and its Linux dependencies with
npx playwright install --with-deps chromium.
MkDocs command is not found¶
Install documentation requirements inside the active virtual environment:
python -m pip install -r requirements-docs.txt
Then prefer python -m mkdocs ... so the command uses the intended Python environment.
15. Onboarding verification record¶
Issue #12 requires a second team member to follow this guide from a clean clone. The verifier must record:
- name;
- date;
- operating system;
- shell/terminal;
- editor/IDE used, if any;
- Git, Node.js, npm and Python versions;
- whether
npm cisucceeded; - whether environment setup was understandable;
- whether frontend/backend start commands worked;
- whether
npm run checksucceeded; - whether the MkDocs strict build succeeded;
- any unclear step or failure; and
- the final result after fixes.
The repository evidence template is evidence/validation/issue-12-onboarding-verification.md.
Related documentation¶
- Technology Stack
- Dependencies
- Testing
- Environment Variables
- Authentication and Authorisation
- Deployment Overview
AI Declaration¶
The preceding document was reviewed, reorganised and expanded with the assistance of ChatGPT-Web[GPT-5.6 Sol].