feat(variants): default a registered account to Erudit + Russian Scrabble
CI / changes (pull_request) Successful in 3s
CI / unit (pull_request) Successful in 11s
CI / integration (pull_request) Successful in 22s
CI / ui (pull_request) Successful in 1m16s
CI / conformance (pull_request) Successful in 10s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 1m53s

New Game opened on a single variant for everyone, which reads poorly on VK
where Russian Scrabble is the familiar game. A registered account now starts
with both Russian-alphabet games, so the picker offers a real choice with no
pre-selection.

A guest stays on Erudit alone and is invited to register for the rest: the
device-local guest has no profile at all, so the client-side fallback has to
keep matching the server. Registering promotes the set, but only while the
guest still carries the untouched guest default. Existing accounts are not
backfilled — the set they carry may be a deliberate choice.

The Telegram promo start-param becomes additive rather than a replacement,
with English Scrabble withheld from a Russian-speaking arrival; otherwise the
English campaign link would have taken Russian Scrabble away from every
account it onboarded.
This commit is contained in:
Ilia Denisov
2026-07-27 20:38:09 +02:00
parent 69b1a50644
commit b6d88da78c
19 changed files with 338 additions and 56 deletions
+23 -4
View File
@@ -245,9 +245,15 @@ arrive from a platform rather than completing a mandatory registration).
than stranding a user who never opened Settings on the creation-time seed.
- **Variant preferences (New Game gating).** Which variants a player may be matched into is a
per-user **profile** setting — `variant_preferences`, a set of `engine.Variant` labels
(`scrabble_en`, `scrabble_ru`, `erudit_ru`) edited on the Settings/Profile screen. New
accounts default to **Erudit only** (a DB column default); at least one variant must stay
selected. The picker is ordered **Erudit-first** everywhere. The preference gates the New
(`scrabble_en`, `scrabble_ru`, `erudit_ru`) edited on the Settings/Profile screen. A newly
**registered** account defaults to the two Russian-alphabet games — **Erudit + Russian
Scrabble** (a DB column default); a **guest** is deliberately narrower and starts on
**Erudit only** (`account.ProvisionGuest` writes the set explicitly), with New Game inviting
the guest to register for the rest. Registering promotes the set to the registered default
(`account.ClearGuest`), but only while the guest still carries the untouched guest set —
a player who chose their own set is never overruled, and **existing accounts are not
backfilled** when the default moves. At least one variant must stay selected. The picker is
ordered **Erudit-first** everywhere. The preference gates the New
Game picker on every create path the player **initiates** — auto-match, vs-AI and a friend
invitation the player **creates** — and the backend **enforces** it on those paths (a chosen
variant outside the caller's preferences is rejected with HTTP 400). An **invited** friend
@@ -316,6 +322,18 @@ arrive from a platform rather than completing a mandatory registration).
> `service_language`/`supported_languages` and the push `language` routing field, and
> gained `variant_preferences` on Profile/UpdateProfile.
> **Decision (2026-07-27) — registered accounts start on both Russian games.** The
> Erudit-only default was too narrow a first impression on VK, where Russian Scrabble is the
> familiar game: a **registered** account is now created with `erudit_ru + scrabble_ru`, so
> New Game opens with a real choice (and therefore no pre-selected variant). A **guest**
> stays on Erudit alone and is invited to register for the rest, which keeps the offline
> device-local guest — who has no profile at all — matching the server. **Existing accounts
> are not backfilled**: the set a player already carries may be a deliberate choice, and the
> two are indistinguishable in the data. The Telegram promo `start_param` correspondingly
> became **additive** rather than a replacement (it can only widen a set), with English
> Scrabble withheld from a Russian-speaking arrival — otherwise the English campaign link
> would have quietly taken Russian Scrabble away from every account it onboarded.
## 4. Accounts, identities, linking & merge
- One internal account may carry several **platform identities**
@@ -883,7 +901,8 @@ in either direction (the enqueue excludes the caller's `BlockedWith` set);
- **Profile**: `preferred_language` (en/ru; tracks the interface language — §4), display name, email
(confirm-code binding, see §4), **timezone**, the daily **away window**, the
**variant preferences** (`variant_preferences`, the matchable-variant set that gates New
Game — §3, defaulting to Erudit only, at least one enforced) and the
Game — §3, defaulting to Erudit + Russian Scrabble for a registered account and Erudit
alone for a guest, at least one enforced) and the
block toggles — all editable through `account.UpdateProfile`, which validates them:
a display name is Unicode letters joined by single ` `/`.`/`_`
separators (no leading/trailing/adjacent separators, ≤ 32 runes); the timezone is a