Owner review-pass rework of the landing page:
- Rename the per-language Telegram link build var
VITE_TELEGRAM_LINK_EN/_RU -> VITE_TELEGRAM_GAME_CHANNEL_NAME_EN/_RU
(it carries a channel username; the landing builds https://t.me/<name> --
the same channels the connector posts to via TELEGRAM_GAME_CHANNEL_ID_*).
- Language switcher -> a globe icon dropdown (flags + names), saved + synced
to the app prefs.
- Theme switcher -> a sun/moon icon toggle, ephemeral (follows the system
scheme, no auto, never persisted) -- galaxy-game style.
- Drop the "Play in browser" CTA (no standalone-web onboarding yet).
Docs: FUNCTIONAL(+ru), PLAN, deploy + ui READMEs.
Close out Stage 17 round 6:
- Landing page at / — one Vite build with two entries (index.html = game
SPA, landing.html = a lightweight landing reusing the theme/i18n/
aboutContent leaf modules, not the app store).
- Move the web game SPA to /app/; the Telegram Mini App stays at /telegram/
(gateway webui.Handler(stripPrefix, indexName): landing at /, SPA at /app/
+ /telegram/). Per-language "Play in Telegram" link via new
VITE_TELEGRAM_LINK_EN/_RU build vars (button hides when unset).
- Cache headers: hash-named /assets/* immutable, HTML shells no-cache (the
go:embed zero modtime emitted no validators, so the client re-downloaded
the whole bundle every launch).
- Live-stream 15s abort fix: an immediate heartbeat on open + a 10s default
interval (the first tick at 15s raced the edge idle timeout -> reconnect
storm).
PLAN/ARCHITECTURE(§13)/FUNCTIONAL(+ru)/gateway+ui+deploy READMEs updated;
round 6 closed. Tests: gateway webui/connectsrv units, ui landing unit + e2e,
full e2e (60) green.
Live play now exchanges per-variant alphabet indices instead of concrete
letters (rack out; submit-play, evaluate, exchange, word-check in). The client
caches each variant's (index, letter, value) table behind
StateRequest.include_alphabet and renders the rack and blank chooser from it,
dropping the hardcoded value/alphabet tables. History, the durable journal and
GCG stay decoded concrete characters (ARCHITECTURE §9.1, unchanged).
- pkg/fbs: new AlphabetEntry + PlayTile; StateView.rack -> [ubyte] + alphabet;
StateRequest.include_alphabet; SubmitPlay/Eval tiles -> [PlayTile];
Exchange tiles + CheckWord word -> [ubyte] (committed Go + TS regenerated).
- engine: AlphabetTable + a cached per-variant codec (LetterForIndex/EncodeRack/
DecodeTiles/DecodeWord) + BlankIndex sentinel; Go parity test.
- backend server edge maps index<->letter (new thin game.Service.GameVariant);
game.Service domain methods, engine.Game and the robot keep one letter-based
play path. The gateway forwards indices verbatim (no alphabet table).
- ui: lib/alphabet.ts in-memory cache; codec encodes/decodes indices; premiums.ts
is geometry-only; the mock seeds a fixture table; the UI normalises display to
upper case (codec + cache), leaving placement/board/checkword unchanged.
Parity moved to the Go engine.AlphabetTable test; premiums.ts loses its value
tables. Discharges TODO-4.
Wire the deferred Stage 7 surfaces end-to-end (UI -> gateway transcode ->
backend REST -> existing domain services): friends (incl. one-time friend
codes), per-user blocks, friend-game invitations, profile editing + email
binding, the statistics screen, and the in-game history + GCG export.
Friends gain two add paths (interview decision, a deliberate plan change):
one-time 6-digit codes (friend_codes table, 12h TTL, single-use, rate-limited
redeem); and play-gated requests (shared game required) where an explicit
decline is permanent, an ignored request lapses after 30 days, and a code
bypasses a decline. Migration 00006 widens friendships_status_chk and adds
friend_codes.
Lobby notification badge is poll + push: a new generic `notify` event drives
it live; the client polls on open/focus. Language stays a single Settings
control that writes through to the durable account's preferred_language. GCG
export is finished-only (game.ErrGameActive) and shares/downloads the .gcg file.
Tests: backend unit + inttest (friend gate/decline/code, ListInvitations,
GetStats, GCG gate), gateway transcode round-trips + notify constructor, UI
vitest (codecs, win-rate, share choice) + Playwright social specs. Docs: PLAN
(Stage 8 done + refinements + TODO-5), ARCHITECTURE, FUNCTIONAL(+ru), UI_DESIGN,
TESTING, module READMEs.