Stage 17: bake decisions into PLAN, ARCHITECTURE, FUNCTIONAL(+ru), UI_DESIGN, READMEs; mark stage done
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 26s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m4s
CI / changes (pull_request) Successful in 1s
CI / unit (pull_request) Successful in 8s
CI / integration (pull_request) Successful in 11s
CI / ui (pull_request) Successful in 26s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m4s
- PLAN: Stage 17 Refinements entry + caveats resolved summary + tracker done - ARCHITECTURE §7 (move-number robot timing, composed variant-aware names), §10 (move event to the actor too), §11 (game_move_duration metric + offline admin per-user analytics), §14 (current branch model, path-conditional CI + gate, connector liveness) - FUNCTIONAL(+ru): robot draws language-appropriate names - UI_DESIGN: screen transitions, Telegram theme/nav, ad-banner accent, players plaque + history drawer - backend README: robot timing/names refinements
This commit is contained in:
@@ -50,7 +50,7 @@ independent (see ARCHITECTURE §9.1).
|
||||
| 14 | Solver & dictionary split (publish solver + scrabble-dictionary repo/artifact) | **done** |
|
||||
| 15 | Dual Telegram bots & language-gated variants | **done** |
|
||||
| 16 | Deploy infra & test contour (Dockerfiles, gateway static UI, compose, observability) | **done** |
|
||||
| 17 | Test-contour verification & defect fixes | todo |
|
||||
| 17 | Test-contour verification & defect fixes | **done** |
|
||||
| 18 | Prod contour deploy (SSH export/import, manual after merge) | todo |
|
||||
|
||||
Scaffolding is incremental: `go.work` lists only existing modules; each stage
|
||||
@@ -298,7 +298,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 17 — Test-contour verification & defect fixes
|
||||
### Stage 17 — Test-contour verification & defect fixes *(done)*
|
||||
Scope: exercise the deployed **test contour** end-to-end and fix the defects it surfaces — the
|
||||
"does it actually work in the contour" pass before prod. Bring up the `development` deploy, then
|
||||
verify each piece against a real run: the gateway serves the SPA at `/` and `/telegram/`; the admin
|
||||
@@ -316,6 +316,95 @@ are in-scope vs deferred; the changed-paths design + the aggregate gate job; the
|
||||
liveness-check grace period (the VPN sidecar handshake lets the connector restart a few times before
|
||||
it settles).
|
||||
|
||||
#### Found caveats (all resolved in Stage 17 — see *Refinements → Stage 17*)
|
||||
|
||||
The owner's collected caveats below were classified (fix-now / verify-then-fix / discuss),
|
||||
discussed where they were forks, and resolved in one session with tests where practical. The
|
||||
per-item outcomes are recorded under *Refinements logged during implementation → Stage 17*; the
|
||||
raw list is kept here as the record of what the first contour run surfaced.
|
||||
|
||||
- /_gm/grafana/ требует повторного ввода пароля basic auth, хотя до этого я уже зашёл в /_gm/
|
||||
Такого быть не должно: графана живёт под /_gm/ и ей не нужен свой auth.
|
||||
|
||||
- нужна ещё метрика "продолжительность хода" - сколько игроки тратят на каждый ход,
|
||||
скорее всего, понадобится новое поле last_move_ts если ещё нет, так же нужно будет завести
|
||||
метрику в графане как общую, так и и по конкретному пользователю (можно ли? дорого ли?),
|
||||
а так же с привязкой к номеру хода и без номера хода. Всё это понадобится для анализа
|
||||
способностей игроков, чтобы подогнать под них роботоа. А так же - выявлять читеров.
|
||||
|
||||
- регистрация пользователя из телеграм (как и других коннекторов):
|
||||
пытаться очистить имя от посторонних символов, аналогично проверке при вводе имени в профиле.
|
||||
если после очистки ничего не осталось, поставить имя Player/Игрок-XXXXX (5 рандомных цифр),
|
||||
язык в зависимости от внешнего коннектора.
|
||||
|
||||
- game - chat - nudge. Когда мой ход и я жму nudge, появляется сообщение "сейчас не ваш ход".
|
||||
Думаю, опечатка - "не" лишняя, проверь на всех языках.
|
||||
|
||||
- если открыли игру через telegram, надо в настройках вообще полностью скрыть переключатель темы "авто/светлая/темная",
|
||||
т.к. тему задаёт сам телеграм (уточни, в какой проперти её можно забрать, и нужно ли, сейчас оно уже нормально работает
|
||||
на самих стилях)
|
||||
|
||||
- возможно, к предыдущему пункту: запускаю мини апп на macos/telegram desktop. в самой macos у меня темная тема.
|
||||
когда я включаю тему "авто" в настройках mini app, а в самом телеграме - светлую, всё ломается, nav bar и tab bar
|
||||
рисуются темным фоном, список игр и меню - светлым, поле игры - тёмное, вокруг него светлоая рамка.
|
||||
Провернул тот же трюк на ios - всё чётко, в режиме "авто" он полностью держит ту настройку, которая в
|
||||
самом телеграме задана. Проверь, можно ли это починить для desktop-версии тг, скорее всего там
|
||||
системные настройки как-то в браузер протекают. Ну если не получится понять причину, тогда и черт с ним.
|
||||
|
||||
- не знаю, ошибка это или by design - если у меня открыта игра сразу в desktop telegram и на ios,
|
||||
то когда я делаю ход, в другом окне не обновляется ничего - ни само игровое поле, ни лобби.
|
||||
интересно, как ходят уведомления через gateway - по последнему активному push-каналу, что ли?
|
||||
если так, стоит ли чинить, чтобы у пользователя все пуш-каналы поддерживались или это дорого?
|
||||
нужен твой анализ и совет.
|
||||
|
||||
- надо подкрутить тайминг автоматического хода работа. идея такая: сейчас, насколько я помню, время хода
|
||||
выбирается от 2 до 90 минут с перекосом ближе к 2 минутам (поправь если что). я предлагаю этот интервал
|
||||
сделать динамическим в зависимости от хода. Например, средяя партия это 25-30 ходов, предположительно.
|
||||
На первом ходу интервал должен быть 1..5 минут, на последнем - 10..90 минут, всё так же с перекосом в меньшую сторону.
|
||||
А то я сейчас поиграл, роботы на первых ходах по 15 минут думают.
|
||||
Сможешь такую хитрую формулу составить? Цифры ориентировочные. Потом после набора реальной статистики подкрутим цифры.
|
||||
Заодно напомни, как работает формула "перекоса", можно ли её "заставить" косить почаще в меньшую сторону, как бы имитируя
|
||||
активного игрока. Этот пункт требует тщательного обсуждения, пожалуй.
|
||||
|
||||
- при навигации между лобби и игрой есть задержка едва заметная на глаз, думаю, связанная с тем, что UI все данные по игре перезапрашивает
|
||||
каждый раз. Кроме этого, когда я в лобби возвращаюсь, глаз ловит перерисовку экрана, довольно быстро, но есть какое-то
|
||||
неприятное ощущение, что туда что-то подгружается. А мы можем внутри UI наполнять кэш этими данными и экраны не рисовать
|
||||
каждый раз, а просто подменять? не знаю, как это работает, если честно. Но вот информацию по игре, в которую пользователь
|
||||
проваливался 1 раз, совершенно точно можно положить в кэш и обновлять его когда с сервера приходит новый ход и т.п.
|
||||
|
||||
- при запуске в telegram, надо бы цвет фона nav bar сделать фоном телеграма, а то он "выпадает" из общего дизайна.
|
||||
|
||||
- а вот фон рекламной строчки под nav bar наоборот, сделать бы чуть светлее (в тёмной теме) или темнее (в светлой),
|
||||
чтобы был акцентирован, но не ярко. что-то там есть в стилях телеграма такое готовое?
|
||||
ну и для собственного дефолтного стиля тоже надо выбрать соответствующие.
|
||||
|
||||
- Переключаюсь в ios в другое приложение, по возвращении ловлю "проблема соединения, повторяем".
|
||||
Вроде бы в телеграм-бандле есть обработчики всяких событий, в том числе background in/out, или как там оно зовётся.
|
||||
Посмотри, можно ли что-то с этим сделать? Если да, то именно в случаях когда приложение уходит в фон - не надо рисовать
|
||||
плашку с ошибкой, просто молча пытаться соединиться, то есть плашка появится когда приложение на в фоне на следующем retry.
|
||||
|
||||
- при использовании подсказки в игре ато зум ведёт в лево-верх, а не туда, где была поставлена подсказка.
|
||||
|
||||
- В русских партиях нужны русские имена для роботов, но можно вперемешку с латинскими именами, только чтобы латинских имён
|
||||
было не больше 20%.
|
||||
|
||||
- Сделать анимацию переходов между экранами: наезд справа если из лобби куда-то переходим и наоборот, уезжание вправо и открытие лобби, когда нажимаем back в навигации.
|
||||
|
||||
- Цвет и размер плашки с игроками над доской: давай сделаем не "кнопками" самих игроков, а просто поделим это пространство
|
||||
поровну между игроками, а активного игрока будем показывать за счёт "поднятия" его плашки, за счёт теней слева и справа, чтобы
|
||||
остальные игроки были как бы "утоплены" внутрь.
|
||||
|
||||
- В игре клик/тач по плашке с именами игроков открывает/закрывает историю.
|
||||
|
||||
- В истории ходов странное выравнивание колонки со словами, они буквально скачут влево-вправо.
|
||||
|
||||
- В многословных партиях надо в истории показывать основное слово + дополнительное (если это ещё не сделано, надо проверить)
|
||||
|
||||
- При открытии истории нижнюю границу таблицы ("тень") сразу прибивать к доске, а не растягивать вслед за таблицей.
|
||||
|
||||
- Баг. Открыл игру через ru-телеграм бота, пытаюсь сделать "new -> русский" (это скрэбл с русским алфавитом), появляется красная плашка
|
||||
"что-то пошло не так". при этом "new -> эрудит" работает. Попробуй посмотреть в логах сейчас, может что-то есть. Или как-то иначе проанализируй, или давай вместе будем смотреть, если не получится.
|
||||
|
||||
### Stage 18 — 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
|
||||
@@ -1115,6 +1204,57 @@ provided cert) at the contour caddy; prod VPN; rollback.
|
||||
environment) rather than via a `TEST_`-prefixed variable — removing a confusing double-`TEST` operator
|
||||
knob and the secret-vs-variable footgun; prod (Stage 18) leaves it `false`.
|
||||
|
||||
- **Stage 17** (interview + implementation): the test-contour verification pass. The owner's
|
||||
collected caveats were classified (fix-now / verify-then-fix / discuss) and resolved in one session.
|
||||
- **Russian Scrabble fixed** (#6): the UI sent the variant id `russian` while the backend's canonical
|
||||
string (and `StateView`) is `russian_scrabble`, so `lobby.enqueue`/invite returned 400 (confirmed in
|
||||
the contour logs). The UI was aligned to `russian_scrabble` (the `Variant` type, `variants.ts`,
|
||||
`Lobby.svelte`, mock fixtures, premium/alphabet keys, tests); the backend label is unchanged
|
||||
(persisted games, GCG and the `variant` metric attribute keep it).
|
||||
- **Nudge message** (#3): `social.ErrNudgeOnOwnTurn` shared the `not_your_turn` result code with
|
||||
`game.ErrNotYourTurn`, so nudging on your own turn read "it is not your turn" — backwards. A distinct
|
||||
`nudge_own_turn` code + i18n message was added, and the UI disables the nudge control on your own turn.
|
||||
- **Connector name sanitization** (#2): `account.ProvisionTelegram` now cleans the platform name to the
|
||||
editable display-name format (`sanitizeDisplayName`) and falls back to `Player`/`Игрок-NNNNN` (by
|
||||
language) when nothing remains. A new `account.ProvisionRobot` lets system robot names bypass editor
|
||||
validation (e.g. "Peter J.").
|
||||
- **Robot names** (#5, interview): per-language composed pools — 32 full + 32 colloquial first names
|
||||
paired by index, plus a surname pool (gender-agreed for Russian) rendered in three forms (first only /
|
||||
first + surname initial / first + full surname), composed deterministically per pool slot (stable
|
||||
across restarts). `Pick(variant)` is variant-aware: a Russian game draws Russian names with ≤ ~20%
|
||||
Latin, an English game the Latin pool. Robot identities are keyed `robot-<lang>-<index>`.
|
||||
- **Robot timing** (#4, interview): the fixed `2 + 88·u^3.5` move delay became move-number-aware — the
|
||||
band interpolates from [1,5] min at the first move to [10,90] min by ~28 moves, right-skewed by k=4,
|
||||
so early moves are quick and the endgame can be long. A daytime nudge pulls the reply toward the
|
||||
move's lower band.
|
||||
- **Multi-device push** (#7, interview): `emitMove` no longer skips the acting seat, so the mover's own
|
||||
other devices (and their lobby) refresh. `opponent_moved` stays in-app only (no out-of-app push to the
|
||||
actor), and the gateway already fans each event out to all of a user's live streams.
|
||||
- **Move-duration analytics** (#1, interview): a live `game_move_duration{variant,phase}` histogram
|
||||
(opening/middle/endgame) + a Grafana panel, plus offline per-user analytics in the admin console —
|
||||
min/avg/max columns in the user list and an inline-SVG chart of think-time by the player's move number,
|
||||
computed from the journal (`game_moves.created_at` deltas; no schema change). Per-user stays offline,
|
||||
not a Prometheus label, to avoid cardinality blow-up; the live histogram aggregates all seats (robots
|
||||
included), so the per-human admin view is authoritative.
|
||||
- **CI** (#9/#10, interview): `unit`/`integration`/`ui` are path-conditional behind a `changes` job; an
|
||||
always-running `gate` job aggregates them (success-or-skipped) and is the single branch-protection
|
||||
required check (`CI / gate`), so a skipped job never blocks a merge. The deploy job gained a
|
||||
Telegram-connector liveness probe (`docker inspect`: running, not restarting, stable restart count,
|
||||
with a VPN-handshake grace period) — closing the Stage 16 blind spot where a crash-looping connector
|
||||
was invisible to the gateway-only probe.
|
||||
- **UI theming / UX**: inside Telegram the colour scheme is forced from `WebApp.colorScheme` over the OS
|
||||
`prefers-color-scheme` (fixes the Telegram Desktop breakage, #12) and the theme switcher is hidden
|
||||
(#11); the nav bar takes Telegram's bg and the announcement banner a subtle `--ad-bg` accent (#14/#15);
|
||||
the reconnect banner is suppressed while backgrounded and the stream reconnects on return (#16); hint
|
||||
zoom scrolls to the placement (#17); the players plaque raises the active seat and sinks the others
|
||||
with a tap toggling history (#19/#20); history fixes the word-column jitter and pins its bottom shadow
|
||||
to the board (#21/#23); directional screen-slide transitions (#18a); a per-game in-memory cache renders
|
||||
instantly on re-entry and refreshes in the background (#13).
|
||||
- **Grafana repeated password (#8) — not a server defect**: verified live that caddy challenges `/_gm`
|
||||
and `/_gm/grafana` with one identical realm and Grafana serves anonymously, so the repeated prompt is a
|
||||
browser Basic-Auth scoping quirk (likely Safari/Desktop), not infra — left for the owner to re-verify,
|
||||
no server change. **Multi-word history (#22)** was already implemented (all formed words shown).
|
||||
|
||||
## Deferred TODOs (cross-stage)
|
||||
|
||||
- ~~**TODO-1 — publish & version the solver.**~~ **Done in Stage 14.** `scrabble-solver` is
|
||||
|
||||
Reference in New Issue
Block a user