The loser of NBA Play-In Round 1 matches 1 and 3 (East/West 7v8 games)
advances to Play-In Round 2 rather than being eliminated, but was being
assigned finalPosition=0 and appearing in Discord as knocked out.
- Add `loserAdvances` param to `processMatchResult` to skip recording an
elimination result when the loser continues to another match
- Extract `doesLoserAdvance()` to `playoff-match.ts` as the single source
of truth for which play-in matches have advancing losers (replaces
duplicated hardcoded checks at both call sites in bracket.server.ts)
- Extract `isLoserNotifiable()` as a pure exported helper so Discord
notification eligibility is testable; losers only appear when their
team's score changed OR they have a finalized (non-partial) result,
correctly suppressing advancing losers while still surfacing 0-pt
eliminations that produce no score delta
- Add 14 new unit tests covering `doesLoserAdvance`, `isLoserNotifiable`,
and the advancing-loser/eliminated-loser `processMatchResult` branches
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>