Merge branch 'feature-endpoints' into feature-roles

This commit is contained in:
Laurin
2022-06-03 22:39:38 +02:00
21 changed files with 331 additions and 485 deletions
+16 -64
View File
@@ -1,10 +1,10 @@
import { Prisma, Organisation, Admin, AdminLevel, Team } from "@prisma/client";
import { PrismaClientKnownRequestError, PrismaClientUnknownRequestError } from "@prisma/client/runtime";
import { Request, Response } from "express";
import { z } from "zod";
import prisma from "../lib/prisma";
import ForwardableError from "../Middleware/error/ForwardableError";
import NotFoundError from "../Middleware/error/NotFoundError";
import { number, z } from "zod";
import {
createInsufficientPermissionsError,
DataType,
@@ -20,6 +20,8 @@ const InitialDisciplineBody = z.object({
name: z.string().min(1),
minTeamSize: z.number(),
maxTeamSize: z.number(),
briefDescription: z.string().min(1),
fullDescription: z.string(),
});
const disciplineRefiner = [
@@ -27,7 +29,7 @@ const disciplineRefiner = [
{ message: "The minTeamSize must be smaller or equal to the maxTeamSize" },
] as const;
const DisciplineBody = InitialDisciplineBody.refine(...disciplineRefiner);
const DisciplineBody = InitialDisciplineBody.partial({ fullDescription: true }).refine(...disciplineRefiner);
const updateDisciplineBody = InitialDisciplineBody.partial().refine(...disciplineRefiner);
const basicDiscipline = {
@@ -36,6 +38,8 @@ const basicDiscipline = {
visual: { select: { pid: true } },
maxTeamSize: true,
minTeamSize: true,
briefDescription: true,
fullDescription: true,
event: { select: { pid: true, name: true } },
roles: { select: { pid: true, name: true } },
} as const;
@@ -132,6 +136,8 @@ interface CreateDisciplineBody {
name?: string;
minTeamSize?: number;
maxTeamSize?: number;
briefDescription?: string;
fullDescription?: string;
}
// require: auth(ELEVATED)
@@ -150,17 +156,19 @@ export const createDiscipline = async (req: Request<{ eventPid: string }, {}, Cr
name: DataType.STRING,
minTeamSize: DataType.NUMBER,
maxTeamSize: DataType.NUMBER,
briefDescription: DataType.STRING,
["fullDescription?"]: DataType.STRING,
},
result.error
)
);
}
const { name, minTeamSize, maxTeamSize } = result.data;
const { name, minTeamSize, maxTeamSize, briefDescription } = result.data;
try {
const discipline = await prisma.discipline.create({
data: { name, minTeamSize, maxTeamSize, event: { connect: { pid: req.params.eventPid } } },
data: { name, minTeamSize, maxTeamSize, briefDescription, event: { connect: { pid: req.params.eventPid } } },
select: basicDiscipline,
});
@@ -188,6 +196,8 @@ export const updateDiscipline = async (req: Request<{ pid: string }>, res: Respo
name: DataType.STRING,
minTeamSize: DataType.NUMBER,
maxTeamSize: DataType.NUMBER,
briefDescription: DataType.STRING,
["fullDescription?"]: DataType.STRING,
},
result.error
)
@@ -204,6 +214,8 @@ export const updateDiscipline = async (req: Request<{ pid: string }>, res: Respo
name: body.name,
minTeamSize: body.minTeamSize,
maxTeamSize: body.maxTeamSize,
briefDescription: body.briefDescription,
fullDescription: body.fullDescription,
},
select: basicDiscipline,
});
@@ -241,63 +253,3 @@ export const deleteDiscipline = async (req: Request<{ pid: string }>, res: Respo
throw e;
}
};
interface visualParams {
disciplinePid: string;
}
interface visualBody {
mediaPid: string;
}
export const addVisual = async (req: Request<visualParams, {}, visualBody>, res: Response) => {
if (req.auth?.permission_level != "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { disciplinePid } = req.params;
const discipline = await prisma.discipline.update({
where: { pid: disciplinePid },
data: {
visual: { connect: { pid: req.body.mediaPid } },
},
});
// TODO: This does not work and should be updated in all addVisual-type code segments
// Reason: update throw a PrismaClientKnownRequestError with code P2025 if the record to update could not be found
if (!discipline) {
throw new NotFoundError("discipline", disciplinePid);
}
return res.status(200).json({
type: "success",
payload: {},
});
};
export const deleteVisual = async (req: Request<visualParams & { pid: string }>, res: Response) => {
if (req.auth?.permission_level != "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { disciplinePid, pid } = req.params;
try {
await prisma.discipline.update({
where: {
pid: disciplinePid,
},
data: {
visual: { disconnect: { pid } },
},
});
return res.status(204).end();
} catch (e) {
if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") {
throw new NotFoundError("discipline", disciplinePid); // Refer: Last todo; This is a correct example
}
throw e;
}
};
+60 -137
View File
@@ -1,6 +1,6 @@
import { Prisma } from "@prisma/client";
import { PrismaClientKnownRequestError } from "@prisma/client/runtime";
import { Request, Response } from "express";
import e, { Request, Response } from "express";
import { z } from "zod";
import prisma from "../lib/prisma";
import NotFoundError from "../Middleware/error/NotFoundError";
@@ -8,17 +8,49 @@ import { createInsufficientPermissionsError, DataType, generateError, generateIn
require("express-async-errors");
export const dateSchema = z.preprocess((arg) => {
if (typeof arg == "string" || arg instanceof Date) return new Date(arg);
}, z.date());
const EventBody = z.object({
name: z.string().min(1),
date: dateSchema,
briefDescription: z.string(),
fullDescription: z.string(),
});
const UpdateBody = EventBody.partial();
const CreateEventBody = EventBody.partial({
fullDescription: true,
});
const basicEvent = {
pid: true,
name: true,
date: true,
briefDescription: true,
fullDescription: true,
} as const;
const detailedEvent = {
pid: true,
name: true,
date: true,
briefDescription: true,
fullDescription: true,
visual: { select: { pid: true, description: true } },
disciplines: {
select: {
pid: true,
name: true,
},
},
} as const;
export const getAllEvents = async (req: Request, res: Response) => {
const events = await prisma.event.findMany({
select: {
name: true,
briefDescription: true,
fullDescription: true,
visual: { select: { pid: true, description: true } },
date: true,
pid: true,
id: false,
},
select: detailedEvent,
});
res.status(200).json({
@@ -45,15 +77,7 @@ export const getEvent = async (req: Request, res: Response) => {
where: {
pid: eventId,
},
select: {
name: true,
briefDescription: true,
fullDescription: true,
date: true,
pid: true,
id: false,
visual: { select: { pid: true, description: true } },
},
select: detailedEvent,
});
if (!event) {
@@ -96,24 +120,23 @@ export const addEvent = async (req: Request, res: Response) => {
if (req.auth?.permission_level !== "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
if (
typeof req.body.name !== "string" ||
typeof req.body.date !== "string" ||
typeof req.body.briefDescription !== "string" ||
(req.body.fullDescription && typeof req.body.fullDescription !== "string")
) {
const result = CreateEventBody.safeParse(req.body);
if (result.success === false) {
return res.status(400).json(
generateInvalidBodyError({
name: DataType.STRING,
date: DataType.DATETIME,
briefDescription: DataType.STRING,
["fullDescription?"]: DataType.STRING,
})
generateInvalidBodyError(
{
name: DataType.STRING,
date: DataType.DATETIME,
briefDescription: DataType.STRING,
["fullDescription?"]: DataType.STRING,
},
result.error
)
);
}
//TODO: Check if date is valid
const event = await prisma.event.create({
data: {
name: req.body.name,
@@ -121,14 +144,7 @@ export const addEvent = async (req: Request, res: Response) => {
briefDescription: req.body.briefDescription,
fullDescription: req.body.fullDescription,
},
select: {
name: true,
date: true,
pid: true,
id: false,
briefDescription: true,
fullDescription: true,
},
select: basicEvent,
});
res.status(201).json({
@@ -139,15 +155,6 @@ export const addEvent = async (req: Request, res: Response) => {
});
};
const EventBody = z.object({
name: z.string(),
date: z.string(),
briefDescription: z.string(),
fullDescription: z.string(),
});
const UpdateBody = EventBody.partial();
export const updateEvent = async (req: Request<{ pid: string }>, res: Response) => {
if (req.auth?.permission_level !== "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
@@ -191,10 +198,6 @@ export const updateEvent = async (req: Request<{ pid: string }>, res: Response)
},
});
if (!event) {
throw new NotFoundError("event", pid);
}
res.status(200).json({
type: "success",
payload: {
@@ -202,24 +205,8 @@ export const updateEvent = async (req: Request<{ pid: string }>, res: Response)
},
});
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError) {
return res.status(500).json({
type: "error",
payload: {
message: `Internal Server error occured. Try again later`,
},
});
}
if (e instanceof Prisma.PrismaClientUnknownRequestError) {
return res.status(500).json({
type: "error",
payload: {
message: "Unknown error occurred with your request. Check if your parameters are correct",
schema: {
eventId: DataType.UUID,
},
},
});
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === "P2025") {
throw new NotFoundError("discipline", pid);
}
throw e;
@@ -244,71 +231,7 @@ export const deleteEvent = async (req: Request<DeleteEventQueryParams>, res: Res
return res.status(204).end();
} catch (e) {
if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") {
return res.status(404).json(generateError(`The event with the ID ${pid} could not be found`));
}
throw e;
}
};
// REVIEW: This code **will** need to be de-duplicated
interface visualParams {
eventPid: string;
}
interface visualBody {
mediaPid: string;
}
export const addVisual = async (req: Request<visualParams, {}, visualBody>, res: Response) => {
if (req.auth?.permission_level != "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { eventPid } = req.params;
if (typeof req.body.mediaPid !== "string") {
res.status(400).json(generateInvalidBodyError({ mediaPid: DataType.STRING }));
}
const event = await prisma.event.update({
where: { pid: eventPid },
data: {
visual: { connect: { pid: req.body.mediaPid } },
},
});
if (!event) {
throw new NotFoundError("event", eventPid);
}
return res.status(200).json({
type: "success",
payload: {},
});
};
export const deleteVisual = async (req: Request<visualParams & { pid: string }>, res: Response) => {
if (req.auth?.permission_level != "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { eventPid, pid } = req.params;
try {
await prisma.event.update({
where: {
pid: eventPid,
},
data: {
visual: { disconnect: { pid } },
},
});
return res.status(204).end();
} catch (e) {
if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") {
throw new NotFoundError("discipline", eventPid);
throw new NotFoundError("discipline", pid);
}
throw e;
+1 -1
View File
@@ -192,7 +192,7 @@ export const deleteGroup = async (req: Request<DeleteGroupQueryParams>, res: Res
const { pid } = req.params;
try {
prisma.group.delete({ where: { pid } });
await prisma.group.delete({ where: { pid } });
return res.status(204).end();
} catch (e) {
+69 -4
View File
@@ -1,4 +1,4 @@
import { Request, response, Response } from "express";
import { Request, Response } from "express";
import fs from "fs";
import isSvg from "is-svg";
import { fromBuffer as fileTypeFromBuffer } from "file-type";
@@ -8,10 +8,8 @@ import prisma from "../lib/prisma";
import NotFoundError from "../Middleware/error/NotFoundError";
import { PrismaClientKnownRequestError } from "@prisma/client/runtime";
import { generateInvalidBodyError, DataType } from "./common";
import { type } from "os";
import { unlink } from "fs/promises";
import ForwardableError from "../Middleware/error/ForwardableError";
import SchemaError from "../Middleware/error/SchemaError";
require("express-async-errors");
@@ -99,7 +97,6 @@ export const uploadImage = async (req: Request, res: Response) => {
const fileName = file.md5 + (fileIsSvg ? ".svg" : "." + fileType?.ext);
try {
//generate record
const media = await prisma.media.create({
data: {
pid: fileName,
@@ -189,3 +186,71 @@ export const deleteMedia = async (req: Request, res: Response) => {
throw e;
}
};
export const linkMedia = async (req: Request<{ pid: string }, {}, { mediaPid: string }>, res: Response) => {
if (req.auth?.permission_level != "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { pid } = req.params;
const { mediaPid } = req.body;
const tableToUpdate = req.originalUrl.split("/");
if (typeof mediaPid !== "string") {
return res.status(400).json(
generateInvalidBodyError({
mediaPid: DataType.UUID,
})
);
}
const updatedRec = await getPrismaUpdateFKT(tableToUpdate[2])({
where: { pid },
data: {
visual: { connect: { pid: mediaPid } },
},
});
if (!updatedRec) {
throw new NotFoundError(tableToUpdate[2], pid);
}
return res.status(200).json({
type: "success",
payload: {},
});
};
export const unlinkMedia = async (req: Request<{ pid: string; mediaPid: string }>, res: Response) => {
if (req.auth?.permission_level != "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { pid, mediaPid } = req.params;
const tableToUpdate = req.originalUrl.split("/");
try {
await getPrismaUpdateFKT(tableToUpdate[2])({
where: { pid },
data: { visual: { disconnect: { pid: mediaPid } } },
});
return res.status(204).end();
} catch (e) {
if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") {
throw new NotFoundError(tableToUpdate[2], pid);
}
throw e;
}
};
function getPrismaUpdateFKT(tableToUpdate: string): Function {
switch (tableToUpdate) {
case "events":
return prisma.event.update;
case "disciplines":
return prisma.discipline.update;
default:
return prisma.roleSchema.update;
}
}
+6 -9
View File
@@ -12,6 +12,7 @@ import {
} from "./common";
import { PrismaClientKnownRequestError } from "@prisma/client/runtime";
import { Prisma } from "@prisma/client";
import NotFoundError from "../Middleware/error/NotFoundError";
function validateOranisationName(name: string) {
return name.length > 0;
@@ -187,16 +188,12 @@ export const updateOrganisation = async (
},
});
} catch (e) {
if (e instanceof PrismaClientKnownRequestError) {
if (e.code === "P2025") {
return res.status(404).json(generateError(`The organisation with the ID ${pid} could not be found`));
}
} else if (e instanceof PrismaClientUnknownRequestError) {
return res.status(400).send(generateError("Unkonwn error occured. This could be due to malformed IDs"));
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === "P2025") {
throw new NotFoundError("discipline", pid);
}
}
return res.status(500).json(genericError);
throw e;
}
};
interface DeleteOrganisationQueryParams {
@@ -216,7 +213,7 @@ export const deleteOrganisation = async (req: Request<DeleteOrganisationQueryPar
const { pid } = req.params;
try {
prisma.organisation.delete({ where: { pid } });
await prisma.organisation.delete({ where: { pid } });
res.status(204).end();
} catch (e) {
+18 -29
View File
@@ -11,20 +11,21 @@ import {
import { Job, Prisma } from "@prisma/client";
import { PrismaClientKnownRequestError } from "@prisma/client/runtime";
import NotFoundError from "../Middleware/error/NotFoundError";
import { requireResponsibleForGroup } from "../Middleware/auth/auth";
import { requireConfiguredAuthentication, requireResponsibleForGroup } from "../Middleware/auth/auth";
//TODO: add TeamleaderAuthentification
// REVIEW: All this code should be able to be executed by the teamleader of the team the participant is in AND
// an admin the group of whom overlaps with the team AND an elevated admin
const ParticipantBody = z.object({
const InitialParticipant = z.object({
firstName: z.string(),
lastName: z.string(),
groupId: z.string().uuid(),
//job: z.enum(["TEAMLEADER", "MEMBER"]),
groupPid: z.string().uuid(),
});
const ParticipantBody = InitialParticipant.extend({ teamPid: z.string().uuid() });
const returnedParticipant = {
pid: true,
firstName: true,
@@ -44,8 +45,8 @@ const returnedParticipant = {
},
} as const;
// REVIEW: Location of this endpoints (/groups, /teams, /participants, ...?)
export const createParticipant = async (req: Request<{ pid: string }>, res: Response) => {
// at: POST api/teams/:teamPid/participant/
export const createParticipant = async (req: Request, res: Response) => {
const result = ParticipantBody.safeParse(req.body);
if (result.success === false) {
@@ -54,24 +55,14 @@ export const createParticipant = async (req: Request<{ pid: string }>, res: Resp
{
firstname: DataType.STRING,
lastName: DataType.STRING,
groupId: DataType.UUID,
groupPid: DataType.UUID,
teamPid: DataType.UUID,
},
result.error
)
);
}
const body = result.data;
const { pid } = req.params;
/*
if (!req.auth?.isAuthenticated || req.teamleader?.team != pid) {
return res.status(500).json(AUTH_ERROR);
}
if (req.teamleader?.team != pid) {
return res.status(500).json(AUTH_ERROR);
}
requireResponsibleForGroup(req.auth, req.body.groupId);
*/
try {
const participant = await prisma.participant.create({
@@ -79,8 +70,8 @@ export const createParticipant = async (req: Request<{ pid: string }>, res: Resp
firstName: body.firstName,
lastName: body.lastName,
relevance: "MEMBER",
group: { connect: { pid: body.groupId } },
team: { connect: { pid } },
group: { connect: { pid: body.groupPid } },
team: { connect: { pid: body.teamPid } },
},
select: returnedParticipant,
});
@@ -93,16 +84,15 @@ export const createParticipant = async (req: Request<{ pid: string }>, res: Resp
if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") {
return res
.status(404)
.json(generateError(`Could not link to team with ID '${pid}, or group with ID ${body.groupId}'`));
.json(generateError(`Could not link to team with ID '${body.teamPid}, or group with ID ${body.groupPid}'`));
}
throw e;
}
};
// at: PATCH api/participants/:pid/
export const updateParticipant = async (req: Request<{ pid: string }>, res: Response) => {
//insert TeamleaderAuth
const result = ParticipantBody.partial().safeParse(req.body); // Should be partial, right?
const result = InitialParticipant.partial().safeParse(req.body);
if (result.success === false) {
return res.status(400).json(
@@ -110,7 +100,7 @@ export const updateParticipant = async (req: Request<{ pid: string }>, res: Resp
{
firstname: DataType.STRING,
lastName: DataType.STRING,
groupId: DataType.UUID,
groupPid: DataType.UUID,
},
result.error
)
@@ -126,7 +116,7 @@ export const updateParticipant = async (req: Request<{ pid: string }>, res: Resp
data: {
firstName: body.firstName,
lastName: body.lastName,
group: { connect: { pid: body.groupId } },
group: { connect: { pid: body.groupPid } },
},
select: returnedParticipant,
});
@@ -144,9 +134,8 @@ 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) => {
//insert TeamleaderAuth
const { pid } = req.params;
try {
@@ -155,7 +144,7 @@ export const deleteParticipant = async (req: Request<{ pid: string }>, res: Resp
return res.status(204).end();
} catch (e) {
if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") {
return res.status(404).json(generateError(`The participant with the ID ${pid} could not be found`));
throw new NotFoundError("participant", pid);
}
throw e;
+24 -65
View File
@@ -8,6 +8,30 @@ import { createInsufficientPermissionsError, DataType, generateInvalidBodyError
require("express-async-errors");
const detailedRole = {
pid: true,
score: true,
schema: {
select: {
pid: true,
name: true,
},
},
participant: {
select: {
pid: true,
firstName: true,
lastName: true,
},
},
team: {
select: {
pid: true,
name: true,
},
},
};
/**
*
* @param teamPid: Pid of the team to add the roles to
@@ -67,8 +91,6 @@ export async function assignParticipantToRole(req: Request<{ pid: string }>, res
const { participantPid } = zBody.data;
const rolePid = req.params.pid;
requireResponsibleForParticipant(req.teamleader, participantPid);
const schema = await prisma.role.findFirst({
where: { pid: rolePid, team: { participants: { some: { pid: participantPid } } } },
select: { participant: { select: { pid: true, firstName: true, lastName: true } } },
@@ -94,66 +116,3 @@ export async function assignParticipantToRole(req: Request<{ pid: string }>, res
},
});
}
export const updateRoleScore = async (req: Request<{ pid: string }, {}, { score: string }>, res: Response) => {
if (req.auth?.permission_level != "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { score } = req.body;
if (typeof score !== "string") {
res.status(400).json(generateInvalidBodyError({ score: DataType.STRING }));
}
const { pid } = req.params;
try {
const role = await prisma.role.update({
where: { pid },
data: { score },
select: {
pid: true,
score: true,
schema: {
select: {
pid: true,
name: true,
},
},
participant: {
select: {
pid: true,
firstName: true,
lastName: true,
},
},
team: {
select: {
pid: true,
name: true,
},
},
},
});
res.status(200).json({
type: "success",
payload: {
role,
},
});
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === "P2025") {
throw new NotFoundError("role", pid);
}
throw e;
}
};
export async function deleteRolesFromTeam(teamPid: string) {
await prisma.role.deleteMany({
where: { team: { pid: teamPid } },
});
}
+11 -89
View File
@@ -20,7 +20,7 @@ const RoleSchemaBody = z.object({
schema: z.string(),
});
const UpdateRoleSchema = RoleSchemaBody.partial();
const UpdateBody = RoleSchemaBody.partial();
const roleSchema = {
pid: true,
@@ -134,126 +134,48 @@ export const createRoleSchema = async (
}
};
export const updateRoleSchema = async (req: Request<{ pid: string }>, res: Response) => {
export const UpdateRoleSchema = async (req: Request<{ pid: string }>, res: Response) => {
if (req.auth?.permission_level !== "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { pid } = req.params;
const result = UpdateRoleSchema.safeParse(req.body);
const result = UpdateBody.safeParse(req.body);
if (result.success === false) {
return res.status(400).json(
generateInvalidBodyError(
{
name: DataType.STRING,
schema: DataType.RESULT_SCHEMA,
schema: DataType.STRING,
},
result.error
)
);
}
const { name, schema } = result.data;
const validatedSchema = parseSchema(schema);
const body = result.data;
try {
const schema = await prisma.roleSchema.update({
where: { pid },
data: {
name: name,
schema: validatedSchema,
name: body.name,
schema: body.schema,
},
select: roleSchema,
});
res.status(200).json({
type: "success",
payload: schema,
payload: {
schema,
},
});
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === "P2025") {
throw new NotFoundError("roleSchema", pid);
}
throw e;
}
};
export const deleteRoleSchema = async (req: Request<{ pid: string }>, res: Response) => {
if (req.auth?.permission_level !== "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { pid } = req.params;
try {
await prisma.roleSchema.delete({ where: { pid } });
return res.status(204).end();
} catch (e) {
if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") {
return res.status(404).json(generateError(`The RoleSchema with the ID ${pid} could not be found`));
}
throw e;
}
};
interface visualParams {
schemaPid: string;
}
interface visualBody {
mediaPid: string;
}
export const addVisual = async (req: Request<visualParams, {}, visualBody>, res: Response) => {
if (req.auth?.permission_level != "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { schemaPid } = req.params;
const schema = await prisma.roleSchema.update({
where: { pid: schemaPid },
data: {
visual: { connect: { pid: req.body.mediaPid } },
},
});
if (!schema) {
throw new NotFoundError("role_schema", schemaPid);
}
return res.status(200).json({
type: "success",
payload: {},
});
};
export const deleteVisual = async (req: Request<visualParams & { pid: string }>, res: Response) => {
if (req.auth?.permission_level != "ELEVATED") {
res.status(403).json(createInsufficientPermissionsError());
}
const { schemaPid, pid } = req.params;
try {
await prisma.roleSchema.update({
where: {
pid: schemaPid,
},
data: {
visual: { disconnect: { pid } },
},
});
return res.status(204).end();
} catch (e) {
if (e instanceof PrismaClientKnownRequestError && e.code === "P2025") {
throw new NotFoundError("role_schema", schemaPid);
throw new NotFoundError("discipline", pid);
}
throw e;
+46 -19
View File
@@ -4,9 +4,31 @@ import { createInsufficientPermissionsError, DataType, generateInvalidBodyError
import { requireLeaderOfTeam } from "../Middleware/auth/teamleaderAuth";
import { z } from "zod";
import { TeamBody } from "./user_auth.controller";
import { Prisma } from "@prisma/client";
import NotFoundError from "../Middleware/error/NotFoundError";
export const basicTeam = {
pid: true,
name: true,
discipline: { select: { pid: true } },
roles: {
select: {
pid: true,
schema: { select: { name: true } },
participant: { select: { pid: true } },
},
},
participants: {
select: {
pid: true,
firstName: true,
lastName: true,
},
},
};
export const getTeams = async (req: Request, res: Response) => {
const teams = prisma.team.findMany({ select: { pid: true, name: true, disciplineId: true } });
const teams = await prisma.team.findMany({ select: basicTeam });
res.status(200).json({ type: "success", payload: { teams } });
};
@@ -14,13 +36,9 @@ export const getTeams = async (req: Request, res: Response) => {
export const getTeam = async (req: Request, res: Response) => {
const { pid } = req.params;
const team = prisma.team.findUnique({
const team = await prisma.team.findUnique({
where: { pid },
select: {
disciplineId: true,
name: true,
pid: true,
},
select: basicTeam,
});
res.status(200).json({ type: "success", payload: { team } });
@@ -48,26 +66,35 @@ export const updateTeam = async (req: Request, res: Response) => {
requireLeaderOfTeam(req.teamleader, body.pid);
const team = prisma.team.update({
where: {
pid: body.pid,
},
data: {
name: body.teamName,
discipline: { connect: { pid: body.disciplineId } },
leaderEmail: body.leaderEmail,
},
});
try {
const team = await prisma.team.update({
where: {
pid: body.pid,
},
data: {
name: body.teamName,
discipline: { connect: { pid: body.disciplineId } },
leaderEmail: body.leaderEmail,
},
});
res.status(204).json({ type: "success", payload: { team } });
res.status(204).json({ type: "success", payload: { team } });
} catch (e) {
if (e instanceof Prisma.PrismaClientKnownRequestError && e.code === "P2025") {
throw new NotFoundError("team", body.pid);
}
throw e;
}
};
export const deleteTeam = async (req: Request, res: Response) => {
const { pid } = req.params;
// TODO: accept admin auth
requireLeaderOfTeam(req.teamleader, pid);
prisma.team.delete({ where: { pid } });
await prisma.team.delete({ where: { pid } });
res.status(204).json({ type: "success", payload: { message: "Sucesfully deleted team" } });
};
+4 -2
View File
@@ -7,6 +7,7 @@ import { createInsufficientPermissionsError, DataType, generateError, generateIn
import { generateTeamleaderJWT, requireLeaderOfTeam } from "../Middleware/auth/teamleaderAuth";
import { createRolesForTeam } from "./role.controller";
import { any, z } from "zod";
import { basicTeam } from "./team.controller";
export const TeamBody = z.object({
teamName: z.string().min(1),
@@ -81,13 +82,13 @@ export const register = async (req: Request<{}, {}, CreateTeamBody>, res: Respon
},
});
//TODO: maybe use returned amount of created use?
createRolesForTeam(team.pid);
await createRolesForTeam(team.pid);
const usid = nanoid();
(await mailClient).set(usid, team.pid);
// TODO: fix "eventname"
verificationMail(req.body.leaderEmail, "eventname", usid);
res.status(201).json({ type: "success", payload: { team } });
@@ -114,6 +115,7 @@ export const requestToken = async (req: Request, res: Response) => {
(await mailClient).set(usid, team.pid);
// TODO: fix "eventname"
verificationMail(team.leaderEmail, "eventname", usid);
res.status(200).json({ type: "sucess", payload: { message: "Email sent!" } });