- accounts.flagged_high_rate_at baked into the R1 baseline (no prod data; the
contour schema is wiped after merge); jet regenerated — the regen also picks
up the previously missing game_drafts/game_hidden models.
- account.Store: FlagHighRate (set-once), ClearHighRateFlag, the flag in
GetByID/ListUsers and a ListFlaggedHighRate review queue.
- New internal/ratewatch: ingests the gateway rejection reports, keeps a
bounded in-memory episode window for the console and applies the
conservative auto-flag (1000 rejected / 10 min, BACKEND_HIGHRATE_FLAG_*).
- POST /api/v1/internal/ratelimit/report (network-trusted, like
sessions/resolve).
- Admin console: Throttled page (episodes + flagged accounts), a high-rate
badge in the user list, the marker + operator clear action on the user card.
- Tests: ratewatch unit suite, report-route handler test, renderer cases,
integration coverage for the store round-trip and the console flow.
Complete the client-side draft feature on top of the shipped backend
foundation (the game_drafts store/service):
- FB: DraftRequest{game_id,json} + DraftView{json} (a draft get reuses
GameActionRequest); regenerated committed Go + TS bindings.
- Backend REST: GET/PUT /games/:id/draft, a draftDTO
(rack_order/board_tiles) mapped to game.Draft.
- Gateway: draft.get/draft.save transcode forwarding the composition
JSON verbatim (json.RawMessage both ways -- no double-encode).
- UI: debounced save of the rack order + board tiles and restore on
load (lib/draft.ts), plus #5 -- tiles may be arranged on the
opponent's turn (placement relaxed; the preview and Make-move stay
your-turn-only, so an off-turn draft is position-only).
Tests: backend handler validation, gateway pass-through round-trip, UI
draft/codec units, and a draft-restore e2e.