Withdrawn teams forfeit visibly through the bracket instead of becoming byes

A withdrawn team stays in any slot whose opponent is not known yet and forfeits
when they arrive; the board strikes the name through and tags the match
'Forfeit · Team'. Release 0.5.1.

Co-Authored-By: Claude Fable 5.1 <[email protected]>
Claude-Session: https://claude.ai/code/session_01MB7nCCAscYsb3zzkT6LHZi
This commit is contained in:
bkvargyasandClaude Fable 5.1 committed 2026-09-05 15:50:49 +00:00
1 parent a4bee22d96
commit 4ce7e48551
8 files changed
+58 -10

No files matched your search

+10 -2
View File
@@ -179,6 +179,12 @@ export class Tournament {
const next = this.match(matchId);
if (!next) return;
next[side === 'A' ? 'teamA' : 'teamB'] = teamId;
// a withdrawn team was waiting here: it forfeits to the team that just arrived
if (next.autoForfeit && next.teamA && next.teamB && ['pending', 'on_deck'].includes(next.status)) {
const f = next.autoForfeit; delete next.autoForfeit;
if (this.teams.get(teamId)?.status === 'withdrawn') { next.status = 'void'; return; } // both gone
this.recordResult(next.id, [], { actor: 'system', forfeit: f });
}
}
_propagate(m) {
@@ -264,10 +270,12 @@ export class Tournament {
m.court = null;
}
} else if (['pending', 'on_deck', 'live'].includes(m.status)) {
// bracket: opponent walks over, if known; otherwise the slot becomes a bye
// bracket: opponent walks over by forfeit. If the opponent isn't known yet, the withdrawn
// team stays in its slot marked autoForfeit and forfeits the moment the opponent arrives,
// so the bracket shows the forfeit rather than a silent bye.
const opp = m.teamA === teamId ? m.teamB : m.teamA;
if (opp) this.recordResult(m.id, [], { actor, forfeit: teamId });
else { const side = m.teamA === teamId ? 'A' : 'B'; m[side === 'A' ? 'teamA' : 'teamB'] = null; m.pendingBye = side; }
else m.autoForfeit = teamId;
m.court = null;
}
}