brackt/app/services
Chris Parsons d271cc6792
Refactor standings notifications to show only changed teams (#182)
* Refine Discord webhook scoring notifications (fixes #180, #181)

- Filter scored matches to only show matchups where a manager scores
  Brackt points (winner drafted) or has a team eliminated (loser drafted);
  matches with no manager involvement are suppressed entirely.
- Escape Discord markdown characters (_*~`|\) in team names and usernames
  to prevent formatting issues (e.g. double-underscore names causing
  unintended underlines).
- Replace full standings with a "Standings Changes" section that shows
  only teams whose points changed, plus any teams whose rank shifted as a
  result, with ↑N / ↓N indicators for rank movement.
- Pass previousRanks map from scoring-calculator to the notification so
  rank-displaced teams (who didn't score points themselves) are included.
- Update test webhook in league settings to demonstrate rank changes and
  a sample scored match.
- Update all discord service tests to cover the new filtering, escaping,
  and standings-change behaviour.

https://claude.ai/code/session_01FciwfdG9Sfr5ZrXUHPeB18

* fix: only set winnerUsername when winning team's score actually changed

Previously, winnerUsername was set for any drafted winner regardless of
whether points were actually scored. This caused R64 wins (where the
scoring system may not award points until later rounds) to appear in
Discord's Scored Matches section even when no Brackt points were earned.

Now winnerUsername is only set when the winner's team's totalPoints
changed after recalculation. loserUsername (eliminations) is always set
when the loser is drafted, since being knocked out is always notable.

https://claude.ai/code/session_01FciwfdG9Sfr5ZrXUHPeB18

* Refactor Discord notification logic in scoring calculator

- Compute changedTeamIds once up front; derive hasChanges from it
  instead of duplicating the same iteration
- Merge usernameForParticipant and winnerUsernameForParticipant into a
  single function with a requireScoreChange flag
- Replace hasDraftedParticipantMatches with hasScoredMatchesToShow,
  which checks that at least one scoredMatch has a displayable username
  — prevents sending a contentless Discord embed when a drafted winner
  doesn't score any points and the loser isn't drafted
- Update inline comment to be sport-agnostic

https://claude.ai/code/session_01FciwfdG9Sfr5ZrXUHPeB18

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-19 15:52:57 -07:00
..
__tests__ Refactor standings notifications to show only changed teams (#182) 2026-03-19 15:52:57 -07:00
simulations Fix NCAAM/NCAAW simulators: FF completion handling and validation hardening (#169) 2026-03-18 01:37:55 -07:00
bracket-simulator.ts feat: implement Expected Value System with ICM probability calculator 2025-11-17 22:19:46 -08:00
discord.ts Refactor standings notifications to show only changed teams (#182) 2026-03-19 15:52:57 -07:00
ev-calculator.ts User/chris/ev f1 framework (#93) 2026-03-09 15:34:31 -07:00
icm-calculator.ts feat: implement sports season expected value calculations and probability updates 2025-11-21 22:05:50 -08:00
probability-engine.ts feat: implement Expected Value System with ICM probability calculator 2025-11-17 22:19:46 -08:00
probability-updater.ts feat: implement sports season expected value calculations and probability updates 2025-11-21 22:05:50 -08:00