feat(m4): player self-service & game data #9

Merged
whitlocktech merged 1 commits from feat/m4-player-self-service into main 2026-07-20 03:45:15 +00:00
Member

M4 — Player self-service & game data (functional pass)

Implements M4 of docs/android/PLAN.md §6.3–§6.4: the signed-in player surface. Functional Kotlin pass only — placeholder Compose UI; the design pass is M5. No backend/API change — the app is a pure consumer of the existing bearer-gated /auth/me/* and /player/shard/* surfaces (the §8 prerequisites, already landed), so no Swagger regeneration.

What's in it

Account self-service over the role-agnostic /auth/me/account* (§6.4) — reworks the M3 AccountScreen stub into full self-service:

  • Change username (409 "taken" surfaced; a success re-validates the session so the shell reflects the new name at once).
  • Change / set password — the SSO-account "no current password" path keyed off has_password.
  • TOTP setup → scan → enable (the data: QR is base64-decoded to a bitmap in-app) / disable-by-code.
  • List / unlink SSO identities.
  • Each mutation folds its ApiResult into a section-scoped, localized banner.

Game-account linking (§6.3) — the in-game [link one-time code (POST /player/shard/link) plus hybrid signup (POST /player/shard/account, shown only when the public gameAccountSignup flag is set), and the linked-accounts list.

Own game data, text-only (§6.3):

  • Per-account character roster → a character sheet (attributes, vitals, resistances, best-first skills, equipment with AOS mods, and guild/governor standing chips — bare cliloc-number titles/item names are skipped, as the app ships no cliloc table, matching the website's CharacterSheet.jsx).
  • Player vendors (shops + listings) with recent sales.
  • The player's own houses (decay/IDOC).
  • Each per-account read carries its own load state, so a down shard degrades that one account to offline/retry (503) — or not-found (403) — without blocking the rest (§7).

Menu gains three PLAYER-access groups (My Characters / Vendors / Houses) revealed only when the session role is player; a PlayerGate sends a signed-out or server-side-demoted user home.

DTOs + the Retrofit interfaces are hand-authored + spec-aligned (as recorded for M1).

Tests (17 new, all green)

Account + player-shard DTO decode (hex serials, permissive objects, equipment mods) and the character-sheet title/skill display helpers (parity with CharacterSheet.jsx#displayTitles).

Verification

./gradlew lint test assembleDebug passes locally.

Local-build note: on a JDK 21 host, build with -Pksp.incremental=false (KSP incremental storage crash). CI runs JDK 17 and is unaffected.

Docs: docs/android/PLAN.md is updated in the docs/ repo to record M4 landed.


AI-assisted: authored with Claude Code (Opus). AI-authored commit carries a Co-Authored-By: Claude trailer per org policy.

🤖 Generated with Claude Code

## M4 — Player self-service & game data (functional pass) Implements **M4** of `docs/android/PLAN.md` §6.3–§6.4: the signed-in player surface. Functional Kotlin pass only — placeholder Compose UI; the design pass is M5. **No backend/API change** — the app is a pure consumer of the existing bearer-gated `/auth/me/*` and `/player/shard/*` surfaces (the §8 prerequisites, already landed), so no Swagger regeneration. ### What's in it **Account self-service** over the role-agnostic `/auth/me/account*` (§6.4) — reworks the M3 `AccountScreen` stub into full self-service: - Change **username** (409 "taken" surfaced; a success re-validates the session so the shell reflects the new name at once). - Change / **set password** — the SSO-account "no current password" path keyed off `has_password`. - **TOTP** setup → scan → enable (the `data:` QR is base64-decoded to a bitmap in-app) / disable-by-code. - List / **unlink SSO identities**. - Each mutation folds its `ApiResult` into a section-scoped, localized banner. **Game-account linking** (§6.3) — the in-game `[link` one-time code (`POST /player/shard/link`) plus hybrid signup (`POST /player/shard/account`, shown only when the public `gameAccountSignup` flag is set), and the linked-accounts list. **Own game data, text-only** (§6.3): - Per-account character **roster** → a **character sheet** (attributes, vitals, resistances, best-first skills, equipment with AOS mods, and guild/governor standing chips — bare cliloc-number titles/item names are skipped, as the app ships no cliloc table, matching the website's `CharacterSheet.jsx`). - Player **vendors** (shops + listings) with recent **sales**. - The player's own **houses** (decay/IDOC). - Each per-account read carries its **own** load state, so a down shard degrades that one account to offline/retry (`503`) — or not-found (`403`) — without blocking the rest (§7). **Menu** gains three **PLAYER-access** groups (My Characters / Vendors / Houses) revealed only when the session role is `player`; a `PlayerGate` sends a signed-out or server-side-demoted user home. DTOs + the Retrofit interfaces are hand-authored + spec-aligned (as recorded for M1). ### Tests (17 new, all green) Account + player-shard DTO decode (hex serials, permissive objects, equipment mods) and the character-sheet title/skill display helpers (parity with `CharacterSheet.jsx#displayTitles`). ### Verification `./gradlew lint test assembleDebug` passes locally. > Local-build note: on a JDK 21 host, build with `-Pksp.incremental=false` (KSP incremental storage crash). CI runs JDK 17 and is unaffected. > Docs: `docs/android/PLAN.md` is updated in the `docs/` repo to record M4 landed. --- **AI-assisted:** authored with **Claude Code** (Opus). AI-authored commit carries a `Co-Authored-By: Claude` trailer per org policy. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
wtclaude added 1 commit 2026-07-20 03:34:25 +00:00
feat(m4): player self-service & game data
All checks were successful
PR Checks / android-build (pull_request) Successful in 10m18s
d4f7fcb241
Account self-service over the role-agnostic /auth/me/account* surface
(change username/password, TOTP enroll/disable, linked SSO identities),
game-account linking ([link one-time code + hybrid signup gated on the
public gameAccountSignup flag), and text-only own game data: per-account
character roster -> character sheet (attributes/vitals/resistances/skills/
equipment + guild/governor standing), player vendors + recent sales, and
own houses (decay/IDOC).

Adds three PLAYER-access menu groups (My Characters/Vendors/Houses)
revealed only when the session role is player, with a PlayerGate that
sends a signed-out or server-side-demoted user home. Each per-account
read carries its own load state, so a down shard (503) degrades that
account to offline/retry without blocking the rest (7).

Pure consumer of the existing bearer API -- no backend/protocol change.
17 new JVM unit tests cover the account + player-shard DTO decode (hex
serials, permissive objects, equipment mods) and the character-sheet
title/skill display helpers.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr
whitlocktech approved these changes 2026-07-20 03:37:18 +00:00
whitlocktech scheduled this pull request to auto merge when all checks succeed 2026-07-20 03:37:32 +00:00
whitlocktech merged commit 2e1bea4220 into main 2026-07-20 03:45:15 +00:00
whitlocktech deleted branch feat/m4-player-self-service 2026-07-20 03:45:16 +00:00
Sign in to join this conversation.
No description provided.