Stage 17: backend defect fixes (nudge code, TG name, robot names/timing, multi-device push, move-duration metric + admin analytics)

- #3 nudge-on-own-turn: distinct result code nudge_own_turn + i18n (was reused 'not_your_turn')
- #2 sanitize connector registration name to the editable format; Player/Игрок-XXXXX fallback
- #5 variant-aware robot name pools (composed full/colloquial first + surname forms; ru gets <=20% latin)
- #4 move-number-aware robot move timing (early 1-5min -> late 10-90min, skew k=4)
- #7 emit move event to the actor too (multi-device sync); opponent_moved stays in-app only
- #1 live game_move_duration{variant,phase} histogram + admin console per-user min/avg/max columns and an inline-SVG move-time-by-move-number chart (offline from the journal)
- ProvisionRobot bypasses editor name validation (system names like 'Peter J.')
This commit is contained in:
Ilia Denisov
2026-06-06 09:59:12 +02:00
parent 6886efb6c0
commit 635f2fd9fc
30 changed files with 1068 additions and 120 deletions
@@ -101,3 +101,17 @@ code { background: var(--bg); padding: 0.05rem 0.3rem; border-radius: 4px; }
.actions { display: flex; flex-wrap: wrap; gap: 0.6rem; margin: 0.8rem 0; }
.actions form { margin: 0; }
.pill { padding: 0.05rem 0.4rem; border: 1px solid var(--line); border-radius: 999px; font-size: 0.8rem; }
/* Move-timing chart: a server-rendered, script-free inline SVG line chart. */
.chart { width: 100%; height: auto; max-width: 680px; margin-top: 0.4rem; }
.chart .axis { stroke: var(--line); stroke-width: 1; }
.chart .grid { stroke: var(--line); stroke-width: 1; stroke-dasharray: 2 3; opacity: 0.6; }
.chart .lbl { fill: var(--ink-dim); font-size: 11px; }
.chart .ln { fill: none; stroke-width: 1.5; }
.chart .ln-min { stroke: var(--ok); }
.chart .ln-avg { stroke: var(--accent); }
.chart .ln-max { stroke: var(--danger); }
.lg { font-weight: 600; }
.lg-min { color: var(--ok); }
.lg-avg { color: var(--accent); }
.lg-max { color: var(--danger); }