ship/add sealed draft event support - #7133
Conversation
|
Warning Review limit reached
Next review available in: 14 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
📝 WalkthroughWalkthroughThe change adds Sealed drafts across the Rust core, WASM, server, client state, setup pages, persistence, and network protocols. Sealed drafts use six packs, enter deckbuilding, require Set pools, and run Bo1 matches. ChangesSealed draft support
Estimated code review effort: 4 (Complex) | ~60 minutes Suggested labels: Sequence Diagram(s)sequenceDiagram
participant DraftPage
participant draftStore
participant DraftAdapter
participant WASM
participant DraftSession
DraftPage->>draftStore: select Sealed and start draft
draftStore->>DraftAdapter: initializeSealed
DraftAdapter->>WASM: start_sealed_draft
WASM->>DraftSession: create six-pack Sealed session
DraftSession-->>WASM: return deckbuilding view
WASM-->>draftStore: return DraftPlayerView
draftStore-->>DraftPage: render deckbuilding state
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 7
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@client/src/pages/DraftPage.tsx`:
- Around line 427-447: Increase the touch target for each selectable label in
the localDraftKind radio group by applying a minimum 44pt size to both labels.
Update the label elements surrounding the Quick and Sealed inputs while
preserving their existing layout and selection behavior.
In `@client/src/pages/DraftPodPage.tsx`:
- Around line 190-199: Increase the touch target for the Sealed radio selector
in the draftKind label by applying at least 44pt minimum height and sufficient
padding, while preserving its existing alignment and radio behavior.
In `@client/src/stores/draftPodStore.ts`:
- Around line 137-142: The setConfig update only resets poolMode when kind
changes, allowing later setPoolMode calls to select cube for Sealed
configurations. Enforce the invariant across setConfig and setPoolMode so kind
=== "Sealed" always uses set mode, and validate the normalized configuration
before createPod submits it to WASM. Ensure setup-layer paths preserve set-based
sealed configuration.
In `@client/src/stores/draftStore.ts`:
- Line 530: Replace local Bo1/Bo3 inference with the engine-provided match
configuration: update client/src/stores/draftStore.ts:530-530 and :616-616 to
use its match type, client/src/adapter/p2p-draft-host.ts:251-251 to stop
deriving configuration from kind, and client/src/pages/DraftPage.tsx:47-47 to
show only permitted formats. Add the resolved field to the engine view and wire
it symmetrically through WASM, WebSocket, Tauri, and P2P adapters, including a
round-trip test.
In `@crates/draft-core/src/session.rs`:
- Around line 72-103: Update the sealed snapshot restore validation around the
visible per-seat and lifecycle checks to reuse the same startup configuration
validation as apply_start_draft, rejecting unsupported Swiss and
single-elimination pod sizes and invalid seat counts. Ensure persisted
DraftStatus::Drafting snapshots are accepted only when their packs and pools
represent a valid in-progress Sealed event, while preserving the existing
per-seat vector and pool-size validation.
In `@crates/server-core/src/draft_session.rs`:
- Around line 94-112: Update try_from_persisted to reject persisted snapshots
containing duplicate non-empty player_tokens before calling from_persisted,
while allowing empty tokens to repeat. Return a validation error consistent with
the existing snapshot checks, and add a restore test covering duplicate tokens
and confirming the snapshot is rejected.
In `@crates/server-core/src/draft_wire_guard.rs`:
- Around line 26-27: Update the pod_size validation in the draft wire guard to
use the caller’s DraftKind, allowing pod_size 1 for Quick drafts while requiring
at least 2 for Premier, Traditional, and Sealed drafts. Use the existing typed
DraftKind enum and composable validation helpers rather than retaining a global
minimum or adding an ad hoc special case.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: c963190a-13cc-4eeb-887c-fe24f0b7be67
⛔ Files ignored due to path filters (1)
client/src/wasm/draft_wasm.d.tsis excluded by!client/src/wasm/**,!**/*.d.ts
📒 Files selected for processing (25)
client/src/adapter/draft-adapter.tsclient/src/adapter/draftPodHostAdapter.tsclient/src/adapter/p2p-draft-host.tsclient/src/adapter/server-draft-adapter.tsclient/src/adapter/ws-adapter.tsclient/src/i18n/locales/en/draft.jsonclient/src/network/__tests__/draftProtocol.test.tsclient/src/network/draftProtocol.tsclient/src/pages/DraftPage.tsxclient/src/pages/DraftPodPage.tsxclient/src/services/draftPersistence.tsclient/src/services/quickDraftPersistence.tsclient/src/stores/draftPodStore.tsclient/src/stores/draftStore.tsclient/src/stores/multiplayerDraftStore.tscrates/draft-core/src/session.rscrates/draft-core/src/types.rscrates/draft-core/src/view.rscrates/draft-wasm/src/lib.rscrates/lobby-broker/src/protocol.rscrates/phase-server/src/main.rscrates/server-core/src/draft_session.rscrates/server-core/src/draft_wire_guard.rscrates/server-core/src/protocol.rsscripts/check-protocol-version.mjs
There was a problem hiding this comment.
Actionable comments posted: 4
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@client/src/adapter/p2p-draft-host.ts`:
- Line 2029: Remove the match_config derivation from P2PDraftHost and stop
inferring match_type from this.kind. Populate the lobby match_config using the
engine-owned draft configuration, preserving all MatchConfig fields and engine
defaults.
In `@client/src/stores/draftPodStore.ts`:
- Around line 175-178: Apply the same Sealed-pod source validation in
resumeHostedPod before restoring the persisted session and calling hostDraft.
Reject or clear any restored configuration where kind is "Sealed" and poolInput
represents a Cube source, while preserving valid set-based Sealed configurations
and existing createPod validation.
- Around line 175-178: Replace the hardcoded configError text in the Sealed and
non-set pool branch of the draft pod store with a stable localization key, or
route it through the project i18n service. Update the UI rendering of
configError to resolve that key via t(), while preserving the existing
validation and return behavior.
In `@crates/draft-core/src/session.rs`:
- Around line 81-85: Update the Sealed snapshot validation in the session
restoration flow around the DraftStatus check to reject Lobby snapshots with
non-empty pools, current_pack, or packs_by_seat. Preserve valid empty Lobby
state and existing Drafting rejection, returning the established
invalid-sealed-snapshot error for retained card state.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: 69101413-59b2-41d4-8fc5-dc1a3febc316
📒 Files selected for processing (19)
client/src/adapter/__tests__/draftPodAdapter.test.tsclient/src/adapter/__tests__/server-draft-adapter.test.tsclient/src/adapter/draft-adapter.tsclient/src/adapter/p2p-draft-host.tsclient/src/components/draft/__tests__/LimitedDeckBuilder.test.tsxclient/src/components/draft/__tests__/PackDisplay.pod.test.tsxclient/src/pages/DraftLandingPage.tsxclient/src/pages/DraftPage.tsxclient/src/pages/DraftPodPage.tsxclient/src/stores/__tests__/multiplayerDraftStore.test.tsclient/src/stores/draftPodStore.tsclient/src/stores/draftStore.tscrates/draft-core/src/session.rscrates/draft-core/src/view.rscrates/phase-server/src/main.rscrates/server-core/src/client_message_wire_guard.rscrates/server-core/src/draft_session.rscrates/server-core/src/draft_wire_guard.rscrates/server-core/src/protocol.rs
🚧 Files skipped from review as they are similar to previous changes (6)
- crates/server-core/src/protocol.rs
- client/src/pages/DraftPodPage.tsx
- crates/server-core/src/draft_session.rs
- client/src/pages/DraftPage.tsx
- crates/phase-server/src/main.rs
- client/src/stores/draftStore.ts
| tournament_format: "Swiss", | ||
| pod_policy: "Competitive", | ||
| pairings: [], | ||
| match_config: { match_type: this.kind === "Traditional" ? "Bo3" : "Bo1" }, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Remove the frontend match_config derivation.
Line 2029 infers match rules from this.kind. This duplicates engine-owned game logic in the frontend. It also drops any engine defaults beyond match_type, such as future MatchConfig fields.
Provide the lobby match_config from the engine-owned draft configuration. Do not derive it in P2PDraftHost.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@client/src/adapter/p2p-draft-host.ts` at line 2029, Remove the match_config
derivation from P2PDraftHost and stop inferring match_type from this.kind.
Populate the lobby match_config using the engine-owned draft configuration,
preserving all MatchConfig fields and engine defaults.
Source: Path instructions
| if (config.kind === "Sealed" && poolMode !== "set") { | ||
| set({ configError: "Sealed pods require a set pool" }); | ||
| return; | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Validate restored pods with the same Sealed source invariant.
Lines 175-178 protect only createPod. resumeHostedPod can still restore a persisted kind: "Sealed" session with a Cube poolInput, then pass it to hostDraft.
Reject or clear this legacy configuration before restore. A Sealed Cube pod is invalid and will later fail core startup validation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@client/src/stores/draftPodStore.ts` around lines 175 - 178, Apply the same
Sealed-pod source validation in resumeHostedPod before restoring the persisted
session and calling hostDraft. Reject or clear any restored configuration where
kind is "Sealed" and poolInput represents a Cube source, while preserving valid
set-based Sealed configurations and existing createPod validation.
Source: Path instructions
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
Localize the Sealed pool error.
Line 176 adds frontend-authored user-facing text directly in the store. Store a stable error key or use the project i18n service, then render the localized message through t() in the UI.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@client/src/stores/draftPodStore.ts` around lines 175 - 178, Replace the
hardcoded configError text in the Sealed and non-set pool branch of the draft
pod store with a stable localization key, or route it through the project i18n
service. Update the UI rendering of configError to resolve that key via t(),
while preserving the existing validation and return behavior.
Source: Path instructions
| if self.status == DraftStatus::Drafting { | ||
| return Err(DraftError::InvalidSealedSnapshot { | ||
| reason: "sealed sessions cannot be in drafting status".to_string(), | ||
| }); | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Reject retained Sealed state in Lobby.
Line 81 rejects only DraftStatus::Drafting. A Sealed snapshot in Lobby with non-empty pools, current_pack, or packs_by_seat still passes because the later checks exclude Lobby.
No valid Sealed lifecycle produces card state before start. Reject retained card state for Lobby snapshots. Otherwise a restored lobby can expose stale pools or packs through the player view before the next start replaces them.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/draft-core/src/session.rs` around lines 81 - 85, Update the Sealed
snapshot validation in the session restoration flow around the DraftStatus check
to reject Lobby snapshots with non-empty pools, current_pack, or packs_by_seat.
Preserve valid empty Lobby state and existing Drafting rejection, returning the
established invalid-sealed-snapshot error for retained card state.
Source: Path instructions
Summary by CodeRabbit