- NCAAM R64/R32 winners no longer receive T5 floor points; only Sweet
Sixteen winners entering the first scoring round get a floor
- AFL T5-T6 and T7-T8 score as separate tiers (avg([5,6]) and avg([7,8]))
instead of one shared avg([5-8]) pool
- Eliminated teams now always show their correct final rank (e.g. T33 for
NCAAM R64 losers) even during partial round scoring, by deriving the
rank label from the total match count per round rather than the dynamic
still-alive count
- Discord notifications now fire when a drafted participant is eliminated
with 0 points (e.g. R64 losers whose team score doesn't change)
- Discord notifications no longer include all prior matches — scoped to
the current batch via matchIds
- Discord section headers have spacing; rank medals replaced with numbers
- Rounds auto-complete when all matches are marked done; manual Complete
Round dropdown removed
- Fixed double Discord notification when the last match in a round
triggers auto-complete: processPlayoffEvent now accepts skipRecalculate
so the caller controls when the notification fires
- Fixed falsy check on finalPosition=0 in calculateTeamScore
- Undrafted 0-point participants filtered from Eliminated Teams display
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
When a participant wins a bracket round, they immediately earn provisional
"floor" points (the averaged minimum they'd receive if eliminated next round).
These update as they advance and are replaced by finalized scores on elimination.
Key changes:
- Add `is_partial_score` column to `participant_results` (migration 0038)
- `processPlayoffEvent`: assign provisional position 5 to non-scoring round
winners; assign round-appropriate floors to scoring round winners via
`getGuaranteedMinimumPosition`; add catch-all for unrecognized round names
- `upsertParticipantResult`: guard against un-finalizing rows (never overwrite
isPartialScore=false with true)
- `calculateBracketPoints`: new function averaging tied bracket tiers
(5-8 → 20 pts, 3-4 → avg, 1-2 solo); used in `calculateTeamScore` for
playoff_bracket pattern (pattern-aware, doesn't affect F1/golf scoring)
- `PlayoffBracket`: "In Contention" table for still-active participants;
AFL double-chance fix (participants who won a later match excluded from
earlier round's loser list); correct `nextRank` starting position
- Server loader: batch owner DB queries (one query vs N+1); deduplicate
participantPoints; use calculateBracketPoints for bracket point display
- Clean up Phase/Q-number tracking comments throughout scoring-calculator.ts
- 3 new tests for non-scoring round provisional floor behavior
Also includes a dev admin bypass via DEV_ADMIN_CLERK_ID env var (separate
change on this branch, not part of floor scoring feature).
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
- Created ScoringRulesEditor component with 8 placement point inputs
- Added scoring-types.ts for shared client/server types
- Integrated scoring rules into league settings page
- Integrated scoring rules into league creation form
- Added validation for point values (0-1000 range)
- Disabled editing in settings after draft starts
- Included helpful tips and preview display
Phase 1.3 complete
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>