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
@@ -55,23 +55,33 @@ public sealed class UpdatePlacedBetUseCase
"The event must already be present in the scrape store.");
}
// Preserve the original entry time; re-grade from Pending so a changed
// selection/event settles against the current result.
// Only the selection or the event affects grading. When neither changed (e.g. a
// stake/notes-only edit) keep the existing outcome — re-grading from Pending here
// would SILENTLY UN-SETTLE a won/lost bet whose result row has since been pruned by
// snapshot retention (the journal is FK-free and outlives result pruning). A
// still-Pending bet is always (re)graded, mirroring RecordPlacedBetUseCase.
var gradingInputChanged = !existing.EventId.Equals(eventId)
|| !existing.Selection.Equals(selection);
var regrade = gradingInputChanged || existing.Outcome == BetOutcome.Pending;
var toPersist = new PlacedBet(
Id: id,
EventId: eventId,
Selection: selection,
Stake: stake,
PlacedAt: existing.PlacedAt,
Outcome: BetOutcome.Pending,
Outcome: regrade ? BetOutcome.Pending : existing.Outcome,
Notes: notes);
var result = await _results.GetAsync(eventId, ct).ConfigureAwait(false);
if (result is not null)
if (regrade)
{
var graded = Marathon.Domain.Betting.BetOutcomeResolver.Resolve(toPersist.Selection, result);
if (graded is not null)
toPersist = toPersist.WithOutcome(graded.Value);
var result = await _results.GetAsync(eventId, ct).ConfigureAwait(false);
if (result is not null)
{
var graded = Marathon.Domain.Betting.BetOutcomeResolver.Resolve(toPersist.Selection, result);
if (graded is not null)
toPersist = toPersist.WithOutcome(graded.Value);
}
}
await _bets.UpdateAsync(toPersist, ct).ConfigureAwait(false);