In league mode, have all matches be unlocked from the start

Closes #2861
This commit is contained in:
Kalle
2026-05-24 14:21:45 +03:00
parent 3df1b93e6a
commit 8cb7dc7ca1
4 changed files with 42 additions and 1 deletions

View File

@@ -558,6 +558,7 @@ export class Tournament {
groupCount: Math.ceil(participantsCount / teamsPerGroup),
seedOrdering: ["groups.seed_optimized"],
hasAbDivisions: selectedSettings?.hasAbDivisions ?? false,
...(this.isLeagueDivision ? { independentRounds: true } : {}),
};
}
case "swiss": {

View File

@@ -469,7 +469,11 @@ class Create {
// In round-robin, only the first round is ready to play at the beginning.
// other matches have teams set but they are busy playing the first round.
if (this.stage.type === "round_robin" && roundNumber > 1) {
if (
this.stage.type === "round_robin" &&
roundNumber > 1 &&
!this.stage.settings?.independentRounds
) {
status = Status.Locked;
}

View File

@@ -368,6 +368,32 @@ describe("Update scores in a round-robin stage", () => {
expect(round2Match2After.status).toBe(2); // Ready
});
test("should leave every match Ready when independentRounds is set", () => {
storage.reset();
manager.create({
name: "Independent rounds",
tournamentId: 0,
type: "round_robin",
seeding: [1, 2, 3, 4],
settings: { groupCount: 1, independentRounds: true },
});
const matches = storage.select<any>("match")!;
for (const match of matches) {
expect(match.status).toBe(2);
}
// reporting a round-2 match before round-1 finishes must not throw
const round2Match = storage.select<any>("match", 2)!;
expect(() =>
manager.update.match({
id: round2Match.id,
opponent1: { score: 16, result: "win" },
opponent2: { score: 4 },
}),
).not.toThrow();
});
test("should unlock next round matches with BYE participants", () => {
storage.reset();
// Create a round robin with 3 teams (odd number creates rounds where one team doesn't play)

View File

@@ -110,6 +110,16 @@ export interface StageSettings {
*/
manualOrdering?: number[][];
/**
* Whether matches in a round-robin stage are playable independently of each other.
*
* - If `false` (default), only round 1 matches start `Ready`; later rounds start
* `Locked` and unlock as both opponents complete the previous round.
* - If `true`, every match with two opponents starts `Ready` (used by league
* formats where weeks are scheduled independently and may be played out of order).
*/
independentRounds?: boolean;
/**
* Optional final between semi-final losers.
*/