7.4 KiB
7.4 KiB
TODO
Auth
Mobile login with Keycloak (phase 5)
The web app logs in with Keycloak; the mobile app still uses the legacy ?userKey= login.
- Add a
mancala-mobilepublic client toapps/keycloak/realm/mancala-realm.json(PKCE S256, redirectcom.mancala_mobile://callback) and toKEYCLOAK_CLIENT_IDSfor the backend - Add
react-native-app-authwith the redirect scheme set up for Android and iOS - Log in as a guest on first launch (
guest=true), withoffline_access; keep tokens in MMKV - Connect with
rtmt.connectWebSocket(url, getToken)instead of?userKey=(apps/mobile/src/App.tsx) and callreauthenticateafter refreshing the token - Log in / sign up / log out in the app, player names on the game screen (
getPlayerDisplayNamein core) - Decide whether guests may skip the browser tab on first launch (would need a custom grant type in the Keycloak extension)
- 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_AUTHonce old app versions are no longer in use; this also removes/register
Later
- Let guests turn their guest user into an account without changing identity (Keycloak required action)
- Statistics for logged in users (wins, losses), now that games are saved
- Social logins (Keycloak identity providers)
- Keycloak email theme in the game's look (password reset emails still use Keycloak's)
- Login pages follow the system color scheme; they could follow the theme chosen in the app instead
- 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
Game clock
See docs/specs/game-clock.
- Other time controls or time added per move; a long move animates on the next player's time
- Clocks in the home page's live game previews and in the ongoing-game banner
- Try the mobile clocks on a device; only the type check and the bundle were run
Game bot
See docs/specs/game-bot.
- Play against the bot without a connection (a bot in the TypeScript engine on the device)
- Keep bot games apart once there are statistics or ratings
- Hints or move analysis for players, with the same search
- Rebuild
MancalaGameonPosition, or usePositionto check moves before running them (see Security) - Tune the levels from real games (
games.botholds each game's level, strength and seed) - Try the bot on a mobile device; only the type check and the bundle were run
Tutorial
See docs/specs/tutorial.
- Lessons and hints in the mobile app, once it has the new design (it has the rules screen)
- Hints that look ahead, e.g. a warning when a move lets the opponent capture (the bot's search could do it)
- Strategy lessons beyond the rules
- Tutorial progress per account instead of per device
- If the end-of-game rule changes (Game rules below), update
RuleEndOfGameText2inen.tsandtr.ts
Web redesign
See docs/specs/web-redesign.
- Bring the new design to the mobile app (themes, board, game screen)
- A rematch button on the game-over card (the design has one; there is no rematch yet)
Deployment
- Build the backend and frontend images from the repo root in CI:
docker build -f apps/backend/Dockerfile .anddocker build -f apps/frontend/Dockerfile . - Pass
--build-arg KEYCLOAK_URL=https://auth.playmancala.appwhen building the frontend image - Deploy Keycloak (
apps/.envwithKEYCLOAK_DB_PASSWORD,KEYCLOAK_ADMIN_PASSWORD,KEYCLOAK_HOSTNAME=https://auth.playmancala.app) and reload nginx with the newauth.playmancala.appblock - Deploy the backend before the web app; the new web app needs token auth on the server
- The backend is now Java (Quarkus, see
docs/specs/quarkus-backend); the compose file passes the database asDATABASE_JDBC_URL/DATABASE_USERNAME/DATABASE_PASSWORDbuilt from the sameMANCALA_DB_PASSWORD, soapps/.envneeds no change. It reads the Node backend's database and live games, so it can replace it (and be rolled back) without ending games - Release the mobile update with the game clock before or with the backend: older app versions do not show the
clock and do not handle
on_game_end, so a game they lose on time does not end for them - Back up the Postgres volume (Keycloak and saved games), e.g. a daily
pg_dumpall - Set
MANCALA_DB_PASSWORDandPOSTGRES_PASSWORDinapps/.envon the server; thepostgresvolume replaceskeycloak-db, so Keycloak starts with a fresh database there - Last step: publish a new
mancala.jsto npm (it is at0.0.2-beta.3from 2022), so the published engine skips the opponent's store when sowing. The apps do not need it; they usepackages/mancala.jsthroughlink:
Security
- Move the Android signing passwords out of
apps/mobile/release_android.sh(committed inbb1c750) into~/.gradle/gradle.propertiesor environment variables, and consider resetting the upload key - Add
apps/mobile/mancala-upload-key.jksto.gitignore(onlyandroid/app/mancala-upload-key.jksis ignored) - Validate moves before running them instead of treating every invalid move as a crash: each one writes a
file to
crashes/and is broadcast to the players (GameManager.onGameError, kept as it was in the Node backend)
Game rules
- Decide who gets the remaining stones when a move empties the opponent's side (e.g. a capture takes their last
stones). Now the player whose side is empty always gets the other side's stones (
GRClearBoardAtEnd), even when the opponent emptied it; some Mangala rules give them only to a player who emptied their own side. Analyse the rule first, then decide
Bugs
PitAnimator.disposeremoves a newly bound function, so the theme listener is never removedonGameErrorbroadcasts{}instead of the error (the Java backend sends{}on purpose, as the Node backend did)
Maintenance
- The web and mobile apps duplicate components and stores; move shared code into
packages/core - Mixed lockfiles:
packages/*andapps/mobilehave bothyarn.lockandpackage-lock.json - Align TypeScript and Jest versions across packages
- Tests for
MatchMaker;PitAnimatoris only tested for the first frame of a move - CI that runs the tests (the backend's need a JDK 25 and Docker)
- The rules exist twice, in
packages/mancala.jsand in the backend's Java port; a parity test keeps them alike, but every rule change has to be made in both - Pre-existing type errors: 1 in the frontend (
react-dom/client), 11 in mobile; the frontend has notsconfig.json, so nothing type-checks it