mancala/apps/backend
Halit Aksoy 7239bbb6ed feat(backend): save every game and keep live games across restarts
- Games record start and move times, spectator peak and distinct count
- Games end as completed, left (the leaver loses), timeout (5 minutes
  offline on your turn while the opponent is online) or inactive (both
  offline for 30 minutes); everyone gets on_game_end
- Connection info carries offlineSince for the countdown
- A new game is rejected while the user has one in progress
- Live games are written to Valkey after every change and restored on
  startup; finished games are saved to Postgres with public ids, and
  saves that fail are kept and retried every 30 seconds
- Clients get a trimmed game without spectator ids
- Startup waits for Valkey, restores games, then accepts connections;
  migrations are retried while Postgres is unreachable
2026-10-16 00:18:33 +03:00
..
.vscode (refactor) change folder structure 2024-06-18 01:11:26 +03:00
src feat(backend): save every game and keep live games across restarts 2026-10-16 00:18:33 +03:00
tests feat(backend): save every game and keep live games across restarts 2026-10-16 00:18:33 +03:00
.gitignore (refactor) change folder structure 2024-06-18 01:11:26 +03:00
build_and_deploy.sh (refactor) change folder structure 2024-06-18 01:11:26 +03:00
Dockerfile build: use local mancala.js and @mancala/core packages 2026-10-14 02:09:05 +03:00
jest.config.js feat(backend): save finished games in Postgres 2026-10-16 00:11:12 +03:00
package.json feat(backend): keep live games and caches in Valkey 2026-10-16 00:14:07 +03:00
README.md build: use local mancala.js and @mancala/core packages 2026-10-14 02:09:05 +03:00
tsconfig.json feat(backend): authenticate WebSocket clients with Keycloak tokens 2026-10-14 01:52:07 +03:00
yarn.lock feat(backend): keep live games and caches in Valkey 2026-10-16 00:14:07 +03:00

Mancala Backend

This is the backend code for the Mancala project, written in Express.js.

Getting Started

Install Packages

yarn install

Start in Development Mode

yarn dev

Start in Release Mode

yarn build
yarn start

Development Dependencies

This package links the local packages @mancala/core and mancala.js. Build them first with yarn build:packages in the repo root.

Authentication

Clients log in with Keycloak (see apps/keycloak), either as a guest or with an account, and send the access token over the WebSocket right after connecting:

{ "channel": "auth", "message": { "token": "<Keycloak access token>" } }

The server answers on on_auth with the user ({ id, name, isGuest }) or on on_auth_error and closes the socket with code 4001. Other messages are ignored until the socket is authenticated, and connections that do not authenticate within 5 seconds are closed. Send auth again with the new token after refreshing it. User ids of Keycloak users are the token subject prefixed with kc:.

Variable Default Purpose
KEYCLOAK_ISSUER http://localhost:8080/realms/mancala Token issuer; must match the iss claim exactly
KEYCLOAK_JWKS_URL issuer + /protocol/openid-connect/certs Where to fetch signing keys, if the backend reaches Keycloak at a different address
KEYCLOAK_CLIENT_IDS mancala-web Comma-separated clients whose tokens are accepted
LEGACY_USERKEY_AUTH true Also accept old clients that connect with ?userKey=<uuid> and the /register endpoint. Turn off once no released client uses it, because a userKey is not a secret the server can check