Repository navigation
Architecture Design
Current release scope: guest-only game and owner-only GitHub admin PWA. Configure server-only WORDPAIRS_GITHUB_CLIENT_ID/WORDPAIRS_GITHUB_CLIENT_SECRET and the exact canonical origin for administration. Public OpenAI/member sign-in, user delegation, nominations and community-submission UI are inactive. Public pages have no install metadata/controls; admin manifest/worker launch at /admin. Earlier feature counts and provider/delegation instructions below describe their historical snapshots. Current active browser tests use playwright.pwa.config.ts; superseded community cases are retained under docs/testing/historical/.
The 31 October release amendment limits new room capacities and match rosters to 2 through 10 players. The separate limit of 25 observers remains, for at most 35 recipients in a newly admitted room. Preserve historical larger running matches and stored results; above-limit legacy waiting/countdown rooms retain readable membership and Leave, block further oversized admission/start, and explain the compatibility state. Enforce new-write safeguards through a forward migration rather than changing existing migration file bytes or deleting historical data.
Requirements traceability, DDD component split, and design-pattern class views
Version 1.1 · 27 October 2026 · Derived from Requirements v2.6 and the administration/ACL extension
This document maps every baseline functional requirement (FR-01–FR-22) and technical requirement (TR-01–TR-31) to bounded contexts, application components and logical classes. Names below describe responsibilities, not mandatory programming-language syntax. Coding Phases 1–6 are complete; the administration extension is documented separately below. Vercel and Supabase/Postgres remain the selected deployment and persistence target (TR-20–TR-24), with hosted deployment work in Phase 7. The implementation is a Next.js/TypeScript modular monolith with the Phase 0-approved interfaces. The diagrams are SVG assets embedded here; the current source layout is documented in local development.
The earlier phone PWA extension described public installation and a root worker. It is historical for this release; the current admin-only PWA keeps private API and administration data out of its cache.
The historical administration and ACL extension, requested 27 October 2026, described /admin/users, bootstrap administrators and delegated role assignment. Current administration uses fixed-owner GitHub authorization; role delegation is inactive. UI visibility is never the permission boundary.
- Domain policies contain each business rule once and import no Next.js, React, Supabase, or transport code.
- Application use cases orchestrate domain decisions and ports; route handlers validate/translate transport input and call use cases.
- A room aggregate is the serialization boundary for membership, readiness, countdown, and roster state. A match/round aggregate owns answer progression and scoring.
- Repository transactions, unique/check constraints, row locking or compare-and-swap, idempotency, and transactional outbox writes protect concurrent commands.
- Realtime is delivery, not authority. Clients render authorized projections and may retry with the same command ID.
- Read projections have explicit field allowlists for players, observers, moderators, and the public landing page.
- Clock, randomness, identity verification, deadline scheduling, storage, and event delivery are ports, so domain and use-case tests can use deterministic fakes.
The component view places identity, room/lobby, gameplay, content/moderation, and public read models behind the application boundary. The domain class map shows representative core classes and their relationships in each context, including identity, catalog/moderation, reactions, and public/player projections. The traceability tables below are the complete requirement-to-class index; the class diagrams show the design-pattern structures and principal relationships rather than repeating every class name from every row. The room and game contexts are separate domain modules with their own aggregates and repositories. Shared identity is referenced by stable PlayerId values. Content review produces approved catalog records consumed by gameplay through a read-only catalog port. The public landing context reads curated projections and cannot query private room or answer state.
The diagram includes central classes from Identity & Profile, Room & Lobby, Gameplay, Content & Moderation, and Read Models/Room Events, along with named policies and infrastructure ports. Policies encode the resolved v2.6 product rules for answer matching, match length, tiebreak treatment, and public leaderboard contract. Domain rules do not depend on persistence.
The command path validates the command key, locks/reloads the aggregate in one transaction, applies one domain decision, saves the new version and idempotency result, and writes an outbox event before commit. A versioned deadline command makes stale timer callbacks harmless. Outbox delivery retries by event ID and cannot reapply a command.
| Requirement | Bounded context / application component | Primary logical classes and responsibilities |
|---|---|---|
| FR-01 Room access | Identity & Profile; Room & Lobby |
CreateRoom, JoinRoom, QuickMatch, Room, RoomCapacity, RoomCode, SeatAssignmentPolicy
|
| FR-02 Player profile | Identity & Profile |
PlayerProfile, PlayerId, IconId, UpdateProfile
|
| FR-03 Lobby | Room & Lobby |
Room, PlayerSeat, Observer, LobbyProjection, RoomInvite
|
| FR-04 Predefined content | Content & Moderation; Gameplay |
WordPair, Category, HintSet, AcceptedAnswerSet, CatalogRepository
|
| FR-05 Relationship categories | Content & Moderation |
Category, CategoryId, WordPair
|
| FR-06 Category backgrounds | Content & Moderation; Presentation adapter |
CategoryBackground, AssetReference, CategoryCatalog
|
| FR-07 Category selection | Gameplay |
StartMatch, Match, AnchorAssignmentPolicy, RandomSource, CategorySelection
|
| FR-08 Answer stages | Gameplay |
Round, HintStage, SubmitAnswer, RoundProgressionPolicy, HintAudiencePolicy
|
| FR-09 Scoring | Gameplay |
ScoringPolicy, ScoreAward, HintStage, PlayerRoundResult
|
| FR-10 Score lock and elapsed time | Gameplay |
Round, SolveRecord, ElapsedTime, Clock
|
| FR-11 Live round scorecard | Gameplay; Read projections |
RoundScorecardProjection, PlayerRoundResult, AuthorizedViewMapper
|
| FR-12 Round reveal | Gameplay |
RevealRound, Round, RoundRevealProjection, TargetAnswer
|
| FR-13 Round summary | Gameplay; Read projections |
RoundSummaryProjection, MatchStanding, Score
|
| FR-14 Game end and tiebreak | Gameplay |
CompleteMatch, Match, MatchLengthPolicy, StandingPolicy, TiebreakPolicy
|
| FR-15 Responsive screens | Web Presentation |
ProfilePage, LobbyPage, RoundPage, ScorecardView, responsive UI components; server-side rules remain in domain/use cases |
| FR-16 Future answer nominations | Content & Moderation |
NominateCandidate, CandidateNomination, NominationThresholdPolicy, ModerationCase
|
| FR-17 Category and pair suggestions | Content & Moderation |
SubmitCategorySuggestion, CategorySuggestion, WinEligibilityPolicy, ModerationCase, CatalogApprovalPolicy
|
| FR-18 Identity modes | Identity & Profile |
AuthenticateWithOidc, ContinueAsGuest, IdentityProviderPort, OidcVerifier, GuestIdentity, PlayerProfile
|
| FR-19 Lobby discovery and matching | Room & Lobby |
BrowseLobbies, QuickMatch, JoinRoom, Room, ObserverPromotionPolicy, ReadinessPolicy, DeadlineScheduler
|
| FR-20 Full-room observer mode | Room & Lobby |
JoinAsObserver, Observer, FollowedPlayerId, ObserverPromotionPolicy, Room
|
| FR-21 Emoji reactions | Gameplay; Realtime adapter |
PublishReaction, EmojiReaction, ReactionAllowlist, RoomEventPort
|
| FR-22 Public landing page | Public Landing; Read projections |
LandingPageProjection, LeaderboardProjection, PublicLobbyProjection, PublicFieldAllowlist, GameplayRulesContent
|
| Requirement | Component / pattern | Primary logical classes, ports, and safeguards |
|---|---|---|
| TR-01 Authoritative room state | Room & Lobby and Gameplay / aggregate roots |
Room and Match/Round aggregates; RoomRepository and MatchRepository; server-side room/game command handlers |
| TR-02 Real-time synchronization | Realtime delivery / outbox |
OutboxEvent, OutboxPublisher, RoomEventPort, authorized projection mappers |
| TR-03 Submission ordering | Gameplay / deterministic domain service |
SubmitAnswer, AcceptedSubmission, AcceptanceSequence, SubmissionOrderingPolicy, Clock
|
| TR-04 Answer validation | Gameplay / strategy policy |
AnswerMatchingPolicy, AcceptedAnswerSet, NormalizeAnswer, SubmitAnswer
|
| TR-05 Answer confidentiality | Gameplay / audience-specific projection |
HintAudiencePolicy, RoundProjectionMapper, RoundRevealProjection, TargetAnswer visibility guard |
| TR-06 Curated content integrity | Content & Moderation / invariant |
WordPair, Category, CatalogApprovalPolicy, PlayableContentValidator, DB constraints |
| TR-07 Background rendering | Content & Presentation adapter |
CategoryBackground, AssetReference, contrast overlay and fallback renderer |
| TR-08 Clock consistency | Shared ports / authoritative time |
Clock, RoundStartedAt, AcceptedAt, ElapsedTime
|
| TR-09 Connection handling | Realtime / retry-safe commands |
CommandId, IdempotencyStore, ReconnectRoom, RoomSnapshotProjection, ConnectionPolicy
|
| TR-10 Room code handling | Room & Lobby / transaction boundary |
RoomCode, JoinRoom, RoomCapacity, RoomRepository, SeatAssignmentPolicy
|
| TR-11 Mobile input | Web Presentation | Accessible responsive controls; RoundPage; adapter-independent command API |
| TR-12 Accessibility and readability | Web Presentation | Accessible component set, semantic status labels, focus management, contrast validation |
| TR-13 Anchor assignment | Gameplay / injected randomness |
StartMatch, AnchorAssignmentPolicy, RandomSource, immutable RosterSnapshot
|
| TR-14 Candidate nomination and moderation | Content & Moderation |
CandidateNomination, NominationThresholdPolicy, ModerationCase, NominationRepository
|
| TR-15 Category suggestion eligibility and review | Content & Moderation |
WinEligibilityPolicy, CategorySuggestion, ModerationCase, CatalogApprovalPolicy
|
| TR-16 Identity and authentication | Identity & Profile / adapter |
IdentityProviderPort, OidcVerifier, GuestIdentity, PlayerProfileRepository, token-validation policy |
| TR-17 Lobby discovery and matching | Room & Lobby / serialized assignment |
BrowseLobbies, QuickMatch, JoinRoom, RoomRepository, transaction and capacity constraints |
| TR-18 Observer perspective and permissions | Room & Lobby / authorization projection |
Observer, FollowedPlayerId, ObserverProjectionPolicy, read-only command authorization |
| TR-19 Emoji reaction delivery | Gameplay / allowlisted event |
EmojiReaction, ReactionAllowlist, RoomEventPort, event audience mapper |
| TR-20 Vercel deployment target | Deployment adapter / platform configuration | Two isolated Vercel projects with production targets, reviewed-SHA staging before production, build artifact manifest |
| TR-21 Free-tier operation | Infrastructure boundary |
DeploymentConfig, resource-budget checks, approved service allowlist; no paid add-ons |
| TR-22 Persistence and real-time room state | Persistence and Realtime adapters |
SupabaseRoomRepository, SupabaseMatchRepository, Postgres, RoomEventPort
|
| TR-23 Provisioning and schema changes | Operations adapter |
ProvisioningCommand, migration runner, environment configurator, safe rerun/idempotency checks |
| TR-24 GitHub Actions availability | Deployment workflow | Vercel Git integration; manually invoked authenticated provisioning; no Actions dependency |
| TR-25 Direct dependencies and attribution | Build / supply-chain component |
package.json, lockfile, AttributionManifest, docs/ATTRIBUTIONS.md
|
| TR-26 Mock-first test gate | Test architecture |
DomainPolicyTests, UseCasePortFakes, mocked test gate; production build test gate |
| TR-27 Per-build software bill of materials | Build / artifact generation |
CycloneDxGenerator, Lockfile, BuildCommit, SwbomArtifact, deployment verification |
| TR-28 SWBOM in release archive | Release packaging |
ReleasePackager, SwbomArtifact, commit/build identity verifier, archive manifest |
| TR-29 Project license | Release packaging / legal metadata |
LicenseArtifact, GPL-2.0-only metadata, third-party attribution inclusion |
| TR-30 Public landing data boundary | Public Landing / CQRS-lite projection |
LandingPageProjection, public query port, PublicFieldAllowlist, no private repository exposure |
| TR-31 Testable domain and concurrency boundaries | Modular monolith / ports-and-adapters, aggregate transaction, idempotency, outbox |
RoomCommandHandler, TransactionRunner, RoomRepository, IdempotencyStore, OutboxRepository, pure policies |
| Pattern | Application in Wordpairs | Test seam / concurrency property |
|---|---|---|
| DDD bounded contexts in a modular monolith | Identity & Profile, Room & Lobby, Gameplay, Content & Moderation, Public Landing | Context APIs can be unit-tested; no distributed consistency or paid service needed |
| Aggregate root |
Room serializes seat/readiness/countdown changes; Match/Round serializes answer and score transitions |
Pure transition tests; invariant checks; one transaction per aggregate command |
| Ports and adapters | Repositories, OIDC verifier, clock, randomness, deadline scheduler, and event delivery are interfaces | Fake ports permit deterministic tests and mock-first validation |
| Strategy/policy objects | Answer match, scoring, anchor, promotion, readiness, tiebreak, and public projection policies | Each rule has isolated examples and edge-case tests, without framework setup |
| Command handler + Unit of Work | Validate, load under lock, decide, persist aggregate and related records, commit | Competing writes serialize; no partially persisted domain transition |
| Optimistic version + pessimistic lock where needed | Aggregate version rejects stale commands; row lock serializes contested seats/room transitions | Parallel join/readiness tests prove capacity and state invariants |
| Idempotent command | Client-supplied command ID stored with result in same transaction | Retry returns the original result and creates no second effect |
| Transactional outbox | Persist event in same transaction as aggregate change; publish after commit | No phantom notification on rollback; retries deduplicated by event ID |
| CQRS-lite projections | Read DTOs differ for player, observer, moderator, and public page; same Postgres source | Allowlist tests prove private fields cannot escape a projection |
| Versioned deadline command | Idle prompt, holdout warning, and countdown callbacks carry aggregate version/deadline | Stale callback becomes a no-op; fixed clock/scheduler fakes support tests |
Vercel hosts the web application selected by the architecture decision record; the selected v2.6 stack is Next.js/TypeScript, recorded in the Phase 0-approved ADR. Supabase Postgres is the durable source of truth; Supabase Realtime transports committed allowlisted outbox events. Domain code stays inside the application modules. A deadline scheduler is accessed through a port and must use a supported free-tier mechanism with durable, idempotent callbacks; a serverless process or browser timer is never treated as the authority. Build and release pipelines validate tests and the commit-matched SWBOM per the technical requirements.
wordpairs is logical staging and wordpairs-j9jf is production. Each uses its own Vercel production target, stable domain and Supabase database. The same reviewed source must pass staging before production; Git integration must not skip this order. Earlier single-project Preview proposals are historical. The detailed mapping and migration/scheduler checks are in hosting execution.
The v2.6 requirements resolve product behavior affecting active AC outcomes, including the exactly two-player holdout exception. Phase 0 approves technical interfaces, schema/security, and transaction contracts. Vercel/Supabase account, topology, and deployment verification occur only at Phase 7 after coding Phases 1–6; deployed artifacts never provide AC coverage.
This matrix intentionally covers FR-01 through FR-22 and TR-01 through TR-31, including responsive/accessibility requirements, operational delivery, supply-chain requirements, and public-data privacy. Acceptance criteria remain the executable coverage ledger; each requirement maps here to implementation boundaries and classes, while the AC-to-test matrix maps it to test cases. Requirements changes should update both mappings in the same review.
The temporary local runtime uses the existing game database and an isolated Realtime internal database. A loopback gateway exposes app and approved Realtime paths through one HTTPS origin. A serialized authenticated worker advances durable deadlines and publishes bounded outbox batches independently of browser reads. Notifications remain per-profile invalidation metadata; all state reads still enforce actor authorization. See live runtime and UI verification. Hosted Phase7 provisioning remains separate.
The repeatable loopback HTTPS UI harness gives its separate Realtime broker a separate migrated game database and outbox. Sharing the public runtime's game database across two brokers would let one publisher acknowledge events delivered to the other broker, losing notifications. Strict-TLS application-URL identity verification precedes publisher startup; cleanup failures preserve owned recovery receipts. The original public game database remains intact.
UI-DEC-01..08 implementation documents the additional moderation states, identity/session-bound memory state, acknowledged result consumption and discovery recovery. Content commands still commit under fresh server roles, expected versions, idempotency and the existing audit/outbox transaction. No-solver summary jobs now use the existing stage dispatcher for a3-second automatic-advance delay; late workers start a full initial answer interval, and catalog revision races preserve retryability rather than losing the job. See the linked execution receipt for the reviewed source snapshot and fixture/SQL boundaries.
Generated from MCP requirements wiki export.
- Home
- Guest Game and GitHub Admin PWA
- Functional Requirements
- Technical Requirements
- Testing Requirements
- TR per FR Mapping
- Requirements Matrix
- Wordpairs
- Local Development
- Testing and Evidence
- Administration and Access Control
- Requirements Baseline v2.8
- Architecture Decision Record
- Architecture Design
- Architecture Patterns
- Content Moderation
- Deployment and Release Plan
- Acceptance Criteria Gap Analysis
- Acceptance Criteria Test Inventory
- Implementation Plan
- Phase 0 Execution
- Phase 0 Interface and Data Contracts
- Phase 1A Execution
- Phase 1 Execution
- Phase 2 Execution
- Phase 3 Execution
- Phase 4 Execution
- Phase 5 Execution
- Phase 6 Execution
- Optional Phase 6 Human Feedback
- Historical Chromium Crash Diagnosis
- Completed Coding Goal and Review Agreement
- Third Party Attributions
- Software Bill of Materials Contract
- Phone Installation and PWA
- Live Multiplayer Runtime and UI Integration
- UI Test Case Index
- UI Design Coverage
- UI Criterion Gaps
- UI Design Questions
- UI Test Persistence
- TEST-ACCESSIBLEGAMECONTROLS-044 UI Case
- TEST-ACLAUTHORIZATION-132 UI Case
- TEST-ADMINUI-136 UI Case
- TEST-AUTHORITATIVEANSWERHANDLING-045 UI Case
- TEST-BROWSEOPENLOBBIES-022 UI Case
- TEST-CATALOGVERSIONING-133 UI Case
- TEST-CATEGORYART-005 UI Case
- TEST-CATEGORYCHOICE-011 UI Case
- TEST-CATEGORYSUGGESTIONUNLOCK-019 UI Case
- TEST-CONFIGUREDCAPACITY-024 UI Case
- TEST-CONNECTIONRECOVERY-109 UI Case
- TEST-CONTENTVALIDATION-016 UI Case
- TEST-DEEPLINKJOINANDFULLROOM-026 UI Case
- TEST-FINALSTANDINGS-013 UI Case
- TEST-FIRSTCATEGORY-004 UI Case
- TEST-FREETIERQUOTAHANDLING-037 UI Case
- TEST-FULLROOMOBSERVER-027 UI Case
- TEST-GUESTPLAY-021 UI Case
- TEST-HINTPROGRESSION-009 UI Case
- TEST-HINTSCORING-007 UI Case
- TEST-HOLDOUTWARNINGANDREMOVAL-032 UI Case
- TEST-IDLELOBBYREADINESSPROMPT-033 UI Case
- TEST-INROUNDEMOJIREACTION-029 UI Case
- TEST-LANDINGPAGEPUBLICDATA-050 UI Case
- TEST-LIVESCORECARD-010 UI Case
- TEST-MODERATIONANDCATALOGBOUNDARY-047 UI Case
- TEST-NOHINTSOLVE-006 UI Case
- TEST-NOMINATIONELIGIBILITY-017 UI Case
- TEST-NOMINATIONMODERATION-114 UI Case
- TEST-NOMINATIONTHRESHOLDANDMODERATION-018 UI Case
- TEST-OBSERVERPERSPECTIVEANDPERMISSIONS-028 UI Case
- TEST-OIDCTOKENVALIDATION-046 UI Case
- TEST-OPENAIOIDCPROFILE-020 UI Case
- TEST-ORIENTATION-015 UI Case
- TEST-PLAYERLIMIT-002 UI Case
- TEST-PRECOUNTDOWNOBSERVERPROMOTION-030 UI Case
- TEST-PROFILEICON-003 UI Case
- TEST-PUBLICGAMELANDINGPAGE-043 UI Case
- TEST-PWAINSTALL-137 UI Case
- TEST-PWAPRIVACY-138 UI Case
- TEST-QUICKMATCH-023 UI Case
- TEST-READYCOUNTDOWNANDROSTERLOCK-031 UI Case
- TEST-ROOMINVITATIONS-025 UI Case
- TEST-ROOMJOINING-001 UI Case
- TEST-ROOMSYNC-139 UI Case
- TEST-ROUNDSUMMARY-012 UI Case
- TEST-SUGGESTIONREVIEW-115 UI Case
- TEST-TIMETIEBREAK-014 UI Case
- TEST-UNSOLVEDRESULT-008 UI Case
- UI Gap Decisions and Synchronization
- TEST-ACCESSIBILITYDETAILS-144 UI Case
- TEST-CANDIDATEHOLD-141 UI Case
- TEST-LOBBYMATCHING-117 UI Case
- TEST-NAVIGATIONDRAFTS-142 UI Case
- TEST-NOSOLVERFALLBACK-146 UI Case
- TEST-REQUESTFEEDBACK-143 UI Case
- TEST-RESPONSIVEMATRIX-145 UI Case
- TEST-REVIEWCHANGES-140 UI Case
- TEST-ROOMCODES-110 UI Case
- UI Gap Implementation Plan
- UI Gap Implementation and Evidence
- Contest Readiness
- Hostile Validation Evidence
- Category Artwork
- 10-Player Release Completion Plan
- Deadline Report and Token Accounting
- Deadline Report Supporting Evidence
- Deadline Timeline and Review Finding Analysis
- Stopped Wordpairs Release Handoff