Feature/add tournament active players endpoint (#2497)

Co-authored-by: Kalle <38327916+Sendouc@users.noreply.github.com>
This commit is contained in:
cesaregarza
2025-08-28 10:53:33 -05:00
committed by GitHub
parent 17250ba177
commit 2ab24f64fa
5 changed files with 68 additions and 35 deletions

View File

@@ -0,0 +1,30 @@
import { json, type LoaderFunctionArgs } from "@remix-run/node";
import { cors } from "remix-utils/cors";
import { z } from "zod/v4";
import * as TournamentMatchRepository from "~/features/tournament-bracket/TournamentMatchRepository.server";
import { parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import {
handleOptionsRequest,
requireBearerAuth,
} from "../api-public-utils.server";
import type { GetTournamentPlayersResponse } from "../schema";
const paramsSchema = z.object({
id,
});
export const loader = async ({ params, request }: LoaderFunctionArgs) => {
await handleOptionsRequest(request);
requireBearerAuth(request);
const { id } = parseParams({
params,
schema: paramsSchema,
});
const participants: GetTournamentPlayersResponse =
await TournamentMatchRepository.userParticipationByTournamentId(id);
return cors(request, json(participants));
};

View File

@@ -200,6 +200,13 @@ export type GetTournamentTeamsResponse = Array<{
}>;
}>;
/** GET /api/tournament/{tournamentId}/players */
export type GetTournamentPlayersResponse = Array<{
userId: number;
matchIds: number[];
}>;
/** GET /api/tournament/{tournamentId}/casted */
export interface GetCastedTournamentMatchesResponse {

View File

@@ -11,3 +11,30 @@ export function findResultById(id: number) {
.where("TournamentMatchGameResult.id", "=", id)
.executeTakeFirst();
}
export async function userParticipationByTournamentId(tournamentId: number) {
return db
.with("playerMatches", (db) =>
db
.selectFrom("TournamentMatchGameResultParticipant as Participant")
.innerJoin(
"TournamentMatchGameResult as GameResult",
"GameResult.id",
"Participant.matchGameResultId",
)
.innerJoin("TournamentMatch as Match", "Match.id", "GameResult.matchId")
.innerJoin("TournamentStage as Stage", "Stage.id", "Match.stageId")
.select(["Participant.userId", "GameResult.matchId"])
.where("Stage.tournamentId", "=", tournamentId)
.distinct(),
)
.selectFrom("playerMatches")
.select(({ fn, ref }) => [
"playerMatches.userId",
fn
.agg<number[]>("json_group_array", [ref("playerMatches.matchId")])
.as("matchIds"),
])
.groupBy("playerMatches.userId")
.execute();
}

View File

@@ -1,35 +0,0 @@
import { sql } from "~/db/sql";
import type { Tables } from "~/db/tables";
const stm = sql.prepare(/* sql */ `
select
"User"."id",
"User"."username",
"User"."discordAvatar",
"User"."discordId",
"User"."customUrl",
"User"."country",
"TournamentTeam"."id" as "tournamentTeamId"
from "TournamentTeam"
left join "TournamentTeamMember" on "TournamentTeamMember"."tournamentTeamId" = "TournamentTeam"."id"
left join "User" on "User"."id" = "TournamentTeamMember"."userId"
left join "TournamentStage" on "TournamentStage"."tournamentId" = "TournamentTeam"."tournamentId"
left join "TournamentMatch" on "TournamentMatch"."stageId" = "TournamentStage"."id"
left join "TournamentMatchGameResult" on "TournamentMatchGameResult"."matchId" = "TournamentMatch"."id"
right join "TournamentMatchGameResultParticipant" on
"TournamentMatchGameResultParticipant"."matchGameResultId" = "TournamentMatchGameResult"."id"
and
"TournamentTeamMember"."userId" = "TournamentMatchGameResultParticipant"."userId"
where "TournamentTeam"."tournamentId" = @tournamentId
group by "User"."id"
`);
export type PlayerThatPlayedByTeamId = Pick<
Tables["User"],
"id" | "username" | "discordAvatar" | "discordId" | "customUrl" | "country"
> & { tournamentTeamId: number };
export function playersThatPlayedByTournamentId(tournamentId: number) {
return stm.all({ tournamentId }) as PlayerThatPlayedByTeamId[];
}

View File

@@ -269,6 +269,10 @@ export default [
"/tournament/:id/teams",
"features/api-public/routes/tournament.$id.teams.ts",
),
route(
"/tournament/:id/players",
"features/api-public/routes/tournament.$id.players.ts",
),
route(
"/tournament/:id/casted",
"features/api-public/routes/tournament.$id.casted.ts",