import { superTokensFunctionMiddleware, superTokensAdminFunctionMiddleware } from "@/utils/supertokens"; import { createServerFn } from "@tanstack/react-start"; import { pbAdmin } from "@/lib/pocketbase/client"; import { z } from "zod"; import { toServerResult } from "@/lib/tanstack-query/utils/to-server-result"; import { teamInputSchema, teamUpdateSchema } from "./types"; import { logger } from "@/lib/logger"; export const listTeams = createServerFn() .middleware([superTokensFunctionMiddleware]) .handler(async () => toServerResult(() => pbAdmin.listTeams()) ); export const listTeamInfos = createServerFn() .middleware([superTokensFunctionMiddleware]) .handler(async () => toServerResult(() => pbAdmin.listTeamInfos()) ); export const getTeam = createServerFn() .validator(z.string()) .middleware([superTokensFunctionMiddleware]) .handler(async ({ data: teamId }) => toServerResult(() => pbAdmin.getTeam(teamId)) ); export const getTeamInfo = createServerFn() .validator(z.string()) .middleware([superTokensFunctionMiddleware]) .handler(async ({ data: teamId }) => toServerResult(() => pbAdmin.getTeamInfo(teamId)) ); export const createTeam = createServerFn() .validator(teamInputSchema) .middleware([superTokensFunctionMiddleware]) .handler(async ({ data, context }) => toServerResult(async () => { const userId = context.userAuthId; const isAdmin = context.roles.includes("Admin"); // Check if user is trying to create a team with themselves as a player if (!isAdmin && !data.players.includes(userId)) { throw new Error("You can only create teams that include yourself as a player"); } // Additional validation: ensure user is not already on another team if (!isAdmin) { const userTeams = await pbAdmin.listTeams(); const existingTeam = userTeams.find(team => team.players.some(player => player.id === userId) ); if (existingTeam) { throw new Error(`You are already a member of team "${existingTeam.name}"`); } } logger.info("Creating team", { name: data.name, userId, isAdmin }); return pbAdmin.createTeam(data); }) ); export const updateTeam = createServerFn() .validator(z.object({ id: z.string(), updates: teamUpdateSchema })) .middleware([superTokensFunctionMiddleware]) .handler(async ({ data: { id, updates }, context }) => toServerResult(async () => { const userId = context.userAuthId; const isAdmin = context.roles.includes("Admin"); // Get the team to verify ownership const team = await pbAdmin.getTeam(id); if (!team) { throw new Error("Team not found"); } // Check if user has permission to update this team const isPlayerOnTeam = team.players.some(player => player.id === userId); if (!isAdmin && !isPlayerOnTeam) { throw new Error("You can only update teams that you are a member of"); } logger.info("Updating team", { teamId: id, userId, isAdmin }); return pbAdmin.updateTeam(id, updates); }) ); export const deleteTeam = createServerFn() .validator(z.string()) .middleware([superTokensAdminFunctionMiddleware]) .handler(async ({ data: teamId }) => toServerResult(() => pbAdmin.deleteTeam(teamId)) );