docs(telegram): document the Mini App embedding enhancements
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 17s
CI / ui (pull_request) Successful in 56s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m22s

Record the current state in ARCHITECTURE and FUNCTIONAL (+ _ru mirror): inside the
Mini App the client tracks Telegram's live theme switch, fits the full device
safe-area, exposes a native Settings button into the in-app settings, and syncs the
device-independent display prefs (theme, reduce-motion, board labels — not the
interface language) across the user's Telegram devices via CloudStorage; the
validator denies a bot user (is_bot) before provisioning an account.
This commit is contained in:
Ilia Denisov
2026-06-24 12:19:50 +02:00
parent 8de9fb1ecd
commit 29b6c7e4d8
3 changed files with 23 additions and 7 deletions
+9 -3
View File
@@ -42,7 +42,12 @@ Three executables plus per-platform side-services:
users, a weighted fair rotation — §10),
and a client **board-style** setting (bonus-label
mode). The visual/interaction design system is documented in
[`UI_DESIGN.md`](UI_DESIGN.md).
[`UI_DESIGN.md`](UI_DESIGN.md). Inside the Telegram Mini App the client additionally
tracks Telegram's live theme switch (`themeChanged`), fits the full device safe-area
insets (the bottom/home-indicator strip taking the bottom bar's colour), exposes
Telegram's native **Settings** button into the in-app settings, and syncs the
device-independent display preferences (theme, reduce-motion, board labels — **not** the
interface language) across the user's Telegram devices via **CloudStorage**.
- **`platform/telegram`** — the Telegram side-service (module
`scrabble/platform/telegram`), split into two binaries that share the bot token
(**one bot**, one optional game channel, §3):
@@ -152,7 +157,8 @@ arrive from a platform rather than completing a mandatory registration).
- **Single bot.** The platform side-service runs **one bot** (one token + one optional
game channel), split into a home **validator** and a remote **bot** that share the
token. `ValidateInitData` (the validator) validates `initData` against that single
token and returns only the Telegram user identity — there is no per-bot "service
token, **rejects a bot user** (the signed `is_bot` flag), and returns only the Telegram
user identity — there is no per-bot "service
language" and no supported-languages set on the wire. The bot's chat messages and
out-of-app push are
rendered in the recipient's **interface language** (`preferred_language`, en/ru), not in
@@ -972,7 +978,7 @@ edits take effect on the next `profile.get` (open/reconnect/foreground), not mid
| Concern | Enforced by |
| --- | --- |
| Public rate limiting / anti-abuse | gateway (per-IP public/email/admin classes, per-user authenticated class; a request body cap of `GATEWAY_MAX_BODY_BYTES`; rejections are metered, summarised to the backend and surfaced in the admin console with a conservative reversible auto-flag — §11). In prod a **temporary IP ban** (`GATEWAY_ABUSE_BAN_ENABLED`) blocks an IP that sustains rejections or trips a **honeypot** decoy path / **honeytoken**, refused with 429 before any work; operators lift bans from the console. Off in the shared-NAT test contour, where the client IP is not real (§11) |
| Telegram initData validation (bot-token HMAC) | the Telegram **validator**; the gateway delegates it over gRPC, so the bot token (the HMAC secret) lives only in the validator and the bot, never in the gateway |
| Telegram initData validation (bot-token HMAC) | the Telegram **validator**; the gateway delegates it over gRPC, so the bot token (the HMAC secret) lives only in the validator and the bot, never in the gateway. The validator also **rejects a bot principal** (the signed `is_bot` flag) before any account is provisioned |
| Session minting; email-code / guest validation | gateway (with backend) |
| Session → `user_id` resolution, `X-User-ID` injection | gateway |
| Authorisation, ownership, state transitions | backend (`X-User-ID` is the sole identity input) |