sendou.ink/app/features/api-public/routes/org.$id.ts
2025-12-29 20:04:40 +02:00

78 lines
2.3 KiB
TypeScript

import { jsonArrayFrom } from "kysely/helpers/sqlite";
import type { LoaderFunctionArgs } from "react-router";
import { cors } from "remix-utils/cors";
import { z } from "zod";
import { db } from "~/db/sql";
import { concatUserSubmittedImagePrefix } from "~/utils/kysely.server";
import { notFoundIfFalsy, parseParams } from "~/utils/remix.server";
import { id } from "~/utils/zod";
import {
handleOptionsRequest,
requireBearerAuth,
} from "../api-public-utils.server";
import type { GetTournamentOrganizationResponse } 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 organization = notFoundIfFalsy(
await db
.selectFrom("TournamentOrganization")
.leftJoin(
"UserSubmittedImage",
"UserSubmittedImage.id",
"TournamentOrganization.avatarImgId",
)
.select((eb) => [
"TournamentOrganization.id",
"TournamentOrganization.name",
"TournamentOrganization.description",
"TournamentOrganization.socials",
"TournamentOrganization.slug",
concatUserSubmittedImagePrefix(eb.ref("UserSubmittedImage.url")).as(
"logoUrl",
),
jsonArrayFrom(
eb
.selectFrom("TournamentOrganizationMember")
.innerJoin("User", "User.id", "TournamentOrganizationMember.userId")
.select([
"User.id",
"User.discordId",
"User.username",
"TournamentOrganizationMember.role",
"TournamentOrganizationMember.roleDisplayName",
])
.where("TournamentOrganizationMember.organizationId", "=", id),
).as("members"),
])
.where("TournamentOrganization.id", "=", id)
.executeTakeFirst(),
);
const result: GetTournamentOrganizationResponse = {
id: organization.id,
name: organization.name,
description: organization.description,
logoUrl: organization.logoUrl,
socialLinkUrls: organization.socials ?? [],
url: `https://sendou.ink/org/${organization.slug}`,
members: organization.members.map((member) => ({
userId: member.id,
discordId: member.discordId,
name: member.username,
role: member.role,
roleDisplayName: member.roleDisplayName,
})),
};
return await cors(request, Response.json(result));
};