feat(tournament): scheduled events with prize pools
Entry fees collect into a real ledger account rather than a number in a row, so tournament money obeys the same double-entry invariants as everything else and every movement is explained by a posting. Settlement distributes the entire pool: dividing a pool across percentage shares leaves a remainder, and dropping it would destroy money and break conservation, so it goes to first place. Settlement claims the tournament before paying, so two instances cannot both pay out. Cancellation refunds every entrant and asserts the pool empties exactly. 18 tests including concurrent entry, concurrent settlement, unfunded entry taking no seat, and books balancing after payout. Removes an append-only trigger that had been over-applied to entry rows. An entry is a seat reservation, not a financial record: a seat claimed but unpaid must be releasable so the player can retry once funded. The money side stays immutable because it is a ledger posting. The journey test now derives the expected payout from the published fee schedule instead of hardcoding it, so it keeps checking something real if the rake changes. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -327,6 +327,10 @@ func TestCannotCashOutAfterTheCrash(t *testing.T) {
|
||||
|
||||
func TestCashedOutPlayerIsPaid(t *testing.T) {
|
||||
f := newFixture(t)
|
||||
// Isolate the payout arithmetic from the fee schedule, which is covered
|
||||
// by its own tests. Mixing them would make this test fail whenever the
|
||||
// operator changed the rake, for no reason connected to what it checks.
|
||||
f.room.Fees = fees.NoFees()
|
||||
id, pk := f.player("a", 100_000)
|
||||
house, err := f.ledger.AccountByName(f.ctx, "house_pot")
|
||||
if err != nil {
|
||||
@@ -764,6 +768,9 @@ func TestAutoCashOutTargetMustExceedOne(t *testing.T) {
|
||||
// An auto cash-out must pay the target exactly, not the tick's multiplier.
|
||||
func TestAutoCashOutPaysTheTargetExactly(t *testing.T) {
|
||||
f := newFixture(t)
|
||||
// The claim under test is that the target pays exactly, not what the
|
||||
// operator deducts afterwards.
|
||||
f.room.Fees = fees.NoFees()
|
||||
house, _ := f.ledger.AccountByName(f.ctx, "house_pot")
|
||||
hp, _ := f.player("housefund", 5_000_000)
|
||||
if _, err := f.ledger.Transfer(f.ctx, hp, house, 5_000_000); err != nil {
|
||||
|
||||
Reference in New Issue
Block a user