Stage 8: UI social/account/history surfaces #9

Merged
developer merged 7 commits from feature/stage-8-social-account-history into master 2026-06-03 21:25:28 +00:00
Owner

Stage 8 — UI: social, account & history surfaces

Wires the deferred Stage 7 surfaces end-to-end (client → gateway transcode → backend REST → existing domain services): friends (incl. one-time codes), per-user blocks, friend-game invitations, profile editing + email binding, the statistics screen, and the in-game history + GCG export.

Key decisions (interviewed):

  • Friends: one-time 6-digit codes (12 h, single-use) and play-gated requests (shared game required; an explicit decline is permanent; an ignored request lapses after 30 days; a code bypasses a decline). Migration 00006 adds friend_codes and the declined status.
  • Lobby notification badge: poll + a generic notify push event.
  • GCG export: finished-only (ErrGameActive); share or download.
  • Guests: durable-only surfaces. Language stays a single Settings control; profile editing validated on both UI and backend.

Review polish (3 iPhone rounds): copyable friend code; the notification-badge render fix; Safari flex-overflow (min-width:0); display-name / away (≤12 h) / UTC-offset-timezone / email validation with a disabled Save + red-bordered fields; finished-game inert footer + trimmed menu + no last-word highlight; chat ⬆️/🛎️ icon buttons; keyboard-aware modals (visualViewport); every picker a native <select> for cross-platform consistency; a required game type (smart default → TODO-6).

Docs updated (PLAN, ARCHITECTURE, FUNCTIONAL +ru, UI_DESIGN, TESTING, module READMEs); TODO-5 (QR friend codes) and TODO-6 (smart game-type default) logged. All CI green (go-unit + integration + ui-test).

## Stage 8 — UI: social, account & history surfaces Wires the deferred Stage 7 surfaces end-to-end (client → gateway transcode → backend REST → existing domain services): friends (incl. one-time codes), per-user blocks, friend-game invitations, profile editing + email binding, the statistics screen, and the in-game history + GCG export. **Key decisions (interviewed):** - Friends: one-time 6-digit codes (12 h, single-use) **and** play-gated requests (shared game required; an explicit decline is permanent; an ignored request lapses after 30 days; a code bypasses a decline). Migration `00006` adds `friend_codes` and the `declined` status. - Lobby notification badge: poll **+** a generic `notify` push event. - GCG export: finished-only (`ErrGameActive`); share or download. - Guests: durable-only surfaces. Language stays a single Settings control; profile editing validated on both UI and backend. **Review polish (3 iPhone rounds):** copyable friend code; the notification-badge render fix; Safari flex-overflow (`min-width:0`); display-name / away (≤12 h) / UTC-offset-timezone / email validation with a disabled Save + red-bordered fields; finished-game inert footer + trimmed menu + no last-word highlight; chat ⬆️/🛎️ icon buttons; keyboard-aware modals (`visualViewport`); every picker a native `<select>` for cross-platform consistency; a required game type (smart default → TODO-6). Docs updated (PLAN, ARCHITECTURE, FUNCTIONAL +ru, UI_DESIGN, TESTING, module READMEs); TODO-5 (QR friend codes) and TODO-6 (smart game-type default) logged. All CI green (go-unit + integration + ui-test).
developer added 7 commits 2026-06-03 21:25:16 +00:00
Stage 8: UI social/account/history surfaces
Tests · Go / test (push) Successful in 7s
Tests · Integration / integration (push) Successful in 13s
Tests · UI / test (push) Successful in 16s
d733ce3119
Wire the deferred Stage 7 surfaces end-to-end (UI -> gateway transcode ->
backend REST -> existing domain services): friends (incl. one-time friend
codes), per-user blocks, friend-game invitations, profile editing + email
binding, the statistics screen, and the in-game history + GCG export.

Friends gain two add paths (interview decision, a deliberate plan change):
one-time 6-digit codes (friend_codes table, 12h TTL, single-use, rate-limited
redeem); and play-gated requests (shared game required) where an explicit
decline is permanent, an ignored request lapses after 30 days, and a code
bypasses a decline. Migration 00006 widens friendships_status_chk and adds
friend_codes.

Lobby notification badge is poll + push: a new generic `notify` event drives
it live; the client polls on open/focus. Language stays a single Settings
control that writes through to the durable account's preferred_language. GCG
export is finished-only (game.ErrGameActive) and shares/downloads the .gcg file.

Tests: backend unit + inttest (friend gate/decline/code, ListInvitations,
GetStats, GCG gate), gateway transcode round-trips + notify constructor, UI
vitest (codecs, win-rate, share choice) + Playwright social specs. Docs: PLAN
(Stage 8 done + refinements + TODO-5), ARCHITECTURE, FUNCTIONAL(+ru), UI_DESIGN,
TESTING, module READMEs.
Stage 8 polish: profile validation, finished-game UI, badge + Safari fixes
Tests · Go / test (push) Successful in 7s
Tests · Integration / integration (push) Successful in 11s
Tests · UI / test (push) Successful in 17s
acbb2d8254
Owner-review follow-up on the Stage 8 branch:
- Friend code is copyable (📋 + toast). The lobby notification badge is fixed —
  it had inherited the hamburger-bar style — into a proper round count dot.
- Safari: min-width:0 on flex text inputs (friend code, profile, chat) so they
  shrink instead of pushing the adjacent button off-screen.
- Profile editing is validated on both the UI and the backend: display-name format
  (letters joined by single space/./_ separators, no leading/trailing/adjacent
  separators, <=32 runes), a UTC-offset timezone picker (account.ResolveZone parses
  ±HH:MM or a legacy IANA name), a 10-minute away grid capped at 12h (wrap-aware),
  and email format; Save is disabled and invalid fields red-bordered until valid.
  Language stays in Settings.
- In a game, an "add to friends" menu item flips to a disabled "request sent"; chat
  send/nudge became ⬆️/🛎️ icon buttons.
- A finished game drops its last-word highlight, hides Check word / Drop game,
  disables zoom, and draws an inert (greyed) footer instead of hiding it.

Tests: account validators (name/away/zone), UI profileValidation, e2e for the
finished-game footer/menu and the copy control. Docs (PLAN, ARCHITECTURE,
FUNCTIONAL +ru, UI_DESIGN) updated for the display-name rule, UTC-offset timezone
and the 12h away window.
Second owner-review pass (iPhone simulator):
- Chat (and the modal) are sized in dvh so they shrink above the software keyboard,
  keeping the start of the conversation on screen instead of pushed off the top.
- The profile away window returns to a native <input type="time" step="600"> (the iOS
  wheel with 10-minute steps) instead of separate dropdowns; the timezone stays a
  native offset <select>.
- A finished game reserves the rack's height (min-height) so the footer no longer
  collapses when the final rack is empty — no layout jump versus an active game.
- New-game "play with friends" is made compact: a searchable, bounded-scroll friend
  list, the game-type / move-time / hints controls as native selects in one row
  (labels above), and Send invitation pinned at the bottom — it scales to many friends.
Third owner-review pass (iPhone):
- Modals (and the chat) size their backdrop to window.visualViewport, so they stay
  fully above the software keyboard (dvh alone left the sheet partly behind it).
- On the owner's call, every profile / new-game picker is a native <select> for
  consistent cross-platform behaviour: the away window returns to hour + 10-minute
  selects (which also avoids the iOS time-wheel "clear" button), alongside the offset
  timezone and the game-type / move-time / hints selects. Native time/wheel inputs
  render differently per OS and cannot be forced to match.
- New-game "play with friends" has no preselected game type — an explicit, required
  pick (empty placeholder); Send invitation stays disabled until both a type and a
  friend are chosen. A smart default (from play history / language) is TODO-6.
Stage 8: regression tests for the review-round refinements
Tests · Go / test (push) Successful in 6s
Tests · Integration / integration (push) Successful in 11s
Tests · UI / test (push) Successful in 18s
Tests · Go / test (pull_request) Successful in 6s
Tests · Integration / integration (pull_request) Successful in 12s
Tests · UI / test (pull_request) Successful in 18s
695508042a
Lock the polish behaviours so a future edit surfaces as a failing test:
- backend: UpdateProfile now rejects a bad name layout, an away window over 12h, and
  a malformed offset timezone (confirming it wires the Stage 8 validators); a new
  integration test accepts and resolves a "+03:00" offset timezone.
- e2e (mock): the lobby notification badge count, the play-with-friends required
  game type + invitation send, the in-game add-to-friends flipping to a disabled
  "request sent", the profile-edit invalid-name Save guard, and the chat send/nudge
  icon buttons.
developer merged commit 1012fb47a0 into master 2026-06-03 21:25:28 +00:00
developer deleted branch feature/stage-8-social-account-history 2026-06-03 21:25:28 +00:00
Sign in to join this conversation.
No Reviewers
No Label
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: developer/scrabble-game#9