docs(01-09): complete Tournament Lifecycle + Multi-Tournament + Chop/Deal plan
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
295844983a
commit
14e405c101
3 changed files with 188 additions and 17 deletions
|
|
@ -69,7 +69,7 @@ Requirements for Phase 1 (Development Focus: Live Tournament Management). Each m
|
||||||
- [x] **FIN-08**: Prize pool auto-calculation from all financial inputs
|
- [x] **FIN-08**: Prize pool auto-calculation from all financial inputs
|
||||||
- [x] **FIN-09**: Guaranteed pot support (house covers shortfall)
|
- [x] **FIN-09**: Guaranteed pot support (house covers shortfall)
|
||||||
- [x] **FIN-10**: Payout structures (percentage, fixed, custom table) with configurable rounding
|
- [x] **FIN-10**: Payout structures (percentage, fixed, custom table) with configurable rounding
|
||||||
- [ ] **FIN-11**: Chop/deal support (ICM calculator, chip-chop, even-chop, custom)
|
- [x] **FIN-11**: Chop/deal support (ICM calculator, chip-chop, even-chop, custom)
|
||||||
- [x] **FIN-12**: End-of-season withholding (reserve rake portion for season prizes)
|
- [x] **FIN-12**: End-of-season withholding (reserve rake portion for season prizes)
|
||||||
- [x] **FIN-13**: Every financial action generates a receipt with full transaction log
|
- [x] **FIN-13**: Every financial action generates a receipt with full transaction log
|
||||||
- [x] **FIN-14**: Transaction editing with audit trail and receipt reprint capability
|
- [x] **FIN-14**: Transaction editing with audit trail and receipt reprint capability
|
||||||
|
|
@ -98,8 +98,8 @@ Requirements for Phase 1 (Development Focus: Live Tournament Management). Each m
|
||||||
|
|
||||||
### Multi-Tournament
|
### Multi-Tournament
|
||||||
|
|
||||||
- [ ] **MULTI-01**: Run multiple simultaneous tournaments with independent clocks, financials, and player tracking
|
- [x] **MULTI-01**: Run multiple simultaneous tournaments with independent clocks, financials, and player tracking
|
||||||
- [ ] **MULTI-02**: Tournament lobby view (multi-tournament overview on displays)
|
- [x] **MULTI-02**: Tournament lobby view (multi-tournament overview on displays)
|
||||||
|
|
||||||
### League & Season
|
### League & Season
|
||||||
|
|
||||||
|
|
@ -333,8 +333,8 @@ Which phases cover which requirements. Updated during roadmap reorganization.
|
||||||
| CHIP-02 | Phase 1 | Complete |
|
| CHIP-02 | Phase 1 | Complete |
|
||||||
| CHIP-03 | Phase 1 | Complete |
|
| CHIP-03 | Phase 1 | Complete |
|
||||||
| CHIP-04 | Phase 1 | Complete |
|
| CHIP-04 | Phase 1 | Complete |
|
||||||
| MULTI-01 | Phase 1 | Pending |
|
| MULTI-01 | Phase 1 | Complete |
|
||||||
| MULTI-02 | Phase 1 | Pending |
|
| MULTI-02 | Phase 1 | Complete |
|
||||||
| FIN-01 | Phase 1 | Complete |
|
| FIN-01 | Phase 1 | Complete |
|
||||||
| FIN-02 | Phase 1 | Complete |
|
| FIN-02 | Phase 1 | Complete |
|
||||||
| FIN-03 | Phase 1 | Complete |
|
| FIN-03 | Phase 1 | Complete |
|
||||||
|
|
@ -345,7 +345,7 @@ Which phases cover which requirements. Updated during roadmap reorganization.
|
||||||
| FIN-08 | Phase 1 | Complete |
|
| FIN-08 | Phase 1 | Complete |
|
||||||
| FIN-09 | Phase 1 | Complete |
|
| FIN-09 | Phase 1 | Complete |
|
||||||
| FIN-10 | Phase 1 | Complete |
|
| FIN-10 | Phase 1 | Complete |
|
||||||
| FIN-11 | Phase 1 | Pending |
|
| FIN-11 | Phase 1 | Complete |
|
||||||
| FIN-12 | Phase 1 | Complete |
|
| FIN-12 | Phase 1 | Complete |
|
||||||
| FIN-13 | Phase 1 | Complete |
|
| FIN-13 | Phase 1 | Complete |
|
||||||
| FIN-14 | Phase 1 | Complete |
|
| FIN-14 | Phase 1 | Complete |
|
||||||
|
|
|
||||||
|
|
@ -3,12 +3,12 @@ gsd_state_version: 1.0
|
||||||
milestone: v1.0
|
milestone: v1.0
|
||||||
milestone_name: milestone
|
milestone_name: milestone
|
||||||
status: unknown
|
status: unknown
|
||||||
last_updated: "2026-03-01T03:35:13.000Z"
|
last_updated: "2026-03-01T08:12:00.000Z"
|
||||||
progress:
|
progress:
|
||||||
total_phases: 1
|
total_phases: 1
|
||||||
completed_phases: 0
|
completed_phases: 0
|
||||||
total_plans: 14
|
total_plans: 14
|
||||||
completed_plans: 10
|
completed_plans: 11
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
|
|
@ -23,27 +23,27 @@ See: .planning/PROJECT.md (updated 2026-02-28)
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 1 of 7 (Tournament Engine)
|
Phase: 1 of 7 (Tournament Engine)
|
||||||
Plan: 11 of 14 in current phase
|
Plan: 12 of 14 in current phase
|
||||||
Status: Executing Phase 1
|
Status: Executing Phase 1
|
||||||
Last activity: 2026-03-01 — Completed Plan G (Player Management)
|
Last activity: 2026-03-01 — Completed Plan 09 (Tournament Lifecycle + Multi-Tournament + Chop/Deal)
|
||||||
|
|
||||||
Progress: [███████░░░] 71%
|
Progress: [████████░░] 79%
|
||||||
|
|
||||||
## Performance Metrics
|
## Performance Metrics
|
||||||
|
|
||||||
**Velocity:**
|
**Velocity:**
|
||||||
- Total plans completed: 10
|
- Total plans completed: 11
|
||||||
- Average duration: 8min
|
- Average duration: 10min
|
||||||
- Total execution time: 1.33 hours
|
- Total execution time: 1.75 hours
|
||||||
|
|
||||||
**By Phase:**
|
**By Phase:**
|
||||||
|
|
||||||
| Phase | Plans | Total | Avg/Plan |
|
| Phase | Plans | Total | Avg/Plan |
|
||||||
|-------|-------|-------|----------|
|
|-------|-------|-------|----------|
|
||||||
| 01-tournament-engine | 10 | 80min | 8min |
|
| 01-tournament-engine | 11 | 105min | 10min |
|
||||||
|
|
||||||
**Recent Trend:**
|
**Recent Trend:**
|
||||||
- Last 5 plans: 01-03 (5min), 01-13 (5min), 01-06 (9min), 01-08 (6min), 01-07 (7min)
|
- Last 5 plans: 01-13 (5min), 01-06 (9min), 01-08 (6min), 01-07 (7min), 01-09 (25min)
|
||||||
- Trend: steady
|
- Trend: steady
|
||||||
|
|
||||||
*Updated after each plan completion*
|
*Updated after each plan completion*
|
||||||
|
|
@ -100,6 +100,11 @@ Recent decisions affecting current work:
|
||||||
- [01-07]: CSV formula injection neutralized with tab prefix on =, +, -, @ characters
|
- [01-07]: CSV formula injection neutralized with tab prefix on =, +, -, @ characters
|
||||||
- [01-07]: Buy-in flow auto-registers player in tournament_players if not already present
|
- [01-07]: Buy-in flow auto-registers player in tournament_players if not already present
|
||||||
- [01-07]: QR code URL format: felt://player/{uuid} for future PWA self-check-in
|
- [01-07]: QR code URL format: felt://player/{uuid} for future PWA self-check-in
|
||||||
|
- [01-09]: ICM dispatcher: exact Malmuth-Harville for <=10 players, Monte Carlo (100K iterations) for 11+
|
||||||
|
- [01-09]: Deal proposal/confirm workflow: ProposeDeal returns preview, ConfirmDeal applies payouts
|
||||||
|
- [01-09]: Full chop sets all players to 'deal' status and completes tournament; partial chop continues play
|
||||||
|
- [01-09]: Tournament auto-close: 1 remaining = EndTournament, 0 remaining = CancelTournament
|
||||||
|
- [01-09]: Integration tests use file-based DB with WAL mode for clock ticker goroutine compatibility
|
||||||
|
|
||||||
### Pending Todos
|
### Pending Todos
|
||||||
|
|
||||||
|
|
@ -117,5 +122,5 @@ None yet.
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-03-01
|
Last session: 2026-03-01
|
||||||
Stopped at: Completed 01-07-PLAN.md (Player Management)
|
Stopped at: Completed 01-09-PLAN.md (Tournament Lifecycle + Multi-Tournament + Chop/Deal)
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|
|
||||||
166
.planning/phases/01-tournament-engine/01-09-SUMMARY.md
Normal file
166
.planning/phases/01-tournament-engine/01-09-SUMMARY.md
Normal file
|
|
@ -0,0 +1,166 @@
|
||||||
|
---
|
||||||
|
phase: 01-tournament-engine
|
||||||
|
plan: 09
|
||||||
|
subsystem: api, tournament, financial
|
||||||
|
tags: [tournament-lifecycle, multi-tournament, icm, chop, deal, malmuth-harville, monte-carlo, lobby]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 01-tournament-engine/04
|
||||||
|
provides: Clock engine with registry, ticker, state machine
|
||||||
|
- phase: 01-tournament-engine/06
|
||||||
|
provides: Financial engine with transactions, prize pool, payouts
|
||||||
|
- phase: 01-tournament-engine/07
|
||||||
|
provides: Player management, rankings, buy-in flow
|
||||||
|
- phase: 01-tournament-engine/08
|
||||||
|
provides: Seating engine with tables, balancing, break table
|
||||||
|
provides:
|
||||||
|
- Tournament lifecycle service (create, start, pause, resume, end, cancel, auto-close)
|
||||||
|
- Multi-tournament manager with lobby view (MULTI-01, MULTI-02)
|
||||||
|
- ICM calculator (exact Malmuth-Harville for <=10, Monte Carlo for 11+)
|
||||||
|
- Chop/deal engine (ICM, chip chop, even chop, custom, partial chop)
|
||||||
|
- Tournament state aggregation for WebSocket connect
|
||||||
|
- Activity feed from audit trail
|
||||||
|
- Tournament API routes with deal proposal workflow
|
||||||
|
- Deal proposals migration (007_deal_proposals.sql)
|
||||||
|
affects: [01-11, 01-12, 01-14, phase-02]
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns: [tournament-scoped-state, template-first-creation, local-copy-semantics, proposal-confirm-workflow, icm-dispatcher-pattern]
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created:
|
||||||
|
- internal/tournament/tournament.go
|
||||||
|
- internal/tournament/state.go
|
||||||
|
- internal/tournament/multi.go
|
||||||
|
- internal/financial/icm.go
|
||||||
|
- internal/financial/chop.go
|
||||||
|
- internal/server/routes/tournaments.go
|
||||||
|
- internal/store/migrations/007_deal_proposals.sql
|
||||||
|
- internal/financial/icm_test.go
|
||||||
|
- internal/financial/chop_test.go
|
||||||
|
- internal/tournament/tournament_test.go
|
||||||
|
- internal/tournament/integration_test.go
|
||||||
|
modified: []
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "ICM dispatcher: exact Malmuth-Harville for <=10 players, Monte Carlo (100K iterations) for 11+"
|
||||||
|
- "Deal proposal/confirm workflow: ProposeDeal returns preview, ConfirmDeal applies payouts"
|
||||||
|
- "Full chop sets all players to 'deal' status and completes tournament; partial chop continues play"
|
||||||
|
- "Integration tests use file-based DB with WAL mode for clock ticker goroutine compatibility"
|
||||||
|
- "Tournament auto-close: 1 remaining = end, 0 remaining = cancel"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Tournament-scoped state: all state (clock, players, tables, financials) keyed by tournament_id"
|
||||||
|
- "Template-first creation: CreateFromTemplate loads expanded template, applies overrides, copies all refs"
|
||||||
|
- "Proposal-confirm pattern: deal proposals are stored, reviewed, then confirmed or cancelled"
|
||||||
|
- "ICM dispatcher pattern: CalculateICM auto-selects exact vs Monte Carlo based on player count"
|
||||||
|
- "Activity feed: audit entries converted to human-readable ActivityEntry structs"
|
||||||
|
|
||||||
|
requirements-completed: [MULTI-01, MULTI-02, FIN-11, SEAT-06]
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 25min
|
||||||
|
completed: 2026-03-01
|
||||||
|
---
|
||||||
|
|
||||||
|
# Plan 09: Tournament Lifecycle + Multi-Tournament + Chop/Deal Summary
|
||||||
|
|
||||||
|
**Full tournament lifecycle (create/start/pause/resume/end/cancel/auto-close) with multi-tournament lobby, ICM calculator (exact + Monte Carlo), and chop/deal engine supporting 5 deal types**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** ~25 min
|
||||||
|
- **Started:** 2026-03-01T07:45:00Z
|
||||||
|
- **Completed:** 2026-03-01T08:10:00Z
|
||||||
|
- **Tasks:** 2
|
||||||
|
- **Files created:** 11
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
- Tournament lifecycle service with all state transitions, template-first creation with local copy semantics, and auto-close on last player standing
|
||||||
|
- Multi-tournament manager enabling lobby view with independent state per tournament (clocks, financials, players, tables)
|
||||||
|
- ICM calculator with exact Malmuth-Harville algorithm (<=10 players, <2ms) and Monte Carlo simulation (11+ players, 100K iterations, <25ms)
|
||||||
|
- Chop/deal engine with 5 deal types (ICM, chip chop, even chop, custom, partial chop) and proposal/confirm workflow
|
||||||
|
- 31 new tests across 4 test files: 12 ICM, 6 chop, 9 tournament unit, 4 integration
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task I1: Tournament lifecycle and multi-tournament management** - `75ccb6f` (feat)
|
||||||
|
2. **Task I2: ICM calculator, chop/deal engine, and comprehensive tests** - `2958449` (test)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
- `internal/tournament/tournament.go` - Tournament service: create from template, start, pause, resume, end, cancel, auto-close, list
|
||||||
|
- `internal/tournament/state.go` - State aggregation for WebSocket snapshots and activity feed
|
||||||
|
- `internal/tournament/multi.go` - Multi-tournament manager with lobby view, active tournament listing
|
||||||
|
- `internal/financial/icm.go` - ICM calculator: exact Malmuth-Harville + Monte Carlo dispatcher
|
||||||
|
- `internal/financial/chop.go` - Chop engine: 5 deal types, proposal/confirm workflow, position assignment
|
||||||
|
- `internal/server/routes/tournaments.go` - Tournament API routes: CRUD, lifecycle, deal proposals
|
||||||
|
- `internal/store/migrations/007_deal_proposals.sql` - Deal proposals table migration
|
||||||
|
- `internal/financial/icm_test.go` - 12 ICM tests (exact, Monte Carlo, validation, performance, convergence)
|
||||||
|
- `internal/financial/chop_test.go` - 6 chop/deal tests (all deal types, positions, tournament end)
|
||||||
|
- `internal/tournament/tournament_test.go` - 9 tournament unit tests (template, start, auto-close, multi, state)
|
||||||
|
- `internal/tournament/integration_test.go` - 4 integration tests (lifecycle, deal, cancel, pause/resume)
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
- **ICM dispatcher pattern:** CalculateICM auto-selects exact for <=10 players (factorial complexity manageable) and Monte Carlo with 100K iterations for 11+ (converges to <2% deviation with equal stacks)
|
||||||
|
- **Deal proposal/confirm workflow:** ProposeDeal calculates and stores proposal without applying; ConfirmDeal applies payouts as chop transactions -- matches the TD review flow from CONTEXT.md
|
||||||
|
- **Full vs partial chop:** Full chop sets all players to 'deal' status and completes the tournament; partial chop applies partial payouts and lets tournament continue with remaining pool
|
||||||
|
- **Integration test DB strategy:** In-memory DBs with libsql don't support cross-goroutine access; integration tests use file-based DB with WAL mode and busy_timeout for clock ticker compatibility
|
||||||
|
- **Auto-close semantics:** CheckAutoClose called after every bust-out; 1 player remaining triggers EndTournament, 0 players triggers CancelTournament
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
### Auto-fixed Issues
|
||||||
|
|
||||||
|
**1. [Rule 1 - Bug] Fixed in-memory DB cross-goroutine access in integration tests**
|
||||||
|
- **Found during:** Task I2 (integration tests)
|
||||||
|
- **Issue:** `setupTestDB` creates per-test in-memory DBs that aren't accessible from the clock ticker's background goroutine, causing "no such table" errors
|
||||||
|
- **Fix:** Created `setupIntegrationDB` using file-based temp DB with WAL mode and busy_timeout=5000; added StopTicker call after StartTournament
|
||||||
|
- **Files modified:** internal/tournament/integration_test.go
|
||||||
|
- **Verification:** All 4 integration tests pass
|
||||||
|
- **Committed in:** 2958449
|
||||||
|
|
||||||
|
**2. [Rule 1 - Bug] Fixed blind_levels notes NULL scan failure**
|
||||||
|
- **Found during:** Task I2 (tournament tests)
|
||||||
|
- **Issue:** blind_levels notes column could be NULL, causing scan into string to fail when loading template
|
||||||
|
- **Fix:** Used sql.NullString for notes scanning in loadLevelsFromDB; added explicit empty string notes to seed data
|
||||||
|
- **Files modified:** internal/tournament/tournament.go, internal/tournament/tournament_test.go
|
||||||
|
- **Verification:** TestCreateFromTemplate passes
|
||||||
|
- **Committed in:** 2958449
|
||||||
|
|
||||||
|
**3. [Rule 1 - Bug] Fixed payout_brackets column name mismatch**
|
||||||
|
- **Found during:** Task I2 (tournament tests)
|
||||||
|
- **Issue:** Test DDL used `payout_structure_id` but service queries use `structure_id` column name
|
||||||
|
- **Fix:** Renamed column to `structure_id` in test DDL to match production schema
|
||||||
|
- **Files modified:** internal/tournament/tournament_test.go
|
||||||
|
- **Verification:** All tournament unit tests pass
|
||||||
|
- **Committed in:** 2958449
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Total deviations:** 3 auto-fixed (3 Rule 1 bugs)
|
||||||
|
**Impact on plan:** All auto-fixes necessary for test correctness. No scope creep.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
- libsql PRAGMA handling: `PRAGMA journal_mode=WAL` returns a row, so `Exec` fails with "Execute returned rows" -- must use `QueryRow` with `Scan` instead. This is consistent with the decision logged in 01-02 about libsql PRAGMA inconsistency.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
- Tournament lifecycle is complete and ready for wiring into the full server
|
||||||
|
- Multi-tournament support enables lobby view for the frontend (Plan 11/14)
|
||||||
|
- ICM and chop engines ready for frontend deal UI integration
|
||||||
|
- API routes registered but need wiring into server.go router (will happen in final assembly plan)
|
||||||
|
|
||||||
|
## Self-Check: PASSED
|
||||||
|
|
||||||
|
All 11 created files verified present. Both task commits (75ccb6f, 2958449) verified in git log.
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 01-tournament-engine*
|
||||||
|
*Completed: 2026-03-01*
|
||||||
Loading…
Add table
Reference in a new issue