docs: document game history and update the TODO
- Backend README: DATABASE_URL, VALKEY_URL, the new routes and how the backend behaves when Postgres or Valkey is down - TODO: drop the fixed spectator and memory bugs, add game history on mobile, a page with all games, single-instance limits, backups and the new .env variables - Spec marked as implemented, all tasks ticked
This commit is contained in:
parent
3bb151dbed
commit
b94c9336dd
28
TODO.md
28
TODO.md
@ -18,6 +18,13 @@ The web app logs in with Keycloak; the mobile app still uses the legacy `?userKe
|
||||
- [ ] Delete the unused copy of the WebSocket client in `apps/mobile/src/rtmt`
|
||||
- [ ] Test on a device
|
||||
|
||||
### Game history on mobile
|
||||
|
||||
The web app has game history (see `docs/specs/game-history`); the mobile app needs Keycloak login first.
|
||||
|
||||
- [ ] Ongoing-game banner, live and popular games, recent games on the home screen
|
||||
- [ ] Move list and looking back during a live game; replay of finished games
|
||||
|
||||
### After the mobile release
|
||||
|
||||
- [ ] Turn off `LEGACY_USERKEY_AUTH` once old app versions are no longer in use; this also removes `/register`
|
||||
@ -25,10 +32,18 @@ The web app logs in with Keycloak; the mobile app still uses the legacy `?userKe
|
||||
### Later
|
||||
|
||||
- [ ] Let guests turn their guest user into an account without changing identity (Keycloak required action)
|
||||
- [ ] Stats and game history for logged in users (needs a database)
|
||||
- [ ] Statistics for logged in users (wins, losses), now that games are saved
|
||||
- [ ] Social logins (Keycloak identity providers)
|
||||
- [ ] Restrict the Keycloak admin console in production
|
||||
|
||||
## Game history
|
||||
|
||||
- [ ] A page with all of a user's games (the home page shows the last 3)
|
||||
- [ ] Show games of deleted accounts differently, once accounts can be deleted
|
||||
- [ ] Live game state, previews and spectators assume a single backend instance; share them (e.g. Valkey pub/sub)
|
||||
before running more than one
|
||||
- [ ] If Valkey is unreachable when the backend starts, live games are not restored until the next restart
|
||||
|
||||
## Deployment
|
||||
|
||||
- [ ] Build the backend and frontend images from the repo root in CI:
|
||||
@ -37,6 +52,9 @@ The web app logs in with Keycloak; the mobile app still uses the legacy `?userKe
|
||||
- [ ] Deploy Keycloak (`apps/.env` with `KEYCLOAK_DB_PASSWORD`, `KEYCLOAK_ADMIN_PASSWORD`,
|
||||
`KEYCLOAK_HOSTNAME=https://auth.playmancala.app`) and reload nginx with the new `auth.playmancala.app` block
|
||||
- [ ] Deploy the backend before the web app; the new web app needs token auth on the server
|
||||
- [ ] Back up the Postgres volume (Keycloak and saved games), e.g. a daily `pg_dumpall`
|
||||
- [ ] Set `MANCALA_DB_PASSWORD` and `POSTGRES_PASSWORD` in `apps/.env` on the server; the `postgres` volume replaces
|
||||
`keycloak-db`, so Keycloak starts with a fresh database there
|
||||
|
||||
## Security
|
||||
|
||||
@ -48,16 +66,10 @@ The web app logs in with Keycloak; the mobile app still uses the legacy `?userKe
|
||||
|
||||
## Bugs
|
||||
|
||||
- [ ] `GameStoreImpl.getSpeactatingGameIdsByUser` loops with `for...in` over an iterator, so it never finds
|
||||
anything and spectators are never removed on disconnect; use `for...of`
|
||||
- [ ] Finished and abandoned games are never removed from `gameStore` (`deleteGame` only removes the user
|
||||
mappings), so they stay in memory until restart
|
||||
- [ ] `PitAnimator.animatePit`: `previousPitIndex > 0` should be `>= 0`; a one-stone move from pit 0 does not
|
||||
empty that pit during the animation
|
||||
- [ ] `PitAnimator.dispose` removes a newly bound function, so the theme listener is never removed
|
||||
- [ ] Sowing puts stones into the opponent's store; check against the intended Mangala rules and add a test
|
||||
- [ ] `MatchMaker.join` does not check whether the player is already in a game
|
||||
- [ ] `GameManager.startGame` sends the connection info twice
|
||||
- [ ] `onGameError` broadcasts an `Error`, which serializes to `{}`
|
||||
|
||||
## Maintenance
|
||||
@ -65,7 +77,7 @@ The web app logs in with Keycloak; the mobile app still uses the legacy `?userKe
|
||||
- [ ] The web and mobile apps duplicate components and stores; move shared code into `packages/core`
|
||||
- [ ] Mixed lockfiles: `packages/*` and `apps/mobile` have both `yarn.lock` and `package-lock.json`
|
||||
- [ ] Align TypeScript and Jest versions across packages
|
||||
- [ ] Tests for `GameManager`, `MatchMaker` and `PitAnimator`
|
||||
- [ ] Tests for `MatchMaker` and `PitAnimator`
|
||||
- [ ] CI that runs the tests
|
||||
- [ ] Pre-existing type errors: 4 in the frontend, 11 in mobile; the frontend has no `tsconfig.json`, so nothing
|
||||
type-checks it
|
||||
|
||||
@ -47,3 +47,25 @@ User ids of Keycloak users are the token subject prefixed with `kc:`.
|
||||
| `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 |
|
||||
|
||||
## Saved games and live games
|
||||
|
||||
Finished games are saved in Postgres; live games are copied to Valkey after every change and restored when the
|
||||
backend starts, so a restart or deploy does not end them. The design is in `docs/specs/game-history`.
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `DATABASE_URL` | `postgres://mancala:mancala@localhost:5433/mancala` | Saved games; migrations run on startup |
|
||||
| `VALKEY_URL` | `redis://localhost:6379` | Live game state and short-lived caches |
|
||||
|
||||
The backend keeps running when either is down: games are still played, finished games are saved once Postgres is
|
||||
back, and lists are served without the missing data.
|
||||
|
||||
| Route | Auth | Response |
|
||||
|---|---|---|
|
||||
| `GET /game/:id` | – | A live game, or `{ status: "finished", record }` |
|
||||
| `GET /games/popular?limit=5` | – | `{ kind: "live" \| "finished", games }` |
|
||||
| `GET /games/me/active` | Bearer token | `{ game }` or `{ game: null }` |
|
||||
| `GET /games/me?limit=3` | Bearer token | `{ games }`, newest first |
|
||||
|
||||
Tests use Docker (testcontainers) for Postgres and Valkey.
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
# Game history and live games: requirements
|
||||
|
||||
Status: approved, in development (branch `feature/game-history`, based on `feature/keycloak-auth`).
|
||||
Status: implemented on branch `feature/game-history` (based on `feature/keycloak-auth`).
|
||||
Scope: backend and web app. The mobile app is out of scope (see `TODO.md`).
|
||||
|
||||
## Goals
|
||||
|
||||
@ -22,4 +22,4 @@ Work through the tasks in order; each ends with its tests passing and a commit.
|
||||
rejection message.
|
||||
- [x] 10. **Live game history**: `MoveList`, review mode with `ReviewBanner` and keyboard, timeout countdown.
|
||||
- [x] 11. **Replay**: `ReplayView` with controls, speed, timeline, `?move=`, own-side orientation, duration.
|
||||
- [ ] 12. **End to end and docs**: Chrome tests from `design.md`, README and `TODO.md` updates.
|
||||
- [x] 12. **End to end and docs**: Chrome tests from `design.md`, README and `TODO.md` updates.
|
||||
|
||||
Loading…
Reference in New Issue
Block a user