feat: student send join req

This commit is contained in:
Gabriellvl 2025-03-29 12:21:48 +01:00
parent 70d4c80093
commit 3093a6c131
12 changed files with 347 additions and 169 deletions

View file

@ -0,0 +1,18 @@
import { BadRequestException } from '../exceptions.js';
/**
* Checks for the presence of required fields and throws a BadRequestException
* if any are missing.
*
* @param fields - An object with key-value pairs to validate.
*/
export function requireFields(fields: Record<string, unknown>): void {
const missing = Object.entries(fields)
.filter(([_, value]) => value === undefined || value === null || value === '')
.map(([key]) => key);
if (missing.length > 0) {
const message = `Missing required field${missing.length > 1 ? 's' : ''}: ${missing.join(', ')}`;
throw new BadRequestException(message);
}
}

View file

@ -1,17 +1,19 @@
import { Request, Response } from 'express';
import {
createStudent,
createClassJoinRequest,
createStudent, deleteClassJoinRequest,
deleteStudent,
getAllStudents,
getAllStudents, getJoinRequestsByStudent,
getStudent,
getStudentAssignments,
getStudentClasses,
getStudentGroups,
getStudentQuestions,
getStudentSubmissions,
getStudentSubmissions, updateClassJoinRequestStatus,
} from '../services/students.js';
import { MISSING_FIELDS_ERROR, MISSING_USERNAME_ERROR, NAME_NOT_FOUND_ERROR } from './users.js';
import { StudentDTO } from '../interfaces/student.js';
import {BadRequestException} from "../exceptions";
import {requireFields} from "./error-helper";
export async function getAllStudentsHandler(req: Request, res: Response): Promise<void> {
@ -19,69 +21,42 @@ export async function getAllStudentsHandler(req: Request, res: Response): Promis
const students: StudentDTO[] | string[] = await getAllStudents(full);
if (!students) {
res.status(404).json({ error: `Students not found.` });
return;
}
res.json({ students });
}
export async function getStudentHandler(req: Request, res: Response): Promise<void> {
const username = req.params.username;
requireFields({ username });
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
const student = await getStudent(username);
const user = await getStudent(username);
if (!user) {
res.status(404).json(NAME_NOT_FOUND_ERROR(username));
return;
}
res.status(201).json(user);
res.status(201).json({ student });
}
export async function createStudentHandler(req: Request, res: Response) {
const username = req.body.username;
const firstName = req.body.firstName;
const lastName = req.body.lastName;
requireFields({ username, firstName, lastName });
const userData = req.body as StudentDTO;
if (!userData.username || !userData.firstName || !userData.lastName) {
res.status(400).json(MISSING_FIELDS_ERROR);
return;
}
const newUser = await createStudent(userData);
res.status(201).json(newUser);
const student = await createStudent(userData);
res.status(201).json({ student });
}
export async function deleteStudentHandler(req: Request, res: Response) {
const username = req.params.username;
requireFields({ username });
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
const deletedUser = await deleteStudent(username);
if (!deletedUser) {
res.status(404).json(NAME_NOT_FOUND_ERROR(username));
return;
}
res.status(200).json(deletedUser);
const student = await deleteStudent(username);
res.status(200).json({ student });
}
export async function getStudentClassesHandler(req: Request, res: Response): Promise<void> {
const full = req.query.full === 'true';
const username = req.params.username;
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
requireFields({ username });
const classes = await getStudentClasses(username, full);
@ -97,11 +72,7 @@ export async function getStudentClassesHandler(req: Request, res: Response): Pro
export async function getStudentAssignmentsHandler(req: Request, res: Response): Promise<void> {
const full = req.query.full === 'true';
const username = req.params.username;
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
requireFields({ username });
const assignments = getStudentAssignments(username, full);
@ -113,11 +84,7 @@ export async function getStudentAssignmentsHandler(req: Request, res: Response):
export async function getStudentGroupsHandler(req: Request, res: Response): Promise<void> {
const full = req.query.full === 'true';
const username = req.params.username;
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
requireFields({ username });
const groups = await getStudentGroups(username, full);
@ -128,11 +95,7 @@ export async function getStudentGroupsHandler(req: Request, res: Response): Prom
export async function getStudentSubmissionsHandler(req: Request, res: Response): Promise<void> {
const username = req.params.username;
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
requireFields({ username });
const submissions = await getStudentSubmissions(username);
@ -144,11 +107,7 @@ export async function getStudentSubmissionsHandler(req: Request, res: Response):
export async function getStudentQuestionsHandler(req: Request, res: Response): Promise<void> {
const full = req.query.full === 'true';
const username = req.params.username;
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
requireFields({ username });
const questions = await getStudentQuestions(username, full);
@ -156,3 +115,41 @@ export async function getStudentQuestionsHandler(req: Request, res: Response): P
questions,
});
}
export async function createStudentRequestHandler(req: Request, res: Response): Promise<void> {
const username = req.params.username;
const classId = req.params.classId;
requireFields({ username, classId });
await createClassJoinRequest(username, classId);
res.status(201).send();
}
export async function getStudentRequestHandler(req: Request, res: Response): Promise<void> {
const username = req.params.username;
requireFields({ username });
const requests = await getJoinRequestsByStudent(username);
res.status(201).json({ requests })
}
export async function updateClassJoinRequestHandler(req: Request, res: Response) {
const username = req.query.username as string;
const classId = req.params.classId;
const accepted = req.query.accepted !== 'false'; // default = true
requireFields({ username, classId });
const result = await updateClassJoinRequestStatus(username, classId, accepted);
res.status(200).json(result);
}
export async function deleteClassJoinRequestHandler(req: Request, res: Response) {
const username = req.query.username as string;
const classId = req.params.classId;
requireFields({ username, classId });
await deleteClassJoinRequest(username, classId);
res.status(204).send();
}

View file

@ -1,10 +1,18 @@
import { Request, Response } from 'express';
import { createTeacher, deleteTeacher, getAllTeachers, getClassesByTeacher, getStudentsByTeacher, getTeacher } from '../services/teachers.js';
import {
createTeacher,
deleteTeacher,
getAllTeachers,
getClassesByTeacher,
getStudentsByTeacher,
getTeacher,
getTeacherQuestions
} from '../services/teachers.js';
import { ClassDTO } from '../interfaces/class.js';
import { StudentDTO } from '../interfaces/student.js';
import { QuestionDTO, QuestionId } from '../interfaces/question.js';
import { TeacherDTO } from '../interfaces/teacher.js';
import { MISSING_FIELDS_ERROR, MISSING_USERNAME_ERROR, NAME_NOT_FOUND_ERROR } from './users';
import {requireFields} from "./error-helper";
export async function getAllTeachersHandler(req: Request, res: Response): Promise<void> {
const full = req.query.full === 'true';
@ -21,18 +29,11 @@ export async function getAllTeachersHandler(req: Request, res: Response): Promis
export async function getTeacherHandler(req: Request, res: Response): Promise<void> {
const username = req.params.username;
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
requireFields({ username });
const user = await getTeacher(username);
if (!user) {
res.status(404).json(NAME_NOT_FOUND_ERROR(username));
return;
}
res.status(201).json(user);
}
@ -41,7 +42,6 @@ export async function createTeacherHandler(req: Request, res: Response) {
const userData = req.body as TeacherDTO;
if (!userData.username || !userData.firstName || !userData.lastName) {
res.status(400).json(MISSING_FIELDS_ERROR);
return;
}
@ -53,13 +53,11 @@ export async function deleteTeacherHandler(req: Request, res: Response) {
const username = req.params.username;
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
const deletedUser = await deleteTeacher(username);
if (!deletedUser) {
res.status(404).json(NAME_NOT_FOUND_ERROR(username));
return;
}
@ -71,7 +69,6 @@ export async function getTeacherClassHandler(req: Request, res: Response): Promi
const full = req.query.full === 'true';
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
@ -85,7 +82,6 @@ export async function getTeacherStudentHandler(req: Request, res: Response): Pro
const full = req.query.full === 'true';
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
@ -99,11 +95,10 @@ export async function getTeacherQuestionHandler(req: Request, res: Response): Pr
const full = req.query.full === 'true';
if (!username) {
res.status(400).json(MISSING_USERNAME_ERROR);
return;
}
const questions: QuestionDTO[] | QuestionId[] = await getQuestionsByTeacher(username, full);
const questions: QuestionDTO[] | QuestionId[] = await getTeacherQuestions(username, full);
res.json({ questions });
}

View file

@ -1,7 +0,0 @@
export const MISSING_USERNAME_ERROR = { error: 'Missing required field: username' };
export function NAME_NOT_FOUND_ERROR(username: string) {
return { error: `User with username '${username}' not found.` };
}
export const MISSING_FIELDS_ERROR = { error: 'Missing required fields: username, firstName, lastName' };