Architecture
How the Auto Tournament code is laid out, and how the parts talk to each other.
Auto Tournament is one repository, Auto-Tournament/auto-tournament, with two Yarn workspaces:
api/: the backend. Node.js 20, Express and TypeScript. It stores data in PostgreSQL and sends live updates with Socket.IO.client/: the web app. React, Vite and Material UI.
Other folders: docker/ (the Dockerfile and Compose files), tests/ (Playwright tests), scripts/ (test, release and docs scripts), docs/ (the generated API reference) and examples/discord-bot/ (an example bot that uses the API).
In the Docker image
The published image runs two processes, started by /app/start.sh:
- Node runs the API on port
3000inside the container. - Caddy listens on port
3069. It serves the built web app from/app/publicand forwards/apiand everything under it,/api-docsand everything under it,/socket.ioand everything under it, and/healthto Node.
If either process stops, the container stops, so Docker's restart policy can start it again. This is why the web app, the API and the WebSocket all use port 3069, and why PORT=3000 must not change.
In development
yarn dev starts the API with tsx watch on port 3000 and the Vite dev server on port 5173. Vite forwards /api, /socket.io and /map-images to the API. See Running locally.
The API
| Folder | What is in it |
|---|---|
api/src/routes/ | One Express router per area. routeTable.ts lists every core router and its path prefix, for example /api/matches. |
api/src/core/ | The game-neutral match flow: the scheduler, the allocation queue, match lifecycle and results. |
api/src/services/ | The logic: tournaments, brackets, players, ratings, sign-in settings, game packs. |
api/src/integrations/ | The game modules. registry.ts lists them; cs2/ is the CS2 module (servers, maps, veto, events, the fleet link), manual-report/ is manual reporting. |
api/src/modules/ | Code modules installed at runtime: the catalog, signature checks, the loader. |
api/src/middleware/ | auth.ts checks admin sessions and API tokens. serverAuth.ts checks the token that game servers send. |
api/src/config/ | Database connection and schema, Passport sign-in providers, and the OpenAPI setup. |
api/src/types/, api/src/utils/ | Shared types and helpers. |
Database
The schema is in api/src/config/database.schema.ts. On start, the API creates missing tables and adds missing columns with ALTER TABLE ... ADD COLUMN, derived from the schema itself. Changes that are more than a new column, such as a backfill, are hand-written steps in api/src/config/schemaMigrations.ts, each run once and recorded in schema_migrations. Game modules bring their own migrations (CS2: api/src/integrations/cs2/migrations.ts).
Brackets
Each tournament type has a bracket generator that implements IBracketGenerator (api/src/services/bracketGenerators/types.ts). The registry in bracketGenerators/index.ts maps types to generators:
- Single elimination, double elimination and round robin use
standardBracketGenerator, built on brackets-manager.js. - Swiss uses
swissBracketGenerator. Later rounds are paired byswissProgressionServicewhen a round is done. - Shuffle has no generator.
shuffleTournamentServicemakes the matches round by round.
To add a tournament type, write a generator and add it to the registry.
Game servers
The CS2 module drives servers through one driver (api/src/integrations/cs2/driver.ts), for Ready Up:
fleet, Ready Up. The server keeps one outbound WebSocket to/api/fleet/ws(fleet/gateway.ts). Matches, settings and admins go out over it; state, events and round backups come back. The protocol is versioned JSON, described infleet/protocol/. csm machines use a second link (fleet/hosts/) for server lifecycle, failover and auto-scaling.
allocation.ts picks a free server for each ready match, and matchConfig.ts builds the match config it sends. The plugin side is described in Fleet mode.
The web app
| Folder | What is in it |
|---|---|
client/src/pages/ | One component per page, for example Teams.tsx, Matches.tsx and PlayerProfile.tsx. Routes are in App.tsx. |
client/src/components/ | Shared components, grouped by area. |
client/src/locales/ | Translations. English is the source. See Translating. |
API reference files
docs/API-REFERENCE.md and docs/openapi.json are generated from the routers. After you add, remove or change a route, run:
yarn docs:apiCI runs yarn docs:api:check and fails when the files are out of date.