feat: implement the client routes that had no handler

Sixteen agents, one controller each, over every route the coverage test
reported as missing or wrong-verb. Route+verb coverage is now 516/522 (98.9%),
up from 90.8%.

Each handler was written against binary evidence rather than the audit's prose:
verb from the BestHTTP.HTTPMethods ordinal at the call site, response shape from
the issuing method's return type, request shape from whether the client uses
form fields, a raw JsonUtility body, or query params. Agents were told to skip
rather than stub, and several did.

New surface worth noting:

- Link host: actionlink create/get/consume and datalink get/put, previously
  unrouted entirely.
- Club roster reads: members, banned, requests, requests/search, members/search,
  each with the client's real sort/paging params and the wire row shape its
  reader expects (the banned row has no MembershipType field, so it isn't sent).
- Home clubhouse set/clear, club disband (soft, via the existing State column),
  and DELETE mainimage as its own action rather than a verb alias — the client
  parses the details envelope from it, so it is not status-only.
- Club chat threads, comment CRUD, keepsake collect/delete, progression-event
  xp boosts, image report and cheered/bulk, iOS StoreKit product reporting.

The six routes still missing all need storage that does not exist yet
(per-role club permissions, club additional-image slots, MinLevel,
ClubChatEnabled). Those are left for a single schema change rather than faked.

Also excludes DELETE /account/me from the endpoint contract probe. That route is
now a real, correctly-guarded account purge, and the probe walks every route
with one test player — so calling it destroyed the probe's own session and
turned one real event into 49 cascading foreign-key and 401 failures.
This commit is contained in:
Alexa
2026-07-28 09:11:26 +03:00
parent 90e069ee4b
commit 4b5086cdf1
21 changed files with 4474 additions and 370 deletions
+1
View File
@@ -161,6 +161,7 @@ Note: counts are approximate because several client URLs (`api/avatar/v3/saved`,
| GET | `api/inventions/v3/saved` | REAL | `InventionsController.Saved` — caller's own creations (SAVED list) |
| POST | `api/inventions/v3/save` | REAL | `InventionsController.Save` — creates a new `InventionEntity` (initial save) |
| POST | `api/inventions/v3/addversion` | REAL | `InventionsController.AddVersion` — appends `InventionVersionEntity`, bumps `CurrentVersionNumber` |
| POST | `remote-run/push-to-studio` | REAL | `InventionsController.PushToStudio` (also `roomserver/` alias) — Rec Room Studio remote-run handoff. Raw-JSON body `{SessionId, RoomId, SubRoomId, UnityAssetId, RoomData:{Filename,Hash,OwnershipProof}, SubRoomData:{…}, SavedByAccountId}`; stamps the pushed `RoomDataBlobEntity` with its room/sub-room, records `UnityAssetId` on the `RoomScene`, sets `Rooms.StudioSessionId`, keeps the push under `remoterun:{SessionId}` in `PlayerSettings`. Does NOT commit the live save (that stays `rooms/{id}/subrooms/{id}/data`). Replies with the flattened `RemoteRunDetails` |
### `api/Leaderboard/`