Stage 17 #4: enrich the out-of-app your-turn push + add game-over
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 12s
CI / ui (pull_request) Successful in 34s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m20s

The Telegram 'your turn' notification now names the opponent and recaps their last
move (voiced as the opponent: «{name}: my move — «WORD». Score 120:95» for a scoring
play; a short 'swapped / passed, your turn' otherwise), and a new game-over
notification reports the result + final score when a game ends by any path (closing
play, all-pass, resign, timeout). Scores are recipient-first (the reader's score
leads), 2-4 players (120:95:80).

- schema: YourTurnEvent gains opponent_name/last_action/last_word/score_line
  (appended, backward-compatible); new GameOverEvent{result, score_line}. Go + UI
  bindings regenerated (flatc 23.5.26 + pnpm codegen).
- backend: notify.YourTurn enriched + notify.GameOver; emitMove resolves the mover's
  name and emits per-recipient (your_turn to the next mover, game_over to every seat),
  with recipient-first score lines built in one place.
- gateway: game_over joins the out-of-app whitelist (routing.go).
- connector: render builds the enriched your_turn + game_over text per language (en/ru).
- tests: notify round-trip (enriched + game_over), emit (enriched fields + game_over to
  all seats / per-seat result), connector render (en/ru), routing; integration replay
  (play → your_turn with real name; resign → game_over) green.
- docs: ARCHITECTURE push catalog + out-of-app set, FUNCTIONAL (+ _ru), PLAN tracker.
This commit is contained in:
Ilia Denisov
2026-06-09 01:15:18 +02:00
parent 6956dad354
commit f166ff30fe
19 changed files with 657 additions and 52 deletions
+7 -2
View File
@@ -485,7 +485,12 @@ in-app only, so the actor gets no out-of-app push for their own move), **chat-me
friend-added, friend-declined, invitation or game-started; emitted on a friend-request,
on answering one (accept → friend-added, decline → friend-declined — to the original
requester, so a game screen watching that opponent re-derives its "add to friends" state,
Stage 17), and on an invitation create or its game start). Event payloads are FlatBuffers-encoded by
Stage 17), and on an invitation create or its game start). Stage 17 added **game-over** (emitted to every
seat from the same game commit when a game finishes — any path: a closing play, all-pass,
resign or timeout) and **enriched your-turn** so the out-of-app push reads in full: it now
also carries the mover's display name, their last action and the main word of a scoring play,
and a **recipient-first** running score line (e.g. `120:95:80`, the reader's score first).
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 and, for the lobby **notification
badge** (incoming friend requests + open invitations), the client polls on lobby
@@ -499,7 +504,7 @@ back to the interface language — and the `notifications_in_app_only` flag) and
button — only when the recipient has a Telegram identity and has not confined
notifications to the app, so the two channels never duplicate. The connector routes by
that language to the matching bot and renders the message in it. The out-of-app set is
your-turn, nudge, match-found and the invitation / friend-request notify sub-kinds;
your-turn, game-over, nudge, match-found and the invitation / friend-request notify sub-kinds;
the connector renders the message and skips the rest. Operator broadcasts
(`SendToUser` / `SendToGameChannel`, §10 admin) instead pick the bot by an
**operator-chosen** language in the console, unrelated to the recipient's login. Session-revocation events and
+6 -3
View File
@@ -41,9 +41,12 @@ sets their offered languages and is the bot their out-of-app notifications come
joined a game and has been idle past the retention window is garbage-collected. 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. When the app is **closed**, the chosen
out-of-app events (your turn, nudge, a found match, an invitation or friend request)
arrive as a **Telegram notification** instead — unless the player keeps notifications
in the app only (a profile setting, **on by default**).
out-of-app events (your turn, game over, nudge, a found match, an invitation or friend
request) arrive as a **Telegram notification** instead — unless the player keeps
notifications in the app only (a profile setting, **on by default**). The "your turn"
notification names the opponent and recaps their last move — the word and the running score
for a scoring play, or that they swapped or passed — and a finished game sends a "game over"
notification with your result and the final score (scores read with yours first).
### Accounts, linking & merge *(Stage 1 / 11)*
First platform contact auto-provisions a durable account. From the profile a player
+7 -3
View File
@@ -42,9 +42,13 @@ Mini App** авторизует по подписанным `initData` плат
в одну игру и простаивавший дольше окна удержания, удаляется сборщиком. Пока приложение открыто, клиент
держит живой стрим и получает обновления в реальном времени — ход соперника, ваш ход,
чат, nudge и найденный матч. Когда приложение **закрыто**, выбранные внеприложенческие
события (ваш ход, nudge, найденный матч, приглашение или заявка в друзья) приходят
вместо этого **уведомлением в Telegram** — если только игрок не оставил уведомления
только в приложении (настройка профиля, **включена по умолчанию**).
события (ваш ход, конец партии, nudge, найденный матч, приглашение или заявка в друзья)
приходят вместо этого **уведомлением в Telegram** — если только игрок не оставил
уведомления только в приложении (настройка профиля, **включена по умолчанию**).
Уведомление «ваш ход» называет соперника и пересказывает его последний ход — слово и
текущий счёт для результативного хода либо что он поменял фишки или пропустил, — а по
завершении партии приходит уведомление «конец партии» с твоим результатом и финальным
счётом (счёт читается, твой первым).
### Аккаунты, привязка и слияние *(Stage 1 / 11)*
Первый контакт с платформы заводит постоянный аккаунт. Из профиля игрок