feat(registry): admin player routes: search, read one account, restore, delete saves or the account #16

Merged
kblack0610 merged 1 commit from feat/registry-admin-players into main 2026-11-04 06:48:38 +00:00
Owner

Rewards-admin P1: the admin site can find a player, read everything kept for them, and restore or delete their saves or the whole account. No schema change. The page that uses these routes is P2.

What changed

  • deleteAccount(ctx, id, first) and deleteSaves(tx, id) come out of handleDeleteAccount; DELETE /api/v1/accounts/me and the admin delete run the same code.
  • restore(...) and restoreDone(...) come out of restoreSnapshot; the player's restore and the admin restore share them. The lease precheck outside the transaction is gone (the in-tx check does the same job); a refused restore of a running world now always answers 409 with holder and expires.
  • New admin routes (admin port only, adminplayers.go): GET /api/players?q=, GET /api/players/{account}, GET .../snapshots/{snapshot}, POST .../{characters|worlds}/{id}/restore, DELETE .../characters/{id} (soft), DELETE .../saves, DELETE /api/players/{account}.
  • Every admin player write adds one override_audit row, channel player, with the account id as the game. A delete row holds only counts, so it names no player data once the account is gone.
  • README: admin table and file list.

Assumptions

  • assumed: delete saves is a hard delete (owned worlds, characters, every snapshot body, leases held) and keeps memberships in other players' worlds, because the plan lists soft delete only for the single-character route, and a membership is not save data.
  • assumed: "online now" comes from a roster player's account field. The game's WebAdminRoster does not send that field yet, so the list stays empty until the game adds it (P4 work, unity-core-playground).
  • assumed: no PATCH /api/players/{account} (name, title) in P1. Title arrives with P5, and the plan lists the title edit in P7.

Checks

go vet ./... and go test -count=1 -v ./... in golang:1.24, against throwaway postgres:17.6-alpine and minio: 108 PASS, 0 FAIL. That includes 7 new tests (TestAdminPlayer*: sign-in gating and not on the public port, search by id, name and code, one account's view holds none of another's, presence from the roster, snapshot body and restore including a 409 on a moved head and on a leased world, delete character, delete saves, delete account plus their audit rows). The existing TestAccountDelete, TestCharacterSnapshots and TestWorldRestoreAndFork still pass on the extracted code. gofmt is clean. This repo has no PR CI.

Nothing removed beyond the inlined copies the extraction replaced.

https://claude.ai/code/session_01BALUC2TweemuC6uuKqXygb

Rewards-admin P1: the admin site can find a player, read everything kept for them, and restore or delete their saves or the whole account. No schema change. The page that uses these routes is P2. ## What changed - `deleteAccount(ctx, id, first)` and `deleteSaves(tx, id)` come out of `handleDeleteAccount`; `DELETE /api/v1/accounts/me` and the admin delete run the same code. - `restore(...)` and `restoreDone(...)` come out of `restoreSnapshot`; the player's restore and the admin restore share them. The lease precheck outside the transaction is gone (the in-tx check does the same job); a refused restore of a running world now always answers `409` with `holder` and `expires`. - New admin routes (admin port only, `adminplayers.go`): `GET /api/players?q=`, `GET /api/players/{account}`, `GET .../snapshots/{snapshot}`, `POST .../{characters|worlds}/{id}/restore`, `DELETE .../characters/{id}` (soft), `DELETE .../saves`, `DELETE /api/players/{account}`. - Every admin player write adds one `override_audit` row, channel `player`, with the account id as the game. A delete row holds only counts, so it names no player data once the account is gone. - README: admin table and file list. ## Assumptions - assumed: delete saves is a hard delete (owned worlds, characters, every snapshot body, leases held) and keeps memberships in other players' worlds, because the plan lists soft delete only for the single-character route, and a membership is not save data. - assumed: "online now" comes from a roster player's `account` field. The game's `WebAdminRoster` does not send that field yet, so the list stays empty until the game adds it (P4 work, unity-core-playground). - assumed: no `PATCH /api/players/{account}` (name, title) in P1. Title arrives with P5, and the plan lists the title edit in P7. ## Checks `go vet ./...` and `go test -count=1 -v ./...` in golang:1.24, against throwaway postgres:17.6-alpine and minio: 108 PASS, 0 FAIL. That includes 7 new tests (`TestAdminPlayer*`: sign-in gating and not on the public port, search by id, name and code, one account's view holds none of another's, presence from the roster, snapshot body and restore including a 409 on a moved head and on a leased world, delete character, delete saves, delete account plus their audit rows). The existing `TestAccountDelete`, `TestCharacterSnapshots` and `TestWorldRestoreAndFork` still pass on the extracted code. gofmt is clean. This repo has no PR CI. Nothing removed beyond the inlined copies the extraction replaced. https://claude.ai/code/session_01BALUC2TweemuC6uuKqXygb
deleteAccount and restore are extracted so the player's own routes and the
admin site share one path. Every admin player write is audited as channel
player with the account id as the game.

Claude-Session: https://claude.ai/code/session_01BALUC2TweemuC6uuKqXygb
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
kblack0610/bnb-game-servers!16
No description provided.