R6(a): de-stage code, docs, READMEs; split stage6_test

Mechanical, behaviour-preserving removal of Stage N / TODO-N / phase (RN)
references from comments, doc-comments, service READMEs, the current-state docs
(ARCHITECTURE, FUNCTIONAL+_ru, TESTING, UI_DESIGN), config-file comments, and the
.fbs/.proto schema comments. PLAN.md / PRERELEASE.md / CLAUDE.md keep the stage
history.

- Rename the only stage-named identifiers: registerStage8 -> registerSocialOps,
  registerStage11 -> registerLinkOps (gateway transcode).
- Split stage6_test.go: TestEmailLoginFlow -> email_test.go,
  TestGuestAutoMatchLeavesNoStats (+ provisionGuest) -> account_test.go.
- Regenerated proto bindings (push.pb.go, telegram_grpc.pb.go) from the de-staged
  .proto comments; FB Go/TS bindings unchanged (flatc strips schema comments).

go build/vet/gofmt clean across modules; integration typecheck and pnpm check green.
This commit is contained in:
Ilia Denisov
2026-06-10 16:56:03 +02:00
parent a372343797
commit 8881214213
156 changed files with 749 additions and 778 deletions
+14 -14
View File
@@ -35,7 +35,7 @@ type ProfileResp struct {
NotificationsInAppOnly bool `json:"notifications_in_app_only"`
}
// LinkResultResp is the result of an account link/merge step (Stage 11). Status is
// LinkResultResp is the result of an account link/merge step. Status is
// "linked", "merge_required" (the secondary_* fields summarise the other account) or
// "merged". Token is a switched-session token (a guest initiator's durable
// counterpart won); Profile is the surviving/active account's profile.
@@ -50,7 +50,7 @@ type LinkResultResp struct {
}
// TileJSON is one tile in a decoded move response (history, move result, hint); its Letter
// is a concrete character (Stage 13 keeps the move journal in letters).
// is a concrete character (the move journal is kept in letters).
type TileJSON struct {
Row int `json:"row"`
Col int `json:"col"`
@@ -58,7 +58,7 @@ type TileJSON struct {
Blank bool `json:"blank"`
}
// PlayTileJSON is one inbound tile to place, addressed by alphabet index (Stage 13). For a
// PlayTileJSON is one inbound tile to place, addressed by alphabet index. For a
// blank, Letter is the designated letter's index and Blank is true.
type PlayTileJSON struct {
Row int `json:"row"`
@@ -107,7 +107,7 @@ type GameResp struct {
}
// MoveResultResp is the outcome of a committed move. Rack carries the actor's refilled rack as
// wire alphabet indices and BagLen the bag size after the draw (R4).
// wire alphabet indices and BagLen the bag size after the draw.
type MoveResultResp struct {
Move MoveRecordResp `json:"move"`
Game GameResp `json:"game"`
@@ -116,14 +116,14 @@ type MoveResultResp struct {
}
// AlphabetEntryJSON is one letter of a variant's alphabet (its index, concrete letter and
// tile value), present in StateResp only when the client requested it (Stage 13).
// tile value), present in StateResp only when the client requested it.
type AlphabetEntryJSON struct {
Index int `json:"index"`
Letter string `json:"letter"`
Value int `json:"value"`
}
// StateResp is a player's view of a game. Rack carries wire alphabet indices (Stage 13);
// StateResp is a player's view of a game. Rack carries wire alphabet indices;
// Alphabet is present only when the request asked for it.
type StateResp struct {
Game GameResp `json:"game"`
@@ -224,7 +224,7 @@ func (c *Client) Profile(ctx context.Context, userID string) (ProfileResp, error
}
// SubmitPlay commits a placement on the player's turn. The tiles are addressed by alphabet
// index (Stage 13).
// index.
func (c *Client) SubmitPlay(ctx context.Context, userID, gameID, dir string, tiles []PlayTileJSON) (MoveResultResp, error) {
var out MoveResultResp
body := map[string]any{"dir": dir, "tiles": tiles}
@@ -233,7 +233,7 @@ func (c *Client) SubmitPlay(ctx context.Context, userID, gameID, dir string, til
}
// GameState returns the player's view of a game. When includeAlphabet is set the backend
// embeds the variant's alphabet table (Stage 13); the client asks for it on a per-variant
// embeds the variant's alphabet table; the client asks for it on a per-variant
// cache miss only.
func (c *Client) GameState(ctx context.Context, userID, gameID string, includeAlphabet bool) (StateResp, error) {
var out StateResp
@@ -320,7 +320,7 @@ func (c *Client) Pass(ctx context.Context, userID, gameID string) (MoveResultRes
}
// Exchange swaps the chosen rack tiles back into the bag. Tiles are wire alphabet indices
// (Stage 13; a blank is engine.BlankIndex).
// (a blank is engine.BlankIndex).
func (c *Client) Exchange(ctx context.Context, userID, gameID string, tiles []int) (MoveResultResp, error) {
var out MoveResultResp
err := c.do(ctx, http.MethodPost, c.gamePath(gameID, "/exchange"), userID, "",
@@ -342,7 +342,7 @@ func (c *Client) Hint(ctx context.Context, userID, gameID string) (HintResultRes
return out, err
}
// GetDraft returns the player's saved composition for a game (Stage 17) as the backend's
// GetDraft returns the player's saved composition for a game as the backend's
// raw JSON body. The gateway forwards it verbatim, never interpreting its shape.
func (c *Client) GetDraft(ctx context.Context, userID, gameID string) (json.RawMessage, error) {
var out json.RawMessage
@@ -350,21 +350,21 @@ func (c *Client) GetDraft(ctx context.Context, userID, gameID string) (json.RawM
return out, err
}
// SaveDraft upserts the player's composition for a game (Stage 17). body is the client's
// SaveDraft upserts the player's composition for a game. body is the client's
// {rack_order, board_tiles} JSON, forwarded verbatim — a json.RawMessage marshals as-is, so
// there is no double-encode.
func (c *Client) SaveDraft(ctx context.Context, userID, gameID string, body json.RawMessage) error {
return c.do(ctx, http.MethodPut, c.gamePath(gameID, "/draft"), userID, "", body, nil)
}
// HideGame hides a finished game from the caller's own games list (Stage 17). The action is
// HideGame hides a finished game from the caller's own games list. The action is
// per-account and irreversible; the game stays visible to the other players.
func (c *Client) HideGame(ctx context.Context, userID, gameID string) error {
return c.do(ctx, http.MethodPost, c.gamePath(gameID, "/hide"), userID, "", struct{}{}, nil)
}
// Evaluate previews a tentative play's legality and score. The tiles are addressed by
// alphabet index (Stage 13).
// alphabet index.
func (c *Client) Evaluate(ctx context.Context, userID, gameID, dir string, tiles []PlayTileJSON) (EvalResultResp, error) {
var out EvalResultResp
err := c.do(ctx, http.MethodPost, c.gamePath(gameID, "/evaluate"), userID, "",
@@ -373,7 +373,7 @@ func (c *Client) Evaluate(ctx context.Context, userID, gameID, dir string, tiles
}
// CheckWord looks a word up in the game's pinned dictionary. The word is carried as
// repeated ?idx= alphabet indices (Stage 13); the backend echoes the decoded concrete word.
// repeated ?idx= alphabet indices; the backend echoes the decoded concrete word.
func (c *Client) CheckWord(ctx context.Context, userID, gameID string, word []int) (WordCheckResp, error) {
var out WordCheckResp
q := url.Values{}
+5 -5
View File
@@ -6,7 +6,7 @@ import (
"net/url"
)
// The Stage 8 response structs and client methods mirror the backend's social,
// The response structs and client methods mirror the backend's social,
// account and history JSON DTOs. The transcode layer maps them to FlatBuffers.
// AccountRefResp is a referenced account with its display name resolved.
@@ -249,7 +249,7 @@ func (c *Client) LinkEmailRequest(ctx context.Context, userID, email string) err
}
// LinkEmailConfirm verifies the code and binds a free email or reports a required
// merge (Stage 11).
// merge.
func (c *Client) LinkEmailConfirm(ctx context.Context, userID, email, code string) (LinkResultResp, error) {
var out LinkResultResp
err := c.do(ctx, http.MethodPost, "/api/v1/user/link/email/confirm", userID, "",
@@ -257,7 +257,7 @@ func (c *Client) LinkEmailConfirm(ctx context.Context, userID, email, code strin
return out, err
}
// LinkEmailMerge re-verifies the code and performs the merge (Stage 11).
// LinkEmailMerge re-verifies the code and performs the merge.
func (c *Client) LinkEmailMerge(ctx context.Context, userID, email, code string) (LinkResultResp, error) {
var out LinkResultResp
err := c.do(ctx, http.MethodPost, "/api/v1/user/link/email/merge", userID, "",
@@ -266,7 +266,7 @@ func (c *Client) LinkEmailMerge(ctx context.Context, userID, email, code string)
}
// LinkTelegram attaches a gateway-validated Telegram identity to the caller or
// reports a required merge (Stage 11).
// reports a required merge.
func (c *Client) LinkTelegram(ctx context.Context, userID, externalID string) (LinkResultResp, error) {
var out LinkResultResp
err := c.do(ctx, http.MethodPost, "/api/v1/user/link/telegram", userID, "",
@@ -275,7 +275,7 @@ func (c *Client) LinkTelegram(ctx context.Context, userID, externalID string) (L
}
// LinkTelegramMerge merges the account owning a gateway-validated Telegram identity
// into the caller's (Stage 11).
// into the caller's.
func (c *Client) LinkTelegramMerge(ctx context.Context, userID, externalID string) (LinkResultResp, error) {
var out LinkResultResp
err := c.do(ctx, http.MethodPost, "/api/v1/user/link/telegram/merge", userID, "",
+1 -1
View File
@@ -129,7 +129,7 @@ func (c *Client) SubscribePush(ctx context.Context, gatewayID string) (grpc.Serv
// ReportRateLimited posts the gateway's periodic rate-limiter rejection summary
// to the backend, which feeds the admin console's throttled view and the
// high-rate auto-flag. The endpoint carries no user identity: like
// sessions/resolve it rides the trusted internal segment (R3).
// sessions/resolve it rides the trusted internal segment.
func (c *Client) ReportRateLimited(ctx context.Context, windowSeconds int, entries []ratelimit.Rejection) error {
body := struct {
WindowSeconds int `json:"window_seconds"`