diff --git a/app/models/__tests__/team-projected-score.test.ts b/app/models/__tests__/team-projected-score.test.ts index 7e1df07..5148b04 100644 --- a/app/models/__tests__/team-projected-score.test.ts +++ b/app/models/__tests__/team-projected-score.test.ts @@ -269,6 +269,20 @@ describe("calculateTeamScore", () => { expect(result.placementCounts[5]).toBe(1); }); + it("eliminated in non-scoring round (finalPosition=0) counts as completed", async () => { + // Round of 16 loser: 0 pts, fully eliminated (isPartialScore=false) + const db = makeDb([ + makePick("p1", "ss1", "playoff_bracket", { finalPosition: 0, isPartialScore: false }), + ]); + + const result = await calculateTeamScore("team1", "season1", db); + + expect(result.totalPoints).toBe(0); // no points for pre-bracket elimination + expect(result.participantsCompleted).toBe(1); // done — should not count as remaining + expect(result.participantsTotal).toBe(1); + expect(result.placementCounts[1]).toBe(0); // no placement badge + }); + it("mixed team: partial counts in totalPoints only; finalized counts everywhere", async () => { // p1: finalized 1st → totalPoints +100, placementCounts[1]++, completed++ // p2: partial pos 5 (floor 20) → totalPoints +20, no placement, not completed diff --git a/app/models/scoring-calculator.ts b/app/models/scoring-calculator.ts index 0dcaba8..f09e1af 100644 --- a/app/models/scoring-calculator.ts +++ b/app/models/scoring-calculator.ts @@ -890,6 +890,9 @@ export async function calculateTeamScore( placementCounts[result.finalPosition]++; } } + } else if (result && !result.isPartialScore) { + // Finalized with no scoring position (e.g. eliminated in a non-scoring round) — still counts as done + participantsCompleted++; } }