From 23b5c3b5cc2f61c29a1237c5b719ceebbf903272 Mon Sep 17 00:00:00 2001 From: Ilia Denisov Date: Fri, 5 Jun 2026 08:17:00 +0200 Subject: [PATCH] refine plan stage order --- PLAN.md | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/PLAN.md b/PLAN.md index 717f5ef..a197a14 100644 --- a/PLAN.md +++ b/PLAN.md @@ -48,9 +48,9 @@ independent (see ARCHITECTURE §9.1). | 12 | Observability & performance (telemetry, metrics, guest GC) | **done** | | 13 | Alphabet on the wire (UI alphabet-agnostic) | **done** | | 14 | Solver & dictionary split (publish solver + scrabble-dictionary repo/artifact) | **done** | -| 15 | Deploy infra & test contour (Dockerfiles, gateway static UI, compose, observability) | todo | -| 16 | Prod contour deploy (SSH export/import, manual after merge) | todo | -| 17 | Dual Telegram bots & language-gated variants | todo | +| 15 | Dual Telegram bots & language-gated variants | todo | +| 16 | Deploy infra & test contour (Dockerfiles, gateway static UI, compose, observability) | todo | +| 17 | Prod contour deploy (SSH export/import, manual after merge) | todo | Scaffolding is incremental: `go.work` lists only existing modules; each stage adds the modules it needs. @@ -264,7 +264,21 @@ both — discharging **TODO-1** and **TODO-2**. `BACKEND_DICT_DIR//`, `engine.OpenWithVersions`, per-game `dict_version` pin; a version is safe to retire once no active game pins it). -### Stage 15 — Deploy infra & test contour +### Stage 15 — Dual Telegram bots & language-gated variants *(feature; own interview)* +Scope (owner's idea, to design in detail at its own start): run **two bots in the one connector +container** — one for the English audience, one for Russian — each with its own token + game-channel id ++ service-language tag (the same Telegram user id spans both). `initData` validation tries each bot's +token in turn (none succeeds ⇒ invalid). The connector returns the **service language `en`/`ru`**; +`Notify`/`SendToUser` take a language key so the right bot delivers. The UI **gates the game-type +(variant) choice** by service language (en → English; ru → Russian + Эрудит). +Open details (own interview): which bot sends a notification for an **existing** game (game language vs +the player's service language) given one user id spans both bots; behaviour for **non-Telegram** +players (web/email/guest — ungated, or by interface language); the proto/wire changes +(`ValidateInitData` service-language field, a bot/language selector on the push RPCs); per-bot config + +tests. Engineering feedback already captured at the Stage 14 interview: the two-bots-in-one-container + +sequential validation + language-keyed routing model is sound. + +### Stage 16 — Deploy infra & test contour Scope: the deploy machinery + the **test contour** (the bulk of the original Stage 14). Backend + gateway **Dockerfiles** (multi-stage distroless, mirroring the Stage 9 connector image); the gateway gains **static UI serving** — **embedded** via `go:embed` (a node build stage in the gateway image), @@ -282,7 +296,7 @@ h2c wrap — `/` + `/telegram/` mounts; a committed `dist` placeholder so `go bu build); Postgres healthcheck/volume; whether the connector-scoped compose is retired for the root one; collector/Tempo/Prometheus retention. -### Stage 16 — Prod contour deploy +### Stage 17 — Prod contour deploy Scope: the **production contour** on a remote host over SSH. Deploy by **container export/import** (`docker save` → `scp`/ssh → `docker load` → `docker compose up` on the remote), the SSH key + host IP in Gitea secrets; **strictly manual** (`workflow_dispatch`) after a feature branch is merged to @@ -292,20 +306,6 @@ convention. Open details (re-interview): export/import vs a registry trade-off; prod domain/TLS at the remote caddy; prod VPN; rollback. -### Stage 17 — Dual Telegram bots & language-gated variants *(feature; own interview)* -Scope (owner's idea, to design in detail at its own start): run **two bots in the one connector -container** — one for the English audience, one for Russian — each with its own token + game-channel id -+ service-language tag (the same Telegram user id spans both). `initData` validation tries each bot's -token in turn (none succeeds ⇒ invalid). The connector returns the **service language `en`/`ru`**; -`Notify`/`SendToUser` take a language key so the right bot delivers. The UI **gates the game-type -(variant) choice** by service language (en → English; ru → Russian + Эрудит). -Open details (own interview): which bot sends a notification for an **existing** game (game language vs -the player's service language) given one user id spans both bots; behaviour for **non-Telegram** -players (web/email/guest — ungated, or by interface language); the proto/wire changes -(`ValidateInitData` service-language field, a bot/language selector on the push RPCs); per-bot config + -tests. Engineering feedback already captured at the Stage 14 interview: the two-bots-in-one-container + -sequential validation + language-keyed routing model is sound. - ## Refinements logged during implementation - **Stage 0**: solver `replace` deferred to Stage 2 (nothing imports it yet;