Stage 7 (wip): docs bake + stage renumber (insert UI Stage 8, shift +1)
- PLAN.md: new Stage 8 (UI social/account/history); Telegram->9, Admin->10, Linking->11, Polish->12; tracker + Stage 7 refinements; split the Stage 6 'wired in Stage 7' note between 7 and 8 - ARCHITECTURE: promote ui to current (slice scope, board-replay, codegen, theming, mock) - FUNCTIONAL(+ru): client-app section with the Stage 7/8 split - README + ui/README + CLAUDE.md: UI build/run/test, codegen, pnpm notes - bumped Stage 8-11 refs (+1) across docs and code comments
This commit is contained in:
+21
-10
@@ -24,9 +24,20 @@ Three executables plus per-platform side-services:
|
||||
administration. Embeds the **`scrabble-solver`** engine **as a library,
|
||||
in-process** — there is no per-game container. The only network consumer of
|
||||
`backend` is `gateway` (plus platform side-services over an internal API).
|
||||
- **`ui`** *(planned)* — pure-HTML5 client (plain Svelte + Vite, static build).
|
||||
Talks to `backend` only through `gateway`. Embeddable in platform webviews;
|
||||
packageable to native (iOS/Android) via Capacitor.
|
||||
- **`ui`** — pure-HTML5 client (plain Svelte 5 + TypeScript + Vite, static build;
|
||||
no SvelteKit). Talks to `backend` only through `gateway` over Connect-RPC +
|
||||
FlatBuffers, with the edge TS bindings generated from the **same** `edge.proto`
|
||||
and `scrabble.fbs` and committed under `ui/src/gen/`. The **playable slice**
|
||||
(Stage 7) covers auth, "my games", auto-match, the board (play/pass/exchange/
|
||||
resign), hint, word-check, chat/nudge, the live stream, i18n (en/ru) and a profile
|
||||
view; the social/account/history surfaces follow in Stage 8. There is no board on
|
||||
the wire — the client **reconstructs the 15×15 board by replaying the move
|
||||
journal** (§9.1) and renders board, tiles, premium squares and effects as pure
|
||||
CSS + Unicode (no image/font/SVG assets). Tiles are placed by Pointer-Events drag
|
||||
or tap; a CSS-token theme is light/dark and Telegram-themeParams-ready; navigation
|
||||
is a hash router and the session token is held in memory + IndexedDB. A build-flagged
|
||||
in-memory mock transport (`pnpm start`) runs the whole slice with no backend.
|
||||
Embeddable in platform webviews; packageable to native (iOS/Android) via Capacitor.
|
||||
- **`platform/<name>`** *(planned)* — per-platform side-services (Telegram bot
|
||||
first): deep-link invites and platform-native push notifications. They talk
|
||||
to `backend` over an internal API.
|
||||
@@ -108,7 +119,7 @@ arrive from a platform rather than completing a mandatory registration).
|
||||
TTL, ≤ 5 attempts) is sent through a `Mailer` seam (an SMTP relay, or a
|
||||
development log mailer when none is configured) and, once verified, attaches a
|
||||
confirmed email identity. An email already confirmed by **another** account is
|
||||
refused — adopting it would be a merge, which Stage 10 owns. Accounts and
|
||||
refused — adopting it would be a merge, which Stage 11 owns. Accounts and
|
||||
identities use application-generated **UUIDv7** primary keys.
|
||||
- **Linking** is initiated from an authenticated profile: choose a platform →
|
||||
complete that platform's web-auth confirm → attach the identity to the
|
||||
@@ -140,7 +151,7 @@ Key points:
|
||||
word-check tool through `Registry.Lookup`.
|
||||
- **Dictionary versioning — pin per game.** A game records the `dict_version` it
|
||||
started on and finishes on that version; new games use the latest. Multiple
|
||||
versions may be resident at once. An admin reload *(planned, Stage 9)*
|
||||
versions may be resident at once. An admin reload *(planned, Stage 10)*
|
||||
registers a new version through `Registry.Load`; delivery is the DAWG file in
|
||||
the image / a volume mounted at the dictionary directory. (A future split of
|
||||
the solver into engine + dictionary generator with versioned artifacts is
|
||||
@@ -202,7 +213,7 @@ Key points:
|
||||
- **Word-check tool**: unlimited dictionary lookups against the game's pinned
|
||||
dictionary; each result offers a **complaint** (complainant, game, variant,
|
||||
dict_version, word, the disputed result, an optional note) that lands in an
|
||||
admin review queue *(admin side planned, Stage 9)*.
|
||||
admin review queue *(admin side planned, Stage 10)*.
|
||||
|
||||
## 7. Robot opponent
|
||||
|
||||
@@ -250,7 +261,7 @@ requires (there is no DM surface; chat is per-game).
|
||||
emits a **match-found** notification (§10), delivered over the live stream;
|
||||
`Poll` remains as a fallback for a client that is not currently streaming.
|
||||
- **Friends**: a **request → accept** graph (one `friendships` table) — add by
|
||||
friend list or internal ID now, by platform deep-link with Stage 8. Declining or
|
||||
friend list or internal ID now, by platform deep-link with Stage 9. Declining or
|
||||
cancelling removes the pending request; blocking someone severs an existing
|
||||
friendship.
|
||||
- **Block**: two independent **global** account toggles (`block_chat`,
|
||||
@@ -275,7 +286,7 @@ requires (there is no DM surface; chat is per-game).
|
||||
(confirm-code binding, see §4), **timezone** (drives the away window and the
|
||||
robot's sleep; user-editable), the daily **away window** and the block toggles —
|
||||
all editable through `account.UpdateProfile`. Linked platform accounts and merge
|
||||
are Stage 10.
|
||||
are Stage 11.
|
||||
|
||||
## 9. Persistence
|
||||
|
||||
@@ -337,7 +348,7 @@ does not cover.
|
||||
## 10. Notifications
|
||||
|
||||
Two channels: the **in-app live stream** (delivered from Stage 6) and
|
||||
**platform-native push** (out-of-app, via the platform side-service — Stage 8).
|
||||
**platform-native push** (out-of-app, via the platform side-service — Stage 9).
|
||||
The backend emits notification intents through an in-process hub
|
||||
(`internal/notify`, a `Publisher` seam installed on the game, social and lobby
|
||||
services); a single backend→gateway **gRPC server-stream** (`Push.Subscribe`,
|
||||
@@ -348,7 +359,7 @@ robot-driver and timeout-sweeper moves emit too), **chat-message** and **nudge**
|
||||
(from the social service), and **match-found** (from the matchmaker, §8). Event
|
||||
payloads are FlatBuffers-encoded by the backend and forwarded verbatim. A client
|
||||
that is not currently streaming falls back to the matchmaker's `Poll` for
|
||||
match-found. Out-of-app platform push (your-turn, nudge) is wired in Stage 8;
|
||||
match-found. Out-of-app platform push (your-turn, nudge) is wired in Stage 9;
|
||||
session-revocation events and cursor-based stream resume are deferred
|
||||
(single-instance MVP).
|
||||
|
||||
|
||||
+13
-3
@@ -9,6 +9,16 @@ the detail is authored.
|
||||
|
||||
## Domains
|
||||
|
||||
### Client app *(Stage 7 / 8)*
|
||||
The web/app client (Svelte + Vite) realizes these stories. The **playable slice**
|
||||
(Stage 7) covers signing in (guest or email), the "my games" lobby, starting an
|
||||
auto-match, playing the board (place tiles by drag or tap, pass, exchange, resign),
|
||||
the top-1 hint, the unlimited word-check with complaint, per-game chat and nudge,
|
||||
real-time in-app updates, switching interface language (en/ru) and theme, and a
|
||||
read-only profile. Managing friends and blocks, creating friend games (invitations),
|
||||
editing the profile, the statistics screen and the history/GCG viewer arrive in
|
||||
Stage 8.
|
||||
|
||||
### Identity & sessions *(Stage 1 / 6)*
|
||||
A player arrives from a platform (Telegram first), via email login, or as an
|
||||
ephemeral guest. The gateway validates the credential once and mints a thin
|
||||
@@ -17,7 +27,7 @@ session-only with restricted features (auto-match only; no friends, stats or
|
||||
history). While the app is open the client keeps a live stream and receives
|
||||
in-app updates in real time — the opponent's move, your turn, chat, nudges and a
|
||||
found match; out-of-app push (your turn, nudge) is delivered by the platform
|
||||
later (Stage 8).
|
||||
later (Stage 9).
|
||||
|
||||
### Accounts, linking & merge *(Stage 1 / 10)*
|
||||
First platform contact auto-provisions a durable account. From the profile a
|
||||
@@ -76,7 +86,7 @@ Edit language (en/ru), display name, timezone, the daily away window and the blo
|
||||
toggles, and bind an email by confirm-code: the backend emails a short code that,
|
||||
once entered, attaches the email to the account (an email already confirmed by
|
||||
another account cannot be taken — that is a merge, a later stage). Linked platform
|
||||
accounts and merge arrive in Stage 10.
|
||||
accounts and merge arrive in Stage 11.
|
||||
|
||||
### History & statistics *(Stage 3)*
|
||||
Finished games are archived in a dictionary-independent form and exportable to
|
||||
@@ -84,6 +94,6 @@ GCG. Statistics (durable accounts only): wins, losses, draws, max points in a
|
||||
game, and max points for a single move (the best play, which already includes
|
||||
every word it formed plus the all-tiles bonus).
|
||||
|
||||
### Administration *(Stage 9)*
|
||||
### Administration *(Stage 10)*
|
||||
Admin (Basic Auth at the gateway) reviews word complaints, manages dictionary
|
||||
versions, and inspects users/games.
|
||||
|
||||
+13
-3
@@ -8,6 +8,16 @@
|
||||
|
||||
## Домены
|
||||
|
||||
### Клиентское приложение *(Stage 7 / 8)*
|
||||
Веб/приложение-клиент (Svelte + Vite) воплощает эти истории. **Играбельный срез**
|
||||
(Stage 7) покрывает вход (гость или email), лобби «мои игры», старт авто-подбора,
|
||||
игру на доске (постановка фишек перетаскиванием или тапом, пас, обмен, сдача),
|
||||
top-1 подсказку, безлимитную проверку слова с жалобой, чат и nudge в партии,
|
||||
обновления в реальном времени, переключение языка интерфейса (en/ru) и темы и
|
||||
профиль только для чтения. Управление друзьями и блоками, создание дружеских игр
|
||||
(приглашения), редактирование профиля, экран статистики и просмотр истории/GCG
|
||||
появятся в Stage 8.
|
||||
|
||||
### Личность и сессии *(Stage 1 / 6)*
|
||||
Игрок приходит с платформы (сначала Telegram), через email-вход или как
|
||||
эфемерный гость. Gateway один раз валидирует доступ и выдаёт тонкий
|
||||
@@ -16,7 +26,7 @@ session-токен; backend сопоставляет его с внутренн
|
||||
статистики и истории). Пока приложение открыто, клиент держит живой стрим и
|
||||
получает обновления в реальном времени — ход соперника, ваш ход, чат, nudge и
|
||||
найденный матч; внеприложенческий push (ваш ход, nudge) платформа доставит
|
||||
позже (Stage 8).
|
||||
позже (Stage 9).
|
||||
|
||||
### Аккаунты, привязка и слияние *(Stage 1 / 10)*
|
||||
Первый контакт с платформы заводит постоянный аккаунт. Из профиля игрок
|
||||
@@ -76,7 +86,7 @@ push доставляется через платформу.
|
||||
confirm-коду: backend шлёт на почту короткий код, и после ввода email
|
||||
привязывается к аккаунту (email, уже подтверждённый другим аккаунтом, занять
|
||||
нельзя — это слияние, отдельный этап). Привязанные платформенные аккаунты и
|
||||
слияние появятся в Stage 10.
|
||||
слияние появятся в Stage 11.
|
||||
|
||||
### История и статистика *(Stage 3)*
|
||||
Завершённые партии архивируются в независимом от словаря виде и экспортируются
|
||||
@@ -84,6 +94,6 @@ confirm-коду: backend шлёт на почту короткий код, и
|
||||
макс. очков за партию и макс. очков за один ход (лучший ход, уже включающий все
|
||||
образованные им слова и бонус за все фишки).
|
||||
|
||||
### Администрирование *(Stage 9)*
|
||||
### Администрирование *(Stage 10)*
|
||||
Админ (Basic Auth на gateway) разбирает жалобы на слова, управляет версиями
|
||||
словаря, смотрит пользователей/игры.
|
||||
|
||||
Reference in New Issue
Block a user