diff --git a/src/Controllers/participant.controller.ts b/src/Controllers/participant.controller.ts index 2e0a56a..ee53b5e 100644 --- a/src/Controllers/participant.controller.ts +++ b/src/Controllers/participant.controller.ts @@ -1,5 +1,5 @@ import prisma from "../lib/prisma"; -import { z } from "zod"; +import { string, z } from "zod"; import { Request, Response } from "express"; import { DataType, generateError, generateInvalidBodyError } from "./common"; import { Prisma } from "@prisma/client"; @@ -10,7 +10,7 @@ import { requireLeaderOfTeam } from "../Middleware/auth/teamleaderAuth"; const InitialParticipant = z.object({ firstName: z.string(), lastName: z.string(), - groupPid: z.string().uuid(), + groupPid: z.string().min(1).uuid(), }); const ParticipantBody = InitialParticipant.extend({ teamPid: z.string().uuid() }); @@ -58,6 +58,21 @@ export const createParticipant = async (req: Request, res: Response) => { } try { + const discipline = await prisma.team.findUnique({ + where: { pid: body.teamPid }, + select: { discipline: true } + }); + + const maxteamsize = discipline?.discipline.maxTeamSize; + + const userCount = await prisma.participant.count({ + where: { team: { pid: body.teamPid } } + }); + + if (maxteamsize == userCount) { + return res.status(418).json({ type: "error", payload: "The team has reached the limit of participants!" }); + } + const participant = await prisma.participant.create({ data: { firstName: body.firstName, @@ -69,10 +84,7 @@ export const createParticipant = async (req: Request, res: Response) => { select: returnedParticipant, }); - return res.status(201).json({ - type: "success", - payload: { participant }, - }); + return res.status(201).json({ type: "success", payload: { participant }, }); } catch (e) { if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") { return res @@ -86,9 +98,10 @@ export const createParticipant = async (req: Request, res: Response) => { // at: PATCH api/participants/:pid/ export const updateParticipant = async (req: Request<{ pid: string }>, res: Response) => { const { pid } = req.params; + const teamPid = await getTeamPidByParticipantPid(pid); if (req.teamleader?.isAuthenticated) { - requireLeaderOfTeam(req.teamleader, pid); + requireLeaderOfTeam(req.teamleader, teamPid); } const result = InitialParticipant.partial().safeParse(req.body); @@ -135,9 +148,10 @@ export const updateParticipant = async (req: Request<{ pid: string }>, res: Resp // at: DELETE api/participants/:pid/ export const deleteParticipant = async (req: Request<{ pid: string }>, res: Response) => { const { pid } = req.params; + const teamPid = await getTeamPidByParticipantPid(pid); if (req.teamleader?.isAuthenticated) { - requireLeaderOfTeam(req.teamleader, pid); + requireLeaderOfTeam(req.teamleader, teamPid); } try { @@ -152,3 +166,16 @@ export const deleteParticipant = async (req: Request<{ pid: string }>, res: Resp throw e; } }; + +export const getTeamPidByParticipantPid = async function (partPid: string) { + const participant = await prisma.participant.findUnique({ + where: { pid: partPid }, + select: { team: { select: { pid: true } } } + }); + + if (!participant) { + throw new NotFoundError("participant", partPid); + } + + return participant.team.pid; +} diff --git a/src/Controllers/role.controller.ts b/src/Controllers/role.controller.ts index 294db70..250fa97 100644 --- a/src/Controllers/role.controller.ts +++ b/src/Controllers/role.controller.ts @@ -5,6 +5,7 @@ import prisma from "../lib/prisma"; import { requireLeaderOfTeam, requireResponsibleForParticipant } from "../Middleware/auth/teamleaderAuth"; import NotFoundError from "../Middleware/error/NotFoundError"; import { createInsufficientPermissionsError, DataType, generateInvalidBodyError } from "./common"; +import { getTeamPidByParticipantPid } from "./participant.controller"; require("express-async-errors"); @@ -53,15 +54,15 @@ export async function createRolesForTeam(teamPid: string) { return roles.count; } -export async function getRolesForTeam(req: Request<{ teamPid: string }>, res: Response) { - const teamPid = req.params.teamPid; +export async function getRolesForTeam(req: Request<{ pid: string }>, res: Response) { + const pid = req.params.pid; if (req.teamleader?.isAuthenticated) { - requireLeaderOfTeam(req.teamleader, teamPid); + requireLeaderOfTeam(req.teamleader, pid); } const roles = await prisma.role.findMany({ - where: { team: { pid: teamPid } }, + where: { team: { pid } }, select: { pid: true, score: true, @@ -80,16 +81,13 @@ export async function getRolesForTeam(req: Request<{ teamPid: string }>, res: Re const AssignParticipantToRoleBody = z.object({ participantPid: z.string().uuid(), + teamPid: z.string().uuid(), }); // requires: auth(leader of the team) export async function assignParticipantToRole(req: Request<{ pid: string }>, res: Response) { const { pid } = req.params; - if (req.teamleader?.isAuthenticated) { - requireLeaderOfTeam(req.teamleader, pid); - } - const zBody = AssignParticipantToRoleBody.safeParse(req.body); if (zBody.success === false) { @@ -97,6 +95,11 @@ export async function assignParticipantToRole(req: Request<{ pid: string }>, res } const { participantPid } = zBody.data; + const teamPid = await getTeamPidByParticipantPid(pid); + + if (req.teamleader?.isAuthenticated) { + requireLeaderOfTeam(req.teamleader, teamPid); + } const schema = await prisma.role.findFirst({ where: { pid, team: { participants: { some: { pid: participantPid } } } }, diff --git a/src/Controllers/team.controller.ts b/src/Controllers/team.controller.ts index 88d1271..15a8044 100644 --- a/src/Controllers/team.controller.ts +++ b/src/Controllers/team.controller.ts @@ -32,7 +32,7 @@ export const getTeams = async (req: Request, res: Response) => { res.status(200).json({ type: "success", payload: { teams } }); }; -export const getTeam = async (req: Request, res: Response) => { +export const getTeam = async (req: Request<{ pid: string }>, res: Response) => { const { pid } = req.params; if (req.teamleader?.isAuthenticated) { @@ -44,6 +44,10 @@ export const getTeam = async (req: Request, res: Response) => { select: basicTeam, }); + if (!team) { + throw new NotFoundError("team", pid); + } + res.status(200).json({ type: "success", payload: { team } }); }; diff --git a/src/Routes/role.routes.ts b/src/Routes/role.routes.ts index 6ca39ae..b23d118 100644 --- a/src/Routes/role.routes.ts +++ b/src/Routes/role.routes.ts @@ -4,17 +4,10 @@ import { requireConfiguredAuthentication } from "../Middleware/auth/auth"; const router = Express.Router(); -//TO DO: maybe transfer getRolesForTeam to team router -> Seconded -router.get<"team/:teamPid/", { teamPid: string }>( - "team/:teamPid/", - requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), - getRolesForTeam -); - router.put<"/:pid/participant", { pid: string }>( "/:pid/participant", requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), assignParticipantToRole ); -export default router; +export default router; \ No newline at end of file diff --git a/src/Routes/team.routes.ts b/src/Routes/team.routes.ts index b419c1c..a49789a 100644 --- a/src/Routes/team.routes.ts +++ b/src/Routes/team.routes.ts @@ -1,12 +1,13 @@ import express from "express"; import { requireConfiguredAuthentication } from "../Middleware/auth/auth"; import { deleteTeam, getTeam, getTeams, updateTeam } from "../Controllers/team.controller"; +import { getRolesForTeam } from "../Controllers/role.controller"; const router = express.Router(); router.get("/", requireConfiguredAuthentication({ type: "admin", optional: false }), getTeams); -router.get( - "/:id", +router.get<"/:pid/", { pid: string }>( + "/:pid/", requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), getTeam ); @@ -22,4 +23,10 @@ router.delete<"/:pid/", { pid: string }>( deleteTeam ); +router.get<"/:pid/roles", { pid: string }>( + "/:pid/roles", + requireConfiguredAuthentication({ optional: false, type: { admin: true, teamleader: true } }), + getRolesForTeam +); + export default router;