feat(social): asymmetric per-user block, in-game block control, admin lists #83
Reference in New Issue
Block a user
Delete Branch "feature/in-game-block-and-friend-ux"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What
In-game block control + asymmetric, non-destructive per-user block semantics, plus admin social lists.
A per-user block is now one-directional and silent: the blocker stops receiving everything from the blocked user (chat, nudge, friend requests, invitations) and the matchmaker never pairs them, while the blocked user notices nothing — their sends still persist by the normal rules but are never delivered or surfaced to the blocker (born-read). A block overrides but no longer deletes the friendship (an unblock restores it), and instant-reads any unread the blocked user had left.
Highlights
social,lobby): a directionalblockExistsguard across chat / nudge / friends / invitations — store-but-hide for the blocked→blocker direction, refuse for blocker→blocked; matchmaker excludes a block-related pair (both directions) from auto-match;user_blocked/user_unblockednotifications to the blocker only (in-app only).Tests
Backend unit + full integration (new
block_test.go, updated invitation/block/admin tests), matchmaker unit, adminconsole render; UI svelte-check + unit + build + full Playwright e2e (146 passed, incl. a new block-flow test). All green locally.Notes
No DB migration and no FlatBuffers/proto change (reuses
NotificationEvent.account), so the test contour needs no schema wipe.Make a per-user block one-directional and non-destructive: the blocker stops receiving everything from the blocked user (chat, nudge, friend requests, invitations) and the matchmaker never pairs them, while the blocked user notices nothing — their sends still persist by the normal rules but are never delivered or surfaced (born-read). A block no longer deletes the friendship (an unblock cleanly restores it) and instant-reads any unread the blocked user had left for the blocker. - backend: a directional blockExists guard across chat/nudge/friends/invitations (store-but-hide for the blocked->blocker direction, refuse blocker->blocked); the matchmaker excludes a block-related pair (both directions) from auto-match; user_blocked/user_unblocked notifications to the blocker only (in-app only). - ui: the opponent score card gains a block ✖️ control mirroring add-friend (red "Block?" confirm, mutual-hide while confirming, struck name, hidden chat composer when blocked); optimistic apply + event confirm + rollback for both. - admin: the user card gains cross-linked blocks / blocked-by / friends lists. - docs: FUNCTIONAL(+ru), ARCHITECTURE §10 + decision record, UI_DESIGN, PRERELEASE.