Commit Graph

2 Commits

Author SHA1 Message Date
gamer147
ba7040580f fix(arena-colosseum): tips + colosseum_id wiring + round-aware time derivation
Three fixups the Phase 1-3 work missed (would bite the first time an admin
flipped on a real event):

* IsDisplayTips + TipsId added to ColosseumSeasonConfig. Drives
  Wizard/ColosseumEntryInfoTask.cs:129 (NeedsFirstTips = is_display_tips == 1).
  The wire DTO already had the properties; the season config didn't carry
  them, so admins had no way to gate the first-time tutorial tip popup.
* colosseum_id is now emitted from SeasonId. Wire field was always-absent
  before (DTO had the property but builder never set it); client fell back
  to 0 and couldn't disambiguate cups.
* ColosseumLobbyInfoBuilder.Build now takes ColosseumRoundsConfig + nowUtc
  and derives the wire is_round_period / now_round / next_round / start_time
  / end_time from the rounds schedule against the current clock. Previous
  hardcode (is_round_period: true, now_round: 1, event-window dates) would
  have shown "Round 1 ends 2026-07-31" instead of the actual round's end.
  Per the client parser at ColosseumEntryInfoTask.cs:111-126:
    - inside a round → emit that round's window + is_round_period=true
    - between rounds → emit next round's start as start_time + next_round
    - pre-event → next_round=1, start_time=event start
    - post-event → anchor to last round so the client doesn't NRE
    - no rounds configured → fall back to event-level window

Why these were missed: I implemented ColosseumSeasonConfig from the plan's
explicit field list rather than cross-checking against the captured
colosseum.json wire shape; I added ColosseumId to the wire DTO without
wiring the builder side; and no test exercised a mid-event scenario with
realistic dates — Phase 2's E2E hand-edits run.RoundId via
PromoteRunToRoundAsync instead of letting the controller derive it.

* 10 new builder unit tests cover off-season / mid-round / between-rounds /
  pre-event / post-event / empty-rounds-fallback + the new field surfacing.
  Full suite: 1355/1355 (was 1345 + 10).
2026-06-13 13:44:10 -04:00
gamer147
110867358c feat(arena-colosseum): lobby + constructed entry (phase 1)
Closes 5 of arena-colosseum's 16 spec shapes (1/16 → 6/16). Lobby reads
(/top, /get_fee_info, /event_info) render an empty "no event scheduled"
payload by default; /entry + /register_deck activate via admin-flipped
ColosseumSeason + ColosseumRounds config sections.

* Schema: ViewerArenaColosseumRun standalone table (unique on ViewerId)
  with jsonb run-state columns mirroring ViewerArenaTwoPickRun.
* Config sections: ColosseumSeasonConfig (event-level), ColosseumRoundsConfig
  (the 3-round bracket). Empty defaults — IsColosseumPeriod=false.
* Migration AddArenaColosseumRun (DDL only; seed rows come from the section
  ShippedDefaults via EnsureSeedDataAsync).
* DTOs: ColosseumLobbyInfo (round-level, /top + /get_fee_info), ColosseumEventInfo
  (event-level, /event_info), ColosseumOwnStatus (shared status block),
  ColosseumEntryRef, ColosseumFeeList, ColosseumUserDeck, ColosseumBattleResults,
  ColosseumRoundDetail + ColosseumGroupRow. EventInfoResponse uses explicit
  [JsonPropertyName("1"|"2"|"3")] for the string-keyed rounds shape per spec.
* Controller: ArenaColosseumController replaces the 1-action stub with
  the five lifecycle endpoints. /top emits leader_skin_id even when 0
  (project_wire_null_policy override).
* Tests: 11 controller-level tests + 6 config round-trip tests covering
  empty-season payloads, run-seeded /top round-trip, crystal/rupy entry
  debits, now_round_id mismatch rejection, deck_no_list round-trip + reject.
2026-06-13 12:16:22 -04:00