From f3e660917d89ec137cfdba9dd9b4cfc167aca90a Mon Sep 17 00:00:00 2001 From: Kalle <38327916+Sendouc@users.noreply.github.com> Date: Tue, 14 Apr 2026 20:26:48 +0300 Subject: [PATCH] Various tournament queries migrated to Kysely (#2978) --- .../TournamentMatchRepository.server.ts | 74 +++++++ .../actions/to.$id.brackets.server.ts | 3 +- .../actions/to.$id.matches.$mid.server.ts | 9 +- .../loaders/to.$id.matches.$mid.server.ts | 6 +- .../queries/findMatchById.server.ts | 91 --------- .../TournamentTeamRepository.server.ts | 188 +++++++++++++++++- .../tournament/actions/to.$id.admin.server.ts | 50 ++--- .../tournament/actions/to.$id.join.server.ts | 15 +- .../actions/to.$id.register.server.ts | 42 ++-- .../tournament/loaders/to.$id.join.server.ts | 10 +- .../loaders/to.$id.register.server.ts | 13 +- .../queries/changeTeamOwner.server.ts | 30 --- .../tournament/queries/checkIn.server.ts | 12 -- .../tournament/queries/checkOut.server.ts | 10 - .../tournament/queries/deleteTeam.server.ts | 16 -- .../queries/deleteTeamMember.server.ts | 17 -- .../queries/findOwnTournamentTeam.server.ts | 39 ---- .../queries/findTeamByInviteCode.server.ts | 16 -- .../queries/hasTournamentFinalized.server.ts | 14 -- .../queries/hasTournamentStarted.server.ts | 14 -- .../queries/joinLeaveTeam.server.ts | 76 ------- .../queries/upsertCounterpickMaps.server.ts | 37 ---- .../tournament/routes/to.$id.index.ts | 14 +- .../tournament/tournament-test-utils.ts | 12 +- .../tournament/tournament-utils.server.ts | 17 -- e2e/tournament-bracket.spec.ts | 1 + .../add-leaderboard-teams-to-tournament.ts | 14 +- 27 files changed, 325 insertions(+), 515 deletions(-) delete mode 100644 app/features/tournament-bracket/queries/findMatchById.server.ts delete mode 100644 app/features/tournament/queries/changeTeamOwner.server.ts delete mode 100644 app/features/tournament/queries/checkIn.server.ts delete mode 100644 app/features/tournament/queries/checkOut.server.ts delete mode 100644 app/features/tournament/queries/deleteTeam.server.ts delete mode 100644 app/features/tournament/queries/deleteTeamMember.server.ts delete mode 100644 app/features/tournament/queries/findOwnTournamentTeam.server.ts delete mode 100644 app/features/tournament/queries/findTeamByInviteCode.server.ts delete mode 100644 app/features/tournament/queries/hasTournamentFinalized.server.ts delete mode 100644 app/features/tournament/queries/hasTournamentStarted.server.ts delete mode 100644 app/features/tournament/queries/joinLeaveTeam.server.ts delete mode 100644 app/features/tournament/queries/upsertCounterpickMaps.server.ts diff --git a/app/features/tournament-bracket/TournamentMatchRepository.server.ts b/app/features/tournament-bracket/TournamentMatchRepository.server.ts index bf5f46a83..dbf3de67e 100644 --- a/app/features/tournament-bracket/TournamentMatchRepository.server.ts +++ b/app/features/tournament-bracket/TournamentMatchRepository.server.ts @@ -1,4 +1,78 @@ +import { sql } from "kysely"; +import { jsonArrayFrom } from "kysely/helpers/sqlite"; import { db } from "~/db/sql"; +import type { Unwrapped } from "~/utils/types"; + +export type FindMatchById = NonNullable>; +export async function findMatchById(id: number) { + const row = await db + .selectFrom("TournamentMatch") + .innerJoin( + "TournamentStage", + "TournamentStage.id", + "TournamentMatch.stageId", + ) + .innerJoin( + "TournamentRound", + "TournamentRound.id", + "TournamentMatch.roundId", + ) + .innerJoin("Tournament", "Tournament.id", "TournamentStage.tournamentId") + .select(({ eb }) => [ + "TournamentMatch.id", + "TournamentMatch.groupId", + "TournamentMatch.opponentOne", + "TournamentMatch.opponentTwo", + "TournamentMatch.chatCode", + "TournamentMatch.startedAt", + "TournamentMatch.status", + "Tournament.mapPickingStyle", + "TournamentRound.id as roundId", + "TournamentRound.maps as roundMaps", + jsonArrayFrom( + eb + .selectFrom("TournamentTeamMember") + .innerJoin("User", "User.id", "TournamentTeamMember.userId") + .select([ + "User.id", + "User.username", + "TournamentTeamMember.tournamentTeamId", + sql< + string | null + >`coalesce("TournamentTeamMember"."inGameName", "User"."inGameName")`.as( + "inGameName", + ), + "User.discordId", + "User.customUrl", + "User.discordAvatar", + "User.pronouns", + ]) + .where(({ or, eb: innerEb }) => + or([ + innerEb( + "TournamentTeamMember.tournamentTeamId", + "=", + sql`"TournamentMatch"."opponentOne" ->> '$.id'`, + ), + innerEb( + "TournamentTeamMember.tournamentTeamId", + "=", + sql`"TournamentMatch"."opponentTwo" ->> '$.id'`, + ), + ]), + ), + ).as("players"), + ]) + .where("TournamentMatch.id", "=", id) + .executeTakeFirst(); + + if (!row) return; + + return { + ...row, + bestOf: row.roundMaps.count, + }; +} export function findResultById(id: number) { return db diff --git a/app/features/tournament-bracket/actions/to.$id.brackets.server.ts b/app/features/tournament-bracket/actions/to.$id.brackets.server.ts index 3502a4bdb..0e0bc1b13 100644 --- a/app/features/tournament-bracket/actions/to.$id.brackets.server.ts +++ b/app/features/tournament-bracket/actions/to.$id.brackets.server.ts @@ -288,9 +288,8 @@ export const action: ActionFunction = async ({ params, request }) => { `Checking in (bracket try): tournament team id: ${teamMemberOf.id} - user id: ${user.id} - tournament id: ${tournament.ctx.id} - bracket idx: ${data.bracketIdx}`, ); - await TournamentTeamRepository.checkIn({ + await TournamentTeamRepository.checkIn(teamMemberOf.id, { bracketIdx: data.bracketIdx, - tournamentTeamId: teamMemberOf.id, }); logger.info( diff --git a/app/features/tournament-bracket/actions/to.$id.matches.$mid.server.ts b/app/features/tournament-bracket/actions/to.$id.matches.$mid.server.ts index 7f666ae2a..f2ae5291c 100644 --- a/app/features/tournament-bracket/actions/to.$id.matches.$mid.server.ts +++ b/app/features/tournament-bracket/actions/to.$id.matches.$mid.server.ts @@ -29,14 +29,11 @@ import { deleteMatchPickBanEvents } from "../queries/deleteMatchPickBanEvents.se import { deleteParticipantsByMatchGameResultId } from "../queries/deleteParticipantsByMatchGameResultId.server"; import { deletePickBanEvent } from "../queries/deletePickBanEvent.server"; import { deleteTournamentMatchGameResultById } from "../queries/deleteTournamentMatchGameResultById.server"; -import { - type FindMatchById, - findMatchById, -} from "../queries/findMatchById.server"; import { findResultsByMatchId } from "../queries/findResultsByMatchId.server"; import { insertTournamentMatchGameResult } from "../queries/insertTournamentMatchGameResult.server"; import { insertTournamentMatchGameResultParticipant } from "../queries/insertTournamentMatchGameResultParticipant.server"; import { updateMatchGameResultPoints } from "../queries/updateMatchGameResultPoints.server"; +import type { FindMatchById } from "../TournamentMatchRepository.server"; import { matchPageParamsSchema, matchSchema, @@ -56,7 +53,9 @@ export const action: ActionFunction = async ({ params, request }) => { params, schema: matchPageParamsSchema, }); - const match = notFoundIfFalsy(findMatchById(matchId)); + const match = notFoundIfFalsy( + await TournamentMatchRepository.findMatchById(matchId), + ); const data = await parseRequestPayload({ request, schema: matchSchema, diff --git a/app/features/tournament-bracket/loaders/to.$id.matches.$mid.server.ts b/app/features/tournament-bracket/loaders/to.$id.matches.$mid.server.ts index 04eb9c67b..2feeb52ef 100644 --- a/app/features/tournament-bracket/loaders/to.$id.matches.$mid.server.ts +++ b/app/features/tournament-bracket/loaders/to.$id.matches.$mid.server.ts @@ -15,8 +15,8 @@ import { executeRoll } from "../core/executeRoll.server"; import { mapListFromResults, resolveMapList } from "../core/mapList.server"; import * as PickBan from "../core/PickBan"; import { tournamentFromDBCached } from "../core/Tournament.server"; -import { findMatchById } from "../queries/findMatchById.server"; import { findResultsByMatchId } from "../queries/findResultsByMatchId.server"; +import * as TournamentMatchRepository from "../TournamentMatchRepository.server"; import { matchPageParamsSchema } from "../tournament-bracket-schemas.server"; import { matchEndedEarly } from "../tournament-bracket-utils"; @@ -33,7 +33,9 @@ export const loader = async ({ params }: LoaderFunctionArgs) => { user: undefined, }); - const match = notFoundIfFalsy(findMatchById(matchId)); + const match = notFoundIfFalsy( + await TournamentMatchRepository.findMatchById(matchId), + ); const isBye = !match.opponentOne || !match.opponentTwo; if (isBye) { diff --git a/app/features/tournament-bracket/queries/findMatchById.server.ts b/app/features/tournament-bracket/queries/findMatchById.server.ts deleted file mode 100644 index 74bdc5a39..000000000 --- a/app/features/tournament-bracket/queries/findMatchById.server.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { sql } from "~/db/sql"; -import type { Tables, TournamentRoundMaps } from "~/db/tables"; -import type { Match } from "~/modules/brackets-model"; -import { parseDBArray } from "~/utils/sql"; - -const stm = sql.prepare(/* sql */ ` - select - "TournamentMatch"."id", - "TournamentMatch"."groupId", - "TournamentMatch"."opponentOne", - "TournamentMatch"."opponentTwo", - "TournamentMatch"."chatCode", - "TournamentMatch"."startedAt", - "TournamentMatch"."status", - "Tournament"."mapPickingStyle", - "TournamentRound"."id" as "roundId", - "TournamentRound"."maps" as "roundMaps", - json_group_array( - json_object( - 'id', - "User"."id", - 'username', - "User"."username", - 'tournamentTeamId', - "TournamentTeamMember"."tournamentTeamId", - 'inGameName', - COALESCE("TournamentTeamMember"."inGameName", "User"."inGameName"), - 'discordId', - "User"."discordId", - 'customUrl', - "User"."customUrl", - 'discordAvatar', - "User"."discordAvatar", - 'pronouns', json("User"."pronouns") - ) - ) as "players" - from "TournamentMatch" - left join "TournamentStage" on "TournamentStage"."id" = "TournamentMatch"."stageId" - left join "TournamentRound" on "TournamentRound"."id" = "TournamentMatch"."roundId" - left join "Tournament" on "Tournament"."id" = "TournamentStage"."tournamentId" - left join "TournamentTeamMember" on - "TournamentTeamMember"."tournamentTeamId" = "TournamentMatch"."opponentOne" ->> '$.id' - or - "TournamentTeamMember"."tournamentTeamId" = "TournamentMatch"."opponentTwo" ->> '$.id' - left join "User" on "User"."id" = "TournamentTeamMember"."userId" - where "TournamentMatch"."id" = @id - group by "TournamentMatch"."id" -`); - -export type FindMatchById = ReturnType; - -export const findMatchById = (id: number) => { - const row = stm.get({ id }) as - | ((Pick< - Tables["TournamentMatch"], - "id" | "groupId" | "chatCode" | "startedAt" | "status" - > & - Pick & { players: string }) & { - opponentOne: string; - opponentTwo: string; - roundId: number; - roundMaps: string; - }) - | undefined; - - if (!row) return; - - const roundMaps = JSON.parse(row.roundMaps) as TournamentRoundMaps; - - return { - ...row, - bestOf: roundMaps.count, - roundId: row.roundId, - roundMaps, - opponentOne: JSON.parse(row.opponentOne) as Match["opponent1"], - opponentTwo: JSON.parse(row.opponentTwo) as Match["opponent2"], - status: row.status, - players: ( - parseDBArray(row.players) as Array<{ - id: Tables["User"]["id"]; - username: Tables["User"]["username"]; - tournamentTeamId: Tables["TournamentTeamMember"]["tournamentTeamId"]; - inGameName: Tables["User"]["inGameName"]; - discordId: Tables["User"]["discordId"]; - customUrl: Tables["User"]["customUrl"]; - discordAvatar: Tables["User"]["discordAvatar"]; - pronouns: Tables["User"]["pronouns"]; - }> - ).filter((player) => player.id), - }; -}; diff --git a/app/features/tournament/TournamentTeamRepository.server.ts b/app/features/tournament/TournamentTeamRepository.server.ts index df5fc8ecc..cdd569a88 100644 --- a/app/features/tournament/TournamentTeamRepository.server.ts +++ b/app/features/tournament/TournamentTeamRepository.server.ts @@ -2,6 +2,7 @@ import type { Transaction } from "kysely"; import { sql } from "kysely"; import { db } from "~/db/sql"; import type { DB, Tables } from "~/db/tables"; +import type { MapPool } from "~/features/map-list-generator/core/map-pool"; import type { ModeShort, StageId } from "~/modules/in-game-lists/types"; import { flatZip } from "~/utils/arrays"; import { databaseTimestampNow, dateToDatabaseTimestamp } from "~/utils/dates"; @@ -111,13 +112,11 @@ export function create({ avatarFileName, userId, tournamentId, - ownerInGameName, }: { team: Pick; avatarFileName?: string; userId: number; tournamentId: number; - ownerInGameName: string | null; }) { return db.transaction().execute(async (trx) => { const avatarImgId = avatarFileName @@ -141,13 +140,15 @@ export function create({ .returning("id") .executeTakeFirstOrThrow(); + const inGameName = await resolveInGameName(trx, tournamentId, userId); + await trx .insertInto("TournamentTeamMember") .values({ tournamentTeamId: tournamentTeam.id, userId, role: "OWNER", - inGameName: ownerInGameName, + inGameName, }) .execute(); @@ -155,6 +156,28 @@ export function create({ }); } +async function resolveInGameName( + trx: Transaction, + tournamentId: number, + userId: number, +) { + const tournament = await trx + .selectFrom("Tournament") + .select("Tournament.settings") + .where("Tournament.id", "=", tournamentId) + .executeTakeFirstOrThrow(); + + if (!tournament.settings.requireInGameNames) return null; + + const user = await trx + .selectFrom("User") + .select("User.inGameName") + .where("User.id", "=", userId) + .executeTakeFirstOrThrow(); + + return user.inGameName; +} + export function copyFromAnotherTournament({ tournamentTeamId, destinationTournamentId, @@ -355,13 +378,17 @@ export function updateStartingBrackets( }); } -export function checkIn({ - tournamentTeamId, - bracketIdx, -}: { - tournamentTeamId: number; - bracketIdx: number | null; -}) { +/** + * Checks in a tournament team. Clears any existing check-out records before inserting the check-in. + * When called without `bracketIdx`, checks in for the whole tournament. + * When called with `bracketIdx`, checks in for a specific bracket (e.g. after progression). + */ +export function checkIn( + tournamentTeamId: number, + options?: { bracketIdx: number }, +) { + const bracketIdx = options?.bracketIdx ?? null; + return db.transaction().execute(async (trx) => { let query = trx .deleteFrom("TournamentTeamCheckIn") @@ -467,6 +494,139 @@ export function undoDropOut(tournamentTeamId: number) { .execute(); } +export function join({ + previousTeamId, + whatToDoWithPreviousTeam, + newTeamId, + userId, + checkOutTeam = false, +}: { + previousTeamId?: number; + whatToDoWithPreviousTeam?: "LEAVE" | "DELETE"; + newTeamId: number; + userId: number; + checkOutTeam?: boolean; +}) { + return db.transaction().execute(async (trx) => { + if (whatToDoWithPreviousTeam === "DELETE") { + await trx + .deleteFrom("TournamentTeam") + .where("TournamentTeam.id", "=", previousTeamId!) + .execute(); + } else if (whatToDoWithPreviousTeam === "LEAVE") { + await trx + .deleteFrom("TournamentTeamMember") + .where("TournamentTeamMember.tournamentTeamId", "=", previousTeamId!) + .where("TournamentTeamMember.userId", "=", userId) + .execute(); + } + + if (checkOutTeam) { + invariant( + previousTeamId, + "previousTeamId is required when checking out team", + ); + await trx + .deleteFrom("TournamentTeamCheckIn") + .where("TournamentTeamCheckIn.tournamentTeamId", "=", previousTeamId) + .execute(); + } + + const tournamentId = ( + await trx + .selectFrom("TournamentTeam") + .select("TournamentTeam.tournamentId") + .where("TournamentTeam.id", "=", newTeamId) + .executeTakeFirstOrThrow() + ).tournamentId; + + const inGameName = await resolveInGameName(trx, tournamentId, userId); + + await trx + .insertInto("TournamentTeamMember") + .values({ + tournamentTeamId: newTeamId, + userId, + inGameName, + }) + .execute(); + }); +} + +export function del(tournamentTeamId: number) { + return db.transaction().execute(async (trx) => { + await trx + .deleteFrom("MapPoolMap") + .where("MapPoolMap.tournamentTeamId", "=", tournamentTeamId) + .execute(); + + await trx + .deleteFrom("TournamentTeam") + .where("TournamentTeam.id", "=", tournamentTeamId) + .execute(); + }); +} + +export function leave({ teamId, userId }: { teamId: number; userId: number }) { + return db + .deleteFrom("TournamentTeamMember") + .where("TournamentTeamMember.tournamentTeamId", "=", teamId) + .where("TournamentTeamMember.userId", "=", userId) + .execute(); +} + +export function transferOwnership( + tournamentTeamId: number, + { + oldCaptainId, + newCaptainId, + }: { oldCaptainId: number; newCaptainId: number }, +) { + return db.transaction().execute(async (trx) => { + await trx + .updateTable("TournamentTeamMember") + .set({ role: "REGULAR" }) + .where("TournamentTeamMember.tournamentTeamId", "=", tournamentTeamId) + .where("TournamentTeamMember.userId", "=", oldCaptainId) + .execute(); + + await trx + .updateTable("TournamentTeamMember") + .set({ role: "OWNER" }) + .where("TournamentTeamMember.tournamentTeamId", "=", tournamentTeamId) + .where("TournamentTeamMember.userId", "=", newCaptainId) + .execute(); + }); +} + +export function upsertCounterpickMaps({ + tournamentTeamId, + mapPool, +}: { + tournamentTeamId: Tables["TournamentTeam"]["id"]; + mapPool: MapPool; +}) { + return db.transaction().execute(async (trx) => { + await trx + .deleteFrom("MapPoolMap") + .where("MapPoolMap.tournamentTeamId", "=", tournamentTeamId) + .execute(); + + if (mapPool.stageModePairs.length > 0) { + await trx + .insertInto("MapPoolMap") + .values( + mapPool.stageModePairs.map(({ stageId, mode }) => ({ + tournamentTeamId, + stageId, + mode, + })), + ) + .execute(); + } + }); +} + async function findTeamRecentMaps(teamId: number, limit: number) { return db .selectFrom("TournamentMatchGameResult") @@ -485,6 +645,14 @@ async function findTeamRecentMaps(teamId: number, limit: number) { .execute(); } +export function findByInviteCode(inviteCode: string) { + return db + .selectFrom("TournamentTeam") + .select(["TournamentTeam.id", "TournamentTeam.tournamentId"]) + .where("TournamentTeam.inviteCode", "=", inviteCode) + .executeTakeFirst(); +} + export async function findRecentlyPlayedMapsByIds({ teamIds, limit = 5, diff --git a/app/features/tournament/actions/to.$id.admin.server.ts b/app/features/tournament/actions/to.$id.admin.server.ts index 942d56502..729e4ca66 100644 --- a/app/features/tournament/actions/to.$id.admin.server.ts +++ b/app/features/tournament/actions/to.$id.admin.server.ts @@ -30,15 +30,9 @@ import { } from "~/utils/remix.server"; import { assertUnreachable } from "~/utils/types"; import { idObject } from "../../../utils/zod"; -import { changeTeamOwner } from "../queries/changeTeamOwner.server"; -import { deleteTeam } from "../queries/deleteTeam.server"; -import { joinTeam, leaveTeam } from "../queries/joinLeaveTeam.server"; import * as TournamentRepository from "../TournamentRepository.server"; import { adminActionSchema } from "../tournament-schemas.server"; -import { - endDroppedTeamMatches, - inGameNameIfNeeded, -} from "../tournament-utils.server"; +import { endDroppedTeamMatches } from "../tournament-utils.server"; export const action: ActionFunction = async ({ request, params }) => { const user = requireUser(); @@ -70,16 +64,14 @@ export const action: ActionFunction = async ({ request, params }) => { !tournament.teamMemberOfByUser({ id: data.userId }), "User already on a team", ); + const addTeamUser = await UserRepository.findLeanById(data.userId); + errorToastIfFalsy(addTeamUser?.friendCode, "User has no friend code set"); errorToastIfFalsy( - (await UserRepository.findLeanById(data.userId))?.friendCode, - "User has no friend code set", + !tournament.ctx.settings.requireInGameNames || addTeamUser?.inGameName, + "User has no in-game name set", ); await TournamentTeamRepository.create({ - ownerInGameName: await inGameNameIfNeeded({ - tournament, - userId: data.userId, - }), team: { name: data.teamName, prefersNotToHost: 0, @@ -112,10 +104,9 @@ export const action: ActionFunction = async ({ request, params }) => { const newCaptain = team.members.find((m) => m.userId === data.memberId); errorToastIfFalsy(newCaptain, "Invalid member id"); - changeTeamOwner({ - newCaptainId: data.memberId, + await TournamentTeamRepository.transferOwnership(data.teamId, { oldCaptainId: oldCaptain.userId, - tournamentTeamId: data.teamId, + newCaptainId: data.memberId, }); message = "Team owner changed"; @@ -152,11 +143,11 @@ export const action: ActionFunction = async ({ request, params }) => { invariant(bracket, "Invalid bracket idx"); errorToastIfFalsy(bracket.preview, "Bracket has been started"); - await TournamentTeamRepository.checkIn({ - tournamentTeamId: data.teamId, + await TournamentTeamRepository.checkIn( + data.teamId, // no sources = regular check in - bracketIdx: !bracket.sources ? null : data.bracketIdx, - }); + bracket.sources ? { bracketIdx: data.bracketIdx } : undefined, + ); message = "Checked team in"; break; @@ -214,7 +205,7 @@ export const action: ActionFunction = async ({ request, params }) => { }); } - leaveTeam({ + await TournamentTeamRepository.leave({ userId: data.memberId, teamId: team.id, }); @@ -250,16 +241,22 @@ export const action: ActionFunction = async ({ request, params }) => { "User trying to be added currently has an active ban from sendou.ink", ); + const addMemberUser = await UserRepository.findLeanById(data.userId); errorToastIfFalsy( - (await UserRepository.findLeanById(data.userId))?.friendCode, + addMemberUser?.friendCode, "User has no friend code set", ); + errorToastIfFalsy( + !tournament.ctx.settings.requireInGameNames || + addMemberUser?.inGameName, + "User has no in-game name set", + ); await TournamentLFGRepository.leaveLfg({ userId: data.userId, tournamentId, }); - joinTeam({ + await TournamentTeamRepository.join({ userId: data.userId, newTeamId: team.id, previousTeamId: previousTeam?.id, @@ -270,11 +267,6 @@ export const action: ActionFunction = async ({ request, params }) => { tournament.hasStarted ? "DELETE" : undefined, - tournamentId, - inGameName: await inGameNameIfNeeded({ - tournament, - userId: data.userId, - }), }); ShowcaseTournaments.addToCached({ @@ -310,7 +302,7 @@ export const action: ActionFunction = async ({ request, params }) => { errorToastIfFalsy(team, "Invalid team id"); errorToastIfFalsy(!tournament.hasStarted, "Tournament has started"); - deleteTeam(team.id); + await TournamentTeamRepository.del(team.id); for (const member of team.members) { ShowcaseTournaments.removeFromCached({ diff --git a/app/features/tournament/actions/to.$id.join.server.ts b/app/features/tournament/actions/to.$id.join.server.ts index 614b4925d..e3f936462 100644 --- a/app/features/tournament/actions/to.$id.join.server.ts +++ b/app/features/tournament/actions/to.$id.join.server.ts @@ -2,6 +2,7 @@ import type { ActionFunction } from "react-router"; import { redirect } from "react-router"; import { requireUser } from "~/features/auth/core/user.server"; import * as ShowcaseTournaments from "~/features/front-page/core/ShowcaseTournaments.server"; +import * as TournamentTeamRepository from "~/features/tournament/TournamentTeamRepository.server"; import { clearTournamentDataCache, tournamentFromDB, @@ -16,11 +17,8 @@ import { } from "~/utils/remix.server"; import { tournamentPage } from "~/utils/urls"; import { idObject } from "~/utils/zod"; -import { findByInviteCode } from "../queries/findTeamByInviteCode.server"; -import { joinTeam } from "../queries/joinLeaveTeam.server"; import { validateCanJoinTeam } from "../tournament-utils"; import { - inGameNameIfNeeded, requireNotBannedByOrganization, requireSendouQParticipationIfNeeded, } from "../tournament-utils.server"; @@ -35,7 +33,9 @@ export const action: ActionFunction = async ({ request, params }) => { const inviteCode = url.searchParams.get("code"); invariant(inviteCode, "code is missing"); - const leanTeam = notFoundIfFalsy(findByInviteCode(inviteCode)); + const leanTeam = notFoundIfFalsy( + await TournamentTeamRepository.findByInviteCode(inviteCode), + ); const tournament = await tournamentFromDB({ tournamentId, user }); @@ -88,7 +88,7 @@ export const action: ActionFunction = async ({ request, params }) => { : "LEAVE"; await TournamentLFGRepository.leaveLfg({ userId: user.id, tournamentId }); - joinTeam({ + await TournamentTeamRepository.join({ userId: user.id, newTeamId: teamToJoin.id, previousTeamId: previousTeam?.id, @@ -99,11 +99,6 @@ export const action: ActionFunction = async ({ request, params }) => { previousTeam && previousTeam.members.length <= tournament.minMembersPerTeam, whatToDoWithPreviousTeam, - tournamentId, - inGameName: await inGameNameIfNeeded({ - tournament, - userId: user.id, - }), }); ShowcaseTournaments.addToCached({ diff --git a/app/features/tournament/actions/to.$id.register.server.ts b/app/features/tournament/actions/to.$id.register.server.ts index 566ba36b3..07c0c7eb8 100644 --- a/app/features/tournament/actions/to.$id.register.server.ts +++ b/app/features/tournament/actions/to.$id.register.server.ts @@ -22,12 +22,6 @@ import { } from "~/utils/remix.server"; import { assertUnreachable } from "~/utils/types"; import { idObject } from "~/utils/zod"; -import { checkIn } from "../queries/checkIn.server"; -import { deleteTeam } from "../queries/deleteTeam.server"; -import deleteTeamMember from "../queries/deleteTeamMember.server"; -import { findOwnTournamentTeam } from "../queries/findOwnTournamentTeam.server"; -import { joinTeam } from "../queries/joinLeaveTeam.server"; -import { upsertCounterpickMaps } from "../queries/upsertCounterpickMaps.server"; import { TOURNAMENT } from "../tournament-constants"; import { registerSchema } from "../tournament-schemas.server"; import { @@ -35,7 +29,6 @@ import { validateCounterPickMapPool, } from "../tournament-utils"; import { - inGameNameIfNeeded, requireNotBannedByOrganization, requireSendouQParticipationIfNeeded, } from "../tournament-utils.server"; @@ -130,10 +123,6 @@ export const action: ActionFunction = async ({ request, params }) => { tournamentId, }); await TournamentTeamRepository.create({ - ownerInGameName: await inGameNameIfNeeded({ - tournament, - userId: user.id, - }), team: { name: data.teamName, prefersNotToHost: Number(data.prefersNotToHost), @@ -165,20 +154,18 @@ export const action: ActionFunction = async ({ request, params }) => { ); errorToastIfFalsy(data.userId !== user.id, "Can't kick yourself"); - const detailedOwnTeam = findOwnTournamentTeam({ - tournamentId, - userId: user.id, - }); // making sure they aren't unfilling one checking in condition i.e. having full roster // and then having members kicked without it affecting the checking in status errorToastIfFalsy( - detailedOwnTeam && - (!detailedOwnTeam.checkedInAt || - ownTeam.members.length > tournament.minMembersPerTeam), + !ownTeamCheckedIn || + ownTeam.members.length > tournament.minMembersPerTeam, "Can't kick a member after checking in", ); - deleteTeamMember({ tournamentTeamId: ownTeam.id, userId: data.userId }); + await TournamentTeamRepository.leave({ + teamId: ownTeam.id, + userId: data.userId, + }); ShowcaseTournaments.removeFromCached({ tournamentId, @@ -197,8 +184,8 @@ export const action: ActionFunction = async ({ request, params }) => { "You cannot leave after checking in", ); - deleteTeamMember({ - tournamentTeamId: teamMemberOf.id, + await TournamentTeamRepository.leave({ + teamId: teamMemberOf.id, userId: user.id, }); @@ -225,7 +212,7 @@ export const action: ActionFunction = async ({ request, params }) => { "Invalid map pool", ); - upsertCounterpickMaps({ + await TournamentTeamRepository.upsertCounterpickMaps({ tournamentTeamId: ownTeam.id, mapPool: new MapPool(data.mapPool), }); @@ -253,7 +240,7 @@ export const action: ActionFunction = async ({ request, params }) => { `Can't check-in - ${tournament.checkInConditionsFulfilledByTeamId(teamMemberOf.id).reason}`, ); - checkIn(teamMemberOf.id); + await TournamentTeamRepository.checkIn(teamMemberOf.id); logger.info( `Checking in (success): tournament team id: ${teamMemberOf.id} - user id: ${user.id} - tournament id: ${tournamentId}`, ); @@ -293,14 +280,9 @@ export const action: ActionFunction = async ({ request, params }) => { userId: data.userId, tournamentId, }); - joinTeam({ + await TournamentTeamRepository.join({ userId: data.userId, newTeamId: ownTeam.id, - tournamentId, - inGameName: await inGameNameIfNeeded({ - tournament, - userId: data.userId, - }), }); await SavedCalendarEventRepository.unsave({ @@ -344,7 +326,7 @@ export const action: ActionFunction = async ({ request, params }) => { "Unregistering from leagues is not possible after registration has closed", ); - deleteTeam(ownTeam.id); + await TournamentTeamRepository.del(ownTeam.id); for (const member of ownTeam.members) { ShowcaseTournaments.removeFromCached({ diff --git a/app/features/tournament/loaders/to.$id.join.server.ts b/app/features/tournament/loaders/to.$id.join.server.ts index e22a0e73c..7a092b567 100644 --- a/app/features/tournament/loaders/to.$id.join.server.ts +++ b/app/features/tournament/loaders/to.$id.join.server.ts @@ -1,12 +1,16 @@ import type { LoaderFunctionArgs } from "react-router"; -import { findByInviteCode } from "../queries/findTeamByInviteCode.server"; +import * as TournamentTeamRepository from "~/features/tournament/TournamentTeamRepository.server"; -export const loader = ({ request }: LoaderFunctionArgs) => { +export const loader = async ({ request }: LoaderFunctionArgs) => { const url = new URL(request.url); const inviteCode = url.searchParams.get("code"); + const team = inviteCode + ? await TournamentTeamRepository.findByInviteCode(inviteCode) + : null; + return { - teamId: inviteCode ? findByInviteCode(inviteCode)?.id : null, + teamId: team?.id ?? null, inviteCode, }; }; diff --git a/app/features/tournament/loaders/to.$id.register.server.ts b/app/features/tournament/loaders/to.$id.register.server.ts index 378ce2472..98ca13c1f 100644 --- a/app/features/tournament/loaders/to.$id.register.server.ts +++ b/app/features/tournament/loaders/to.$id.register.server.ts @@ -3,10 +3,10 @@ import { getUser } from "~/features/auth/core/user.server"; import * as SQGroupRepository from "~/features/sendouq/SQGroupRepository.server"; import * as TeamRepository from "~/features/team/TeamRepository.server"; import * as SavedCalendarEventRepository from "~/features/tournament/SavedCalendarEventRepository.server"; +import { tournamentFromDBCached } from "~/features/tournament-bracket/core/Tournament.server"; import { findMapPoolByTeamId } from "~/features/tournament-bracket/queries/findMapPoolByTeamId.server"; import { parseParams } from "~/utils/remix.server"; import { idObject } from "~/utils/zod"; -import { findOwnTournamentTeam } from "../queries/findOwnTournamentTeam.server"; export const loader = async ({ params }: LoaderFunctionArgs) => { const user = getUser(); @@ -17,11 +17,10 @@ export const loader = async ({ params }: LoaderFunctionArgs) => { schema: idObject, }); - const ownTournamentTeam = findOwnTournamentTeam({ - tournamentId, - userId: user.id, - }); - if (!ownTournamentTeam) { + const tournament = await tournamentFromDBCached({ tournamentId, user }); + const ownTeam = tournament.ownedTeamByUser(user); + + if (!ownTeam) { return { mapPool: null, friendPlayers: null, @@ -34,7 +33,7 @@ export const loader = async ({ params }: LoaderFunctionArgs) => { } return { - mapPool: findMapPoolByTeamId(ownTournamentTeam.id), + mapPool: findMapPoolByTeamId(ownTeam.id), friendPlayers: await SQGroupRepository.friendsAndTeammates(user.id), teams: await TeamRepository.findAllMemberOfByUserId(user.id), isSaved: false, diff --git a/app/features/tournament/queries/changeTeamOwner.server.ts b/app/features/tournament/queries/changeTeamOwner.server.ts deleted file mode 100644 index 062c320f0..000000000 --- a/app/features/tournament/queries/changeTeamOwner.server.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { sql } from "~/db/sql"; -import type { Tables } from "~/db/tables"; - -const stm = sql.prepare(/* sql */ ` - update TournamentTeamMember - set "role" = @role - where - "tournamentTeamId" = @tournamentTeamId and - "userId" = @userId -`); - -export const changeTeamOwner = sql.transaction( - (args: { - tournamentTeamId: Tables["TournamentTeam"]["id"]; - oldCaptainId: Tables["User"]["id"]; - newCaptainId: Tables["User"]["id"]; - }) => { - stm.run({ - tournamentTeamId: args.tournamentTeamId, - userId: args.oldCaptainId, - role: "REGULAR", - }); - - stm.run({ - tournamentTeamId: args.tournamentTeamId, - userId: args.newCaptainId, - role: "OWNER", - }); - }, -); diff --git a/app/features/tournament/queries/checkIn.server.ts b/app/features/tournament/queries/checkIn.server.ts deleted file mode 100644 index 24fa1888e..000000000 --- a/app/features/tournament/queries/checkIn.server.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { sql } from "~/db/sql"; - -const stm = sql.prepare(/* sql */ ` - insert into "TournamentTeamCheckIn" - ("tournamentTeamId", "checkedInAt") - values - (@tournamentTeamId, strftime('%s', 'now')) -`); - -export function checkIn(tournamentTeamId: number) { - stm.run({ tournamentTeamId }); -} diff --git a/app/features/tournament/queries/checkOut.server.ts b/app/features/tournament/queries/checkOut.server.ts deleted file mode 100644 index c26068e86..000000000 --- a/app/features/tournament/queries/checkOut.server.ts +++ /dev/null @@ -1,10 +0,0 @@ -import { sql } from "~/db/sql"; - -const stm = sql.prepare(/* sql */ ` - delete from "TournamentTeamCheckIn" - where "tournamentTeamId" = @tournamentTeamId -`); - -export function checkOut(tournamentTeamId: number) { - stm.run({ tournamentTeamId }); -} diff --git a/app/features/tournament/queries/deleteTeam.server.ts b/app/features/tournament/queries/deleteTeam.server.ts deleted file mode 100644 index fb2a6adc3..000000000 --- a/app/features/tournament/queries/deleteTeam.server.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { sql } from "~/db/sql"; - -const deleteTeamStm = sql.prepare(/*sql*/ ` - delete from "TournamentTeam" - where "id" = @tournamentTeamId -`); - -const deleteMapPoolStm = sql.prepare(/*sql*/ ` - delete from "MapPoolMap" - where "tournamentTeamId" = @tournamentTeamId -`); - -export const deleteTeam = sql.transaction((tournamentTeamId: number) => { - deleteMapPoolStm.run({ tournamentTeamId }); - deleteTeamStm.run({ tournamentTeamId }); -}); diff --git a/app/features/tournament/queries/deleteTeamMember.server.ts b/app/features/tournament/queries/deleteTeamMember.server.ts deleted file mode 100644 index dfca7b6bb..000000000 --- a/app/features/tournament/queries/deleteTeamMember.server.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { sql } from "~/db/sql"; - -const stm = sql.prepare(/*sql*/ ` - delete from "TournamentTeamMember" - where userId = @userId - and tournamentTeamId = @tournamentTeamId -`); - -export default function deleteTeamMember({ - userId, - tournamentTeamId, -}: { - userId: number; - tournamentTeamId: number; -}) { - stm.run({ userId, tournamentTeamId }); -} diff --git a/app/features/tournament/queries/findOwnTournamentTeam.server.ts b/app/features/tournament/queries/findOwnTournamentTeam.server.ts deleted file mode 100644 index 5c04499a4..000000000 --- a/app/features/tournament/queries/findOwnTournamentTeam.server.ts +++ /dev/null @@ -1,39 +0,0 @@ -import { sql } from "~/db/sql"; -import type { Tables } from "~/db/tables"; - -const stm = sql.prepare(/*sql*/ ` - select - "TournamentTeam"."id", - "TournamentTeam"."name", - "TournamentTeamCheckIn"."checkedInAt", - "TournamentTeam"."inviteCode" - from - "TournamentTeam" - left join "TournamentTeamCheckIn" on - "TournamentTeamCheckIn"."tournamentTeamId" = "TournamentTeam"."id" - left join "TournamentTeamMember" on - "TournamentTeamMember"."tournamentTeamId" = "TournamentTeam"."id" - and "TournamentTeamMember"."role" = 'OWNER' - where - "TournamentTeam"."tournamentId" = @tournamentId - and "TournamentTeam"."isPlaceholder" = 0 - and "TournamentTeamMember"."userId" = @userId -`); - -type FindOwnTeam = - | (Pick & - Pick) - | null; - -export function findOwnTournamentTeam({ - tournamentId, - userId, -}: { - tournamentId: number; - userId: number; -}) { - return stm.get({ - tournamentId, - userId, - }) as FindOwnTeam; -} diff --git a/app/features/tournament/queries/findTeamByInviteCode.server.ts b/app/features/tournament/queries/findTeamByInviteCode.server.ts deleted file mode 100644 index 8dcd6fa48..000000000 --- a/app/features/tournament/queries/findTeamByInviteCode.server.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { sql } from "~/db/sql"; - -const stm = sql.prepare(/*sql */ ` - select - "TournamentTeam"."id", - "TournamentTeam"."tournamentId" - from "TournamentTeam" - where "TournamentTeam"."inviteCode" = @inviteCode -`); - -export function findByInviteCode(inviteCode: string) { - return stm.get({ inviteCode }) as { - id: number; - tournamentId: number; - } | null; -} diff --git a/app/features/tournament/queries/hasTournamentFinalized.server.ts b/app/features/tournament/queries/hasTournamentFinalized.server.ts deleted file mode 100644 index af5a232aa..000000000 --- a/app/features/tournament/queries/hasTournamentFinalized.server.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { sql } from "~/db/sql"; -import type { Tables } from "~/db/tables"; - -const stm = sql.prepare(/*sql*/ ` - select 1 - from "TournamentResult" - where "TournamentResult"."tournamentId" = @tournamentId -`); - -export default function hasTournamentFinalized( - tournamentId: Tables["Tournament"]["id"], -) { - return Boolean(stm.get({ tournamentId })); -} diff --git a/app/features/tournament/queries/hasTournamentStarted.server.ts b/app/features/tournament/queries/hasTournamentStarted.server.ts deleted file mode 100644 index a1047d0a3..000000000 --- a/app/features/tournament/queries/hasTournamentStarted.server.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { sql } from "~/db/sql"; -import type { Tables } from "~/db/tables"; - -const stm = sql.prepare(/*sql*/ ` - select 1 - from "TournamentStage" - where "TournamentStage"."tournamentId" = @tournamentId -`); - -export default function hasTournamentStarted( - tournamentId: Tables["Tournament"]["id"], -) { - return Boolean(stm.get({ tournamentId })); -} diff --git a/app/features/tournament/queries/joinLeaveTeam.server.ts b/app/features/tournament/queries/joinLeaveTeam.server.ts deleted file mode 100644 index 8c81e01f2..000000000 --- a/app/features/tournament/queries/joinLeaveTeam.server.ts +++ /dev/null @@ -1,76 +0,0 @@ -import { sql } from "~/db/sql"; -import invariant from "~/utils/invariant"; -import { checkOut } from "./checkOut.server"; - -const createTeamMemberStm = sql.prepare(/*sql*/ ` - insert into "TournamentTeamMember" ( - "tournamentTeamId", - "inGameName", - "userId" - ) values ( - @tournamentTeamId, - @inGameName, - @userId - ) -`); - -const deleteTeamStm = sql.prepare(/*sql*/ ` - delete from "TournamentTeam" - where "id" = @tournamentTeamId -`); - -const deleteMemberStm = sql.prepare(/*sql*/ ` - delete from "TournamentTeamMember" - where "tournamentTeamId" = @tournamentTeamId - and "userId" = @userId -`); - -export const joinTeam = sql.transaction( - ({ - previousTeamId, - whatToDoWithPreviousTeam, - newTeamId, - userId, - inGameName, - tournamentId: _tournamentId, - checkOutTeam = false, - }: { - previousTeamId?: number; - whatToDoWithPreviousTeam?: "LEAVE" | "DELETE"; - newTeamId: number; - userId: number; - inGameName: string | null; - tournamentId: number; - checkOutTeam?: boolean; - }) => { - if (whatToDoWithPreviousTeam === "DELETE") { - deleteTeamStm.run({ tournamentTeamId: previousTeamId ?? null }); - } else if (whatToDoWithPreviousTeam === "LEAVE") { - deleteMemberStm.run({ tournamentTeamId: previousTeamId ?? null, userId }); - } - - if (checkOutTeam) { - invariant( - previousTeamId, - "previousTeamId is required when checking out team", - ); - checkOut(previousTeamId); - } - - createTeamMemberStm.run({ - tournamentTeamId: newTeamId, - userId, - inGameName, - }); - }, -); - -export const leaveTeam = ({ - teamId, - userId, -}: { - teamId: number; - userId: number; -}) => { - deleteMemberStm.run({ tournamentTeamId: teamId, userId }); -}; diff --git a/app/features/tournament/queries/upsertCounterpickMaps.server.ts b/app/features/tournament/queries/upsertCounterpickMaps.server.ts deleted file mode 100644 index c123c4ec2..000000000 --- a/app/features/tournament/queries/upsertCounterpickMaps.server.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { sql } from "~/db/sql"; -import type { Tables } from "~/db/tables"; -import type { MapPool } from "~/features/map-list-generator/core/map-pool"; - -const deleteCounterpickMapsByTeamIdStm = sql.prepare(/* sql */ ` - delete from - "MapPoolMap" - where - "tournamentTeamId" = @tournamentTeamId -`); - -const addCounterpickMapStm = sql.prepare(/* sql */ ` - insert into - "MapPoolMap" ("tournamentTeamId", "stageId", "mode") - values - (@tournamentTeamId, @stageId, @mode) -`); - -export const upsertCounterpickMaps = sql.transaction( - ({ - tournamentTeamId, - mapPool, - }: { - tournamentTeamId: Tables["TournamentTeam"]["id"]; - mapPool: MapPool; - }) => { - deleteCounterpickMapsByTeamIdStm.run({ tournamentTeamId }); - - for (const { stageId, mode } of mapPool.stageModePairs) { - addCounterpickMapStm.run({ - tournamentTeamId, - stageId, - mode, - }); - } - }, -); diff --git a/app/features/tournament/routes/to.$id.index.ts b/app/features/tournament/routes/to.$id.index.ts index 7ee47f7f1..4c5d2c1c0 100644 --- a/app/features/tournament/routes/to.$id.index.ts +++ b/app/features/tournament/routes/to.$id.index.ts @@ -1,4 +1,5 @@ import { type LoaderFunctionArgs, redirect } from "react-router"; +import { tournamentFromDBCached } from "~/features/tournament-bracket/core/Tournament.server"; import { parseParams } from "~/utils/remix.server"; import { tournamentBracketsPage, @@ -6,20 +7,23 @@ import { tournamentResultsPage, } from "~/utils/urls"; import { idObject } from "~/utils/zod"; -import hasTournamentFinalized from "../queries/hasTournamentFinalized.server"; -import hasTournamentStarted from "../queries/hasTournamentStarted.server"; -export const loader = ({ params }: LoaderFunctionArgs) => { +export const loader = async ({ params }: LoaderFunctionArgs) => { const { id: tournamentId } = parseParams({ params, schema: idObject, }); - if (!hasTournamentStarted(tournamentId)) { + const tournament = await tournamentFromDBCached({ + tournamentId, + user: undefined, + }); + + if (!tournament.hasStarted) { return redirect(tournamentRegisterPage(tournamentId)); } - if (!hasTournamentFinalized(tournamentId)) { + if (!tournament.ctx.isFinalized) { return redirect(tournamentBracketsPage({ tournamentId })); } diff --git a/app/features/tournament/tournament-test-utils.ts b/app/features/tournament/tournament-test-utils.ts index 4d7169e4c..8a903b025 100644 --- a/app/features/tournament/tournament-test-utils.ts +++ b/app/features/tournament/tournament-test-utils.ts @@ -3,7 +3,6 @@ import { databaseTimestampNow } from "~/utils/dates"; import invariant from "~/utils/invariant"; import { getServerTournamentManager } from "../tournament-bracket/core/brackets-manager/manager.server"; import { tournamentFromDB } from "../tournament-bracket/core/Tournament.server"; -import { joinTeam } from "./queries/joinLeaveTeam.server"; import { updateRoundMaps } from "./queries/updateRoundMaps.server"; import * as TournamentTeamRepository from "./TournamentTeamRepository.server"; @@ -57,7 +56,6 @@ export async function dbInsertTournamentTeam({ tournamentId?: number; }) { const tournamentTeam = await TournamentTeamRepository.create({ - ownerInGameName: null, team: { name: `Test Team ${ownerId}`, prefersNotToHost: 0, @@ -70,19 +68,13 @@ export async function dbInsertTournamentTeam({ for (let i = 1; i < membersCount; i++) { const memberId = ownerId + i; - joinTeam({ + await TournamentTeamRepository.join({ userId: memberId, newTeamId: tournamentTeam.id, - tournamentId, - inGameName: null, }); } - await TournamentTeamRepository.checkIn({ - tournamentTeamId: tournamentTeam.id, - // no sources = regular check in - bracketIdx: null, - }); + await TournamentTeamRepository.checkIn(tournamentTeam.id); } /** diff --git a/app/features/tournament/tournament-utils.server.ts b/app/features/tournament/tournament-utils.server.ts index cf92161fc..349942302 100644 --- a/app/features/tournament/tournament-utils.server.ts +++ b/app/features/tournament/tournament-utils.server.ts @@ -1,28 +1,11 @@ import * as LeaderboardRepository from "~/features/leaderboards/LeaderboardRepository.server"; import type { getServerTournamentManager } from "~/features/tournament-bracket/core/brackets-manager/manager.server"; import * as TournamentOrganizationRepository from "~/features/tournament-organization/TournamentOrganizationRepository.server"; -import * as UserRepository from "~/features/user-page/UserRepository.server"; import { logger } from "~/utils/logger"; import { errorToast, errorToastIfFalsy } from "~/utils/remix.server"; import { MATCHES_COUNT_NEEDED_FOR_LEADERBOARD } from "../leaderboards/leaderboards-constants"; import type { Tournament } from "../tournament-bracket/core/Tournament"; -export const inGameNameIfNeeded = async ({ - tournament, - userId, -}: { - tournament: Tournament; - userId: number; -}) => { - if (!tournament.ctx.settings.requireInGameNames) return null; - - const inGameName = await UserRepository.inGameNameByUserId(userId); - - errorToastIfFalsy(inGameName, "No in-game name"); - - return inGameName; -}; - export async function requireNotBannedByOrganization({ tournament, user, diff --git a/e2e/tournament-bracket.spec.ts b/e2e/tournament-bracket.spec.ts index 8d7069d18..4e8facf19 100644 --- a/e2e/tournament-bracket.spec.ts +++ b/e2e/tournament-bracket.spec.ts @@ -480,6 +480,7 @@ test.describe("Tournament bracket", () => { test("shows tournament results on user profile after finalized tournament", async ({ page, }) => { + test.slow(); const tournamentId = 4; await seed(page, "SMALL_SOS"); diff --git a/scripts/add-leaderboard-teams-to-tournament.ts b/scripts/add-leaderboard-teams-to-tournament.ts index 36311e22b..1e6bb9830 100644 --- a/scripts/add-leaderboard-teams-to-tournament.ts +++ b/scripts/add-leaderboard-teams-to-tournament.ts @@ -1,7 +1,6 @@ import "dotenv/config"; import * as LeaderboardRepository from "~/features/leaderboards/LeaderboardRepository.server"; import * as Seasons from "~/features/mmr/core/Seasons"; -import { joinTeam } from "~/features/tournament/queries/joinLeaveTeam.server"; import * as TournamentTeamRepository from "~/features/tournament/TournamentTeamRepository.server"; import { tournamentFromDB } from "~/features/tournament-bracket/core/Tournament.server"; import * as UserRepository from "~/features/user-page/UserRepository.server"; @@ -101,10 +100,6 @@ async function main() { const teamName = resolvedNames[i]; const owner = entry.members[0]; - const ownerInGameName = tournament.ctx.settings.requireInGameNames - ? await UserRepository.inGameNameByUserId(owner.id) - : null; - const tournamentTeam = await TournamentTeamRepository.create({ team: { name: teamName, @@ -113,19 +108,12 @@ async function main() { }, userId: owner.id, tournamentId, - ownerInGameName: ownerInGameName ?? null, }); for (const member of entry.members.slice(1)) { - const memberInGameName = tournament.ctx.settings.requireInGameNames - ? await UserRepository.inGameNameByUserId(member.id) - : null; - - joinTeam({ + await TournamentTeamRepository.join({ newTeamId: tournamentTeam.id, userId: member.id, - inGameName: memberInGameName ?? null, - tournamentId, }); }