fix(journal): stop bet edits silently un-settling graded bets

A stake/notes-only edit re-graded from Pending, which un-settled a won/lost
bet once its result row had been pruned by snapshot retention (the journal is
FK-free and outlives results). Now only re-grade when the selection or event
actually changed, or the bet is still Pending — mirroring RecordPlacedBet.
This commit is contained in:
2026-05-29 13:57:23 +03:00
parent 08486667c3
commit 42e62c1ed2
2 changed files with 54 additions and 8 deletions
@@ -82,4 +82,40 @@ public sealed class UpdatePlacedBetUseCaseTests
Arg.Any<CancellationToken>());
await _bets.Received(1).SaveChangesAsync(Arg.Any<CancellationToken>());
}
[Fact]
public async Task NotesOnlyEdit_PreservesSettledOutcome_EvenWhenResultPruned()
{
var id = Guid.NewGuid();
var eid = new EventId("evt-1");
var sameSelection = Selection(side: Side.Side1, rate: 2.0m);
var settledWon = new PlacedBet(id, eid, sameSelection, 50m, PlacedAt, BetOutcome.Won, "old");
_bets.GetAsync(id, Arg.Any<CancellationToken>()).Returns(settledWon);
_events.GetAsync(eid, Arg.Any<CancellationToken>()).Returns(Ev(eid));
// Result row has been pruned by retention.
_results.GetAsync(eid, Arg.Any<CancellationToken>()).Returns((EventResult?)null);
// Same selection/event — only the note changes.
var updated = await CreateSut().ExecuteAsync(id, eid, sameSelection, stake: 50m, notes: "new note");
updated.Outcome.Should().Be(BetOutcome.Won); // NOT silently reset to Pending
updated.Notes.Should().Be("new note");
}
[Fact]
public async Task ChangedSelection_WithNoResult_ResetsToPending()
{
var id = Guid.NewGuid();
var eid = new EventId("evt-1");
var settledWon = new PlacedBet(id, eid, Selection(side: Side.Side1, rate: 2.0m), 50m, PlacedAt, BetOutcome.Won, "old");
_bets.GetAsync(id, Arg.Any<CancellationToken>()).Returns(settledWon);
_events.GetAsync(eid, Arg.Any<CancellationToken>()).Returns(Ev(eid));
_results.GetAsync(eid, Arg.Any<CancellationToken>()).Returns((EventResult?)null);
// Selection changed (Side1 → Side2) but no result to grade against → must be Pending,
// never the now-stale Won.
var updated = await CreateSut().ExecuteAsync(id, eid, Selection(side: Side.Side2, rate: 3.0m), stake: 50m, notes: "old");
updated.Outcome.Should().Be(BetOutcome.Pending);
}
}