diff --git a/PLAN.md b/PLAN.md index b8b28de..4c0c937 100644 --- a/PLAN.md +++ b/PLAN.md @@ -1300,6 +1300,42 @@ provided cert) at the contour caddy; prod VPN; rollback. card now shows each robot seat's per-game play-to-win **intent** + the ~40% target and, on the robot's turn, its deterministic **next-move ETA**. *Open edge:* a bilingual New Game (both en+ru offered) would show two "Scrabble" buttons — left as the owner's chosen naming; disambiguate if it bites. + - **Contour-verification follow-ups** (round 6, from live testing) — **shipped & deployed:** profile drops + the hint-balance line; no mobile tap-flash on a board cell (`-webkit-tap-highlight-color`); variant + display names keyed by the game's **alphabet**, not the UI language (english → "Scrabble", + russian_scrabble → "Скрэббл", both unlocalized so they never collide; erudit localized), and the in-game + title shows the variant name; **chat & nudge are mutually exclusive by turn** (message field on your + turn, nudge on the opponent's, grey "awaiting reply" caption during the cooldown), with chat enforced + server-side to your own turn (`ErrChatNotYourTurn`); the **nudge cooldown resets** once the player has + moved or chatted since the last nudge (`game.LastMoveAt` + last chat vs last nudge; the UI mirrors it); + the **About** screen got localized titles + a rules link + the random/friends sections, and the app + **version comes from `git describe`** (Vite define `__APP_VERSION__` ← Docker build-arg in the deploy + step, default "dev"); the **quick-game buttons** became lobby-style plaques — name + flag (🇺🇸/🇷🇺 + a + bundled minimalist USSR-flag SVG) + a one-line rules summary (bag size, the ё rule, bonus differences + from the engine rulesets) + the 24h move-limit beneath; two follow-up fixes (pin the nudge right when + available; redraw the USSR emblem as a thin schematic hammer & sickle); **#3 drag-reorder of rack tiles** + with a visual gap (the dragged tile lifts out, the rest slide to open a slot; `reorderIndices` + unit-tested; only with no pending tiles); and the **persistence backend foundation** (#4/#5/#6): a + `game_drafts` table (migration 00011) + raw-SQL store/service (`GetDraft`/`SaveDraft`) that, on every + committed move, clears the actor's own draft and resets any opponent's board draft whose cell the play + overlapped — 5 integration tests. + - **Stage 17 round 6 — REMAINING (next pass), designs ready:** + 1. **Persistence gateway slice + UI (#4/#5/#6).** *FB (lean):* `DraftRequest{game_id, json}` (save) + + a game-id request (get) + `DraftView{json}` — one string field; the client serializes/deserializes + `{rack_order, board_tiles}` itself (no FB tile array). Regen Go (`make -C pkg fbs`) + TS + (`pnpm codegen`); flatc is pinned **23.5.26** (the local one matches). *Gateway* forwards the JSON as + `json.RawMessage` (no double-encode). *REST:* `GET`/`PUT /games/:id/draft` (decodes `game.Draft`). + *UI:* save the rack order (#4) and board draft (#6) on change (debounced) and restore on load + (next to `gameState`); **#5** — allow placing tiles on the opponent's turn (relax the `isMyTurn` + gate on placement only; the evaluate-preview and Make-move stay your-turn-only, so an off-turn draft + is position-only — never scored/submitted). + 2. **Landing + `/app/` move (#16–20).** An extra Svelte page at `/`, the game SPA under `/app/` (Vite + `base` conditional: `/app/` for web, `./` for Capacitor); the gateway serves the landing at `/` and + the SPA at `/app/*`; a bundled Telegram logo (from `.claude/telegram-logo.svg`, **copied into + `ui/public/`, the reference itself not committed**) linking to the per-language t.me bot (ru + `Erudit_Game` / en `Scrabble_Game`); theme + language switchers reusing the app stores; reuse the + `aboutContent` copy. **Note:** moving the game to `/app/` means the Telegram Mini App URL must point + to `/app/`. ## Deferred TODOs (cross-stage)