Add public API endpoint to fetch tournament casted matches

This commit is contained in:
Kalle 2025-01-23 17:55:05 +02:00
parent 846f8fe8df
commit 54d30a37b0
3 changed files with 82 additions and 24 deletions

View File

@ -0,0 +1,51 @@
import { type LoaderFunctionArgs, json } from "@remix-run/node";
import { cors } from "remix-utils/cors";
import { z } from "zod";
import { db } from "~/db/sql";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import {
handleOptionsRequest,
requireBearerAuth,
} from "../api-public-utils.server";
import type { GetCastedTournamentMatchesResponse } 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 tournament = notFoundIfFalsy(
await db
.selectFrom("Tournament")
.select(["Tournament.castedMatchesInfo"])
.where("Tournament.id", "=", id)
.executeTakeFirst(),
);
const result: GetCastedTournamentMatchesResponse = {
current:
tournament.castedMatchesInfo?.castedMatches.map((match) => ({
matchId: match.matchId,
channel: {
type: "TWITCH",
channelId: match.twitchAccount,
},
})) ?? [],
future:
tournament.castedMatchesInfo?.lockedMatches.map((matchId) => ({
matchId: matchId,
channel: null,
})) ?? [],
};
return await cors(request, json(result));
};

View File

@ -34,14 +34,6 @@ export interface GetUserResponse {
weaponPool: Array<ProfileWeapon>;
badges: Array<Badge>;
peakXp: number | null;
// TODO: can be added to this endpoint / another one if use case arises
// leaderboardEntry: {
// season: number;
// position: number;
// power: number;
// tier: Tier;
// weapon: Weapon | null;
// } | null;
}
/** GET /api/calendar/{year}/{week} */
@ -155,6 +147,33 @@ export type GetTournamentTeamsResponse = Array<{
}>;
}>;
/** GET /api/tournament/{tournamentId}/casted */
export interface GetCastedTournamentMatchesResponse {
/*
* Matches that are currently being played and casted. Note: at the moment only one match can be casted at a time but this is an array for future proofing.
*/
current: Array<{
matchId: number;
channel: TournamentCastChannel;
}>;
/*
* Matches that are locked to be casted.
*/
future: Array<{
matchId: number;
channel: TournamentCastChannel | null;
}>;
}
type TournamentCastChannel = {
type: "TWITCH";
/**
* @example "iplsplatoon"
*/
channelId: string;
};
/** GET /api/tournament-match/{matchId} */
export interface GetTournamentMatchResponse {
@ -265,22 +284,6 @@ type Badge = {
gifUrl: string;
};
// type Tier =
// | "LEVIATHAN+"
// | "DIAMOND+"
// | "PLATINUM+"
// | "GOLD+"
// | "SILVER+"
// | "BRONZE+"
// | "IRON+"
// | "LEVIATHAN"
// | "DIAMOND"
// | "PLATINUM"
// | "GOLD"
// | "SILVER"
// | "BRONZE"
// | "IRON";
type ModeShort = "TW" | "SZ" | "TC" | "RM" | "CB";
type Stage = {
id: number;

View File

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