mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-07-24 12:11:56 -05:00
Report score backend logic initial
This commit is contained in:
parent
5536f8c1cb
commit
c016813fbb
|
|
@ -1,9 +1,21 @@
|
|||
export const isTournamentAdmin = ({
|
||||
import type { TournamentTeamMember } from "@prisma/client";
|
||||
|
||||
export function isTournamentAdmin({
|
||||
userId,
|
||||
organization,
|
||||
}: {
|
||||
userId?: string;
|
||||
organization: { ownerId: string };
|
||||
}) => {
|
||||
}) {
|
||||
return organization.ownerId === userId;
|
||||
};
|
||||
}
|
||||
|
||||
export function canReportMatchScore({
|
||||
userId,
|
||||
members,
|
||||
}: {
|
||||
userId: string;
|
||||
members: TournamentTeamMember[];
|
||||
}) {
|
||||
return members.some((member) => member.memberId === userId);
|
||||
}
|
||||
|
|
|
|||
51
app/models/TournamentMatch.ts
Normal file
51
app/models/TournamentMatch.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import { Prisma, TeamOrder } from "@prisma/client";
|
||||
import { db } from "~/utils/db.server";
|
||||
|
||||
export type FindById = Prisma.PromiseReturnType<typeof findById>;
|
||||
export function findById(id: string) {
|
||||
return db.tournamentMatch.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
round: {
|
||||
include: {
|
||||
stages: true,
|
||||
},
|
||||
},
|
||||
results: true,
|
||||
participants: {
|
||||
include: {
|
||||
team: {
|
||||
include: {
|
||||
members: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
export function createResult({
|
||||
position,
|
||||
reporterId,
|
||||
winner,
|
||||
matchId,
|
||||
}: {
|
||||
position: number;
|
||||
reporterId: string;
|
||||
winner: TeamOrder;
|
||||
matchId: string;
|
||||
}) {
|
||||
return db.tournamentMatchGameResult.create({
|
||||
data: {
|
||||
position,
|
||||
reporterId,
|
||||
winner,
|
||||
match: {
|
||||
connect: {
|
||||
id: matchId,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
import type { Prisma, Stage } from ".prisma/client";
|
||||
import type { Prisma, Stage, TournamentMatchGameResult } from ".prisma/client";
|
||||
import {
|
||||
TOURNAMENT_CHECK_IN_CLOSING_MINUTES_FROM_START,
|
||||
TOURNAMENT_TEAM_ROSTER_MAX_SIZE,
|
||||
|
|
@ -11,13 +11,17 @@ import {
|
|||
tournamentRoundsForDB,
|
||||
winnersRoundNames,
|
||||
} from "~/core/tournament/bracket";
|
||||
import { isTournamentAdmin } from "~/core/tournament/permissions";
|
||||
import { sortTeamsBySeed } from "~/core/tournament/utils";
|
||||
import {
|
||||
canReportMatchScore,
|
||||
isTournamentAdmin,
|
||||
} from "~/core/tournament/permissions";
|
||||
import { matchIsOver, sortTeamsBySeed } from "~/core/tournament/utils";
|
||||
import * as Tournament from "~/models/Tournament";
|
||||
import * as TournamentBracket from "~/models/TournamentBracket";
|
||||
import * as TournamentTeam from "~/models/TournamentTeam";
|
||||
import * as TournamentTeamMember from "~/models/TournamentTeamMember";
|
||||
import * as TrustRelationship from "~/models/TrustRelationship";
|
||||
import * as TournamentMatch from "~/models/TournamentMatch";
|
||||
import { Serialized, Unpacked } from "~/utils";
|
||||
import { db } from "~/utils/db.server";
|
||||
|
||||
|
|
@ -526,3 +530,50 @@ export async function updateSeeds({
|
|||
// TODO: fail if tournament has started
|
||||
return Tournament.updateSeeds({ tournamentId, seeds: newSeeds });
|
||||
}
|
||||
|
||||
export async function reportScore({
|
||||
userId,
|
||||
winnerTeamId,
|
||||
matchId,
|
||||
rosters,
|
||||
}: {
|
||||
userId: string;
|
||||
winnerTeamId: string;
|
||||
matchId: string;
|
||||
stagePosition: number;
|
||||
rosters: Record<string, string[]>;
|
||||
}) {
|
||||
const match = await TournamentMatch.findById(matchId);
|
||||
if (!match) throw new Response("Invalid match id", { status: 400 });
|
||||
if (
|
||||
!canReportMatchScore({
|
||||
userId,
|
||||
members: match.participants.flatMap((p) => p.team.members),
|
||||
})
|
||||
) {
|
||||
throw new Response("No permissions to report score", { status: 401 });
|
||||
}
|
||||
if (match.results.some((result) => result.matchId === matchId)) {
|
||||
// no throw so it's handled gracefully if both teams report the score at the same time
|
||||
return;
|
||||
}
|
||||
if (
|
||||
matchIsOver(match.round.stages.length, matchResultsToTuple(match.results))
|
||||
) {
|
||||
throw new Response("Match is already over", { status: 400 });
|
||||
}
|
||||
|
||||
// put to DB
|
||||
// if over advance bracket
|
||||
}
|
||||
|
||||
function matchResultsToTuple(results: TournamentMatchGameResult[]) {
|
||||
return results.reduce(
|
||||
(acc: [number, number], result) => {
|
||||
if (result.winner === "UPPER") acc[0]++;
|
||||
else acc[1]++;
|
||||
return acc;
|
||||
},
|
||||
[0, 0]
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user