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
@@ -112,7 +112,7 @@
}
let draftSaveTimer: ReturnType<typeof setTimeout> | null = null;
// scheduleDraftSave persists the composition (rack order + pending tiles) after a short
// debounce; best-effort, so a failed save never interrupts play (Stage 17).
// debounce; best-effort, so a failed save never interrupts play.
function scheduleDraftSave() {
if (draftSaveTimer) clearTimeout(draftSaveTimer);
draftSaveTimer = setTimeout(() => {
@@ -178,7 +178,7 @@
if (!e) return;
if (e.kind === 'opponent_moved' && e.gameId === id) {
// While composing, reload so a draft overlapping the new move is reconciled; otherwise apply
// the move as a delta with no fetch (R4).
// the move as a delta with no fetch.
if (placement.pending.length > 0) void load();
else applyDelta(applyMoveDelta(cacheSnapshot(), { move: e.move, game: e.game, bagLen: e.bagLen }));
} else if (e.kind === 'your_turn' && e.gameId === id) {
@@ -208,15 +208,15 @@
let hoverKey = '';
let hoverTimer: ReturnType<typeof setTimeout> | null = null;
// The empty board cell the dragged tile is currently aimed at, highlighted as a drop
// target while carrying a tile over the board (Stage 17). Null over an occupied cell.
// target while carrying a tile over the board. Null over an occupied cell.
let dropTarget = $state<{ row: number; col: number } | null>(null);
// Rack reordering (Stage 17): while a rack tile is dragged, reorderDragId is its stable id
// Rack reordering: while a rack tile is dragged, reorderDragId is its stable id
// (so the rack hides it — the ghost stands in) and reorderTo is the drop slot over the rack
// (a gap opens there). Only when no tiles are pending, so the order is a clean permutation.
let reorderDragId = $state<number | null>(null);
let reorderTo = $state<number | null>(null);
// While a placed (pending) board tile is dragged to relocate it, draggingPend is its cell —
// hidden from the board (the ghost stands in) like a lifted rack tile (Stage 17).
// hidden from the board (the ghost stands in) like a lifted rack tile.
let draggingPend = $state<{ row: number; col: number } | null>(null);
let dragPointerId = -1;
@@ -245,7 +245,7 @@
drag = null;
}
function onRackDown(e: PointerEvent, index: number) {
// Tiles may be arranged on the opponent's turn too (Stage 17 #5): only placement is
// Tiles may be arranged on the opponent's turn too: only placement is
// relaxed — the preview and Make-move stay your-turn-only, so an off-turn draft is
// position-only (never scored or submitted).
if (busy || gameOver) return;
@@ -390,7 +390,7 @@
window.removeEventListener('pointerdown', onExtraPointer);
clearHover();
clearReorder();
// Flush a pending draft save so leaving mid-composition still persists it (Stage 17).
// Flush a pending draft save so leaving mid-composition still persists it.
if (draftSaveTimer) {
clearTimeout(draftSaveTimer);
void gateway.draftSave(id, serializeDraft(rackIds, placement.pending)).catch(() => {});
@@ -401,7 +401,7 @@
function onCell(row: number, col: number) {
if (swallowClick) return;
// A pending tile is recalled by a double-tap or by dragging it back to the rack, not
// by a single tap (which recalled too easily — Stage 17).
// by a single tap (which recalled too easily).
if (pendingMap.has(`${row},${col}`)) return;
if (selected != null) {
// A committed tile already sits here: keep the rack selection so a stray tap
@@ -418,7 +418,7 @@
scheduleDraftSave();
}
// relocatePending moves a placed-but-unsubmitted tile from one board cell to another free one
// (a board→board drag), keeping its rack slot and any blank letter (Stage 17).
// (a board→board drag), keeping its rack slot and any blank letter.
function relocatePending(fromRow: number, fromCol: number, toRow: number, toCol: number) {
const pt = placement.pending.find((p) => p.row === fromRow && p.col === fromCol);
if (!pt) return;
@@ -459,7 +459,7 @@
function recompute() {
preview = null;
if (previewTimer) clearTimeout(previewTimer);
// Off-turn the composition is position-only: no score preview or evaluate (Stage 17 #5).
// Off-turn the composition is position-only: no score preview or evaluate.
if (!isMyTurn) return;
const sub = toSubmit(placement, dirOverride);
if (!sub) return;
@@ -473,7 +473,7 @@
}
// applyMoveResult renders the actor's own just-committed move from the response — the move, the
// post-move game and the refilled rack — without a follow-up game.state + game.history (R4).
// post-move game and the refilled rack — without a follow-up game.state + game.history.
function applyMoveResult(r: MoveResult) {
view = { game: r.game, seat: r.move.player, rack: r.rack, bagLen: r.bagLen, hintsRemaining: view?.hintsRemaining ?? 0 };
moves = [...moves, r.move];
@@ -613,7 +613,7 @@
}
// Friend state for the in-game "add to friends" item, derived from the server so it is
// correct across reloads and live-updates when a request is answered (Stage 17):
// correct across reloads and live-updates when a request is answered:
// `friends` are the caller's accepted friends; `requested` are the addressees already
// requested (pending or declined — both block a re-send and read as "request sent").
let friends = $state(new Set<string>());
@@ -985,7 +985,7 @@
min-width: 0;
}
/* A borderless icon button (like the tab bar), not a filled accent button — and disabled
while the pending word is known to be illegal (Stage 17). */
while the pending word is known to be illegal. */
.make {
min-width: 56px;
background: none;
@@ -1045,7 +1045,7 @@
pointer-events: none;
z-index: 60;
}
/* On touch the finger covers the tile, so enlarge the drag ghost ~1.5x (Stage 17). */
/* On touch the finger covers the tile, so enlarge the drag ghost ~1.5x. */
.ghost.touch {
transform: translate(-50%, -50%) scale(1.5);
}