From cdc2bf580ef2f9df2da8cd4bb40e4ea12b7e624c Mon Sep 17 00:00:00 2001 From: wtclaude Date: Sun, 19 Jul 2026 22:35:35 -0500 Subject: [PATCH] docs(android): record M4 (player self-service & game data) landed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Marks M4 done in android/PLAN.md §9 build-progress and flips the top status to "M0–M4 landed; M5 (design pass) next." Documents the account self-service (/auth/me/account*), game-account linking, and text-only own game-data screens shipped in RunicGateway/Android-app#9 — a pure consumer of the existing bearer API, no backend/protocol change. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01NgyHnrNa8WwG3doxvxjuCr --- android/PLAN.md | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/android/PLAN.md b/android/PLAN.md index dd9ec1b..6bb3991 100644 --- a/android/PLAN.md +++ b/android/PLAN.md @@ -1,6 +1,6 @@ # Android App — Plan -Status: **M0–M3 landed; M4 (player self-service & game data) next.** This document is the +Status: **M0–M4 landed; M5 (design pass) next.** This document is the design contract for the `RunicGateway/Android-app` repo. It was written before implementation so the API changes it depends on could be landed in `website/` and `docs/` first. The authoritative API reference is the committed OpenAPI spec at `website/server/swagger/swagger-output.json` (regenerated @@ -75,7 +75,30 @@ plain credential `401`), the `SessionManager` lifecycle over a fake store, and t > so an app-lock is a UX layer, not a security requirement, and adding it in the functional pass would > widen scope without changing the data flow. Revisit as an opt-in setting during M6. -**M4 (functional pass) and M5 (design pass) remain.** +✅ **M4 — player self-service & game data** (2026-07-19, `RunicGateway/Android-app#9`, functional Kotlin +pass): the signed-in player surface, all as a pure consumer of the existing bearer-gated API. +**Account self-service** over the role-agnostic `/auth/me/account*` (§6.4) — 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 from `has_password`), TOTP +**setup → scan → enable** (the `data:` QR is base64-decoded to a bitmap in-app) / disable-by-code, and +list/unlink SSO identities — each mutation folding its `ApiResult` into a section-scoped, localized +banner (§7). **Game-account linking** (§6.3) — the in-game `[link` one-time code (`POST +/player/shard/link`) plus the 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; and 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. The 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 are hand-authored + +spec-aligned (as recorded for M1); 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. +**No backend/API change** — the `/auth/me/*` and `/player/shard/*` surfaces the app consumes were the +§8 prerequisites, already landed. + +**M5 (design pass) remains.** **Prerequisite progress (§8):** all v1 prerequisites are **done** (2026-07-19) — ✅ password reset (item 2; website#75 + docs#8), ✅ role-agnostic `/auth/me/*` self surface (item 1; website#76 + docs#10), -- 2.49.1