From 3f62ab70e1d77ad8c3718e553d923c51c5388213 Mon Sep 17 00:00:00 2001 From: Adriaan Jacquet Date: Sat, 8 Mar 2025 21:49:29 +0100 Subject: [PATCH] feat: group verbinding tussen databank en api aangemaakt --- backend/src/controllers/groups.ts | 34 ++++++++++++++++++ .../src/data/assignments/group-repository.ts | 7 ++-- backend/src/interfaces/groups.ts | 22 ++++++++++++ backend/src/routes/assignment.ts | 14 +++----- backend/src/routes/group.ts | 15 ++------ backend/src/services/groups.ts | 36 +++++++++++++++++++ 6 files changed, 104 insertions(+), 24 deletions(-) create mode 100644 backend/src/controllers/groups.ts create mode 100644 backend/src/services/groups.ts diff --git a/backend/src/controllers/groups.ts b/backend/src/controllers/groups.ts new file mode 100644 index 00000000..7ca6617d --- /dev/null +++ b/backend/src/controllers/groups.ts @@ -0,0 +1,34 @@ +import { Request, Response } from 'express'; +import { getGroup } from '../services/groups'; + +// typescript is annoywith with parameter forwarding from class.ts +interface GroupParams { + classid: string; + assignmentid: string; + groupid: string; +} + +export async function getGroupHandler( + req: Request, + res: Response, +): Promise { + const classId = req.params.classid; + const full = req.query.full === "true"; + const assignmentId = +req.params.assignmentid; + + if (isNaN(assignmentId)) { + res.status(400).json({ error: "Assignment id must be a number" }); + return; + } + + const groupId = +req.params.groupid; + + if (isNaN(groupId)) { + res.status(400).json({ error: "Group id must be a number" }); + return; + } + + const group = await getGroup(classId, assignmentId, groupId, full); + + res.json(group); +} \ No newline at end of file diff --git a/backend/src/data/assignments/group-repository.ts b/backend/src/data/assignments/group-repository.ts index ff8ca507..3992e113 100644 --- a/backend/src/data/assignments/group-repository.ts +++ b/backend/src/data/assignments/group-repository.ts @@ -7,10 +7,13 @@ export class GroupRepository extends DwengoEntityRepository { assignment: Assignment, groupNumber: number ): Promise { - return this.findOne({ + return this.findOne( + { assignment: assignment, groupNumber: groupNumber, - }); + }, + { populate: ["members"] }, + ); } public findAllGroupsForAssignment( assignment: Assignment diff --git a/backend/src/interfaces/groups.ts b/backend/src/interfaces/groups.ts index 6056a906..fe78cc69 100644 --- a/backend/src/interfaces/groups.ts +++ b/backend/src/interfaces/groups.ts @@ -1,3 +1,25 @@ +import { Group } from "../entities/assignments/group.entity"; +import { AssignmentDTO, mapToAssignmentDTO } from "./assignments"; +import { mapToStudentDTO, StudentDTO } from "./students"; + export interface GroupDTO { + assignment: number | AssignmentDTO, groupNumber: number, + members: string[] | StudentDTO[], +}; + +export function mapToGroupDTO(group: Group): GroupDTO { + return { + assignment: mapToAssignmentDTO(group.assignment, group.assignment.within), + groupNumber: group.groupNumber, + members: group.members.map(mapToStudentDTO), + } +} + +export function mapToGroupDTOId(group: Group): GroupDTO { + return { + assignment: group.assignment.id, + groupNumber: group.groupNumber, + members: group.members.map(member => member.username), + } } \ No newline at end of file diff --git a/backend/src/routes/assignment.ts b/backend/src/routes/assignment.ts index e9c91160..35b4b986 100644 --- a/backend/src/routes/assignment.ts +++ b/backend/src/routes/assignment.ts @@ -1,9 +1,9 @@ import express from 'express' import { getAssignmentHandler } from '../controllers/assignments'; +import groupRouter from './group.js'; + const router = express.Router({ mergeParams: true }); - - // root endpoint used to search objects router.get('/', (req, res) => { res.json({ @@ -25,14 +25,6 @@ router.get('/:id/submissions', (req, res) => { }); }); -router.get('/:id/groups', (req, res) => { - res.json({ - groups: [ - '0' - ], - }); -}); - router.get('/:id/questions', (req, res) => { res.json({ questions: [ @@ -41,4 +33,6 @@ router.get('/:id/questions', (req, res) => { }); }); +router.use('/:assignmentid/groups', groupRouter); + export default router \ No newline at end of file diff --git a/backend/src/routes/group.ts b/backend/src/routes/group.ts index e55dddd1..436e228a 100644 --- a/backend/src/routes/group.ts +++ b/backend/src/routes/group.ts @@ -1,5 +1,6 @@ import express from 'express' -const router = express.Router(); +import { getGroupHandler } from '../controllers/groups'; +const router = express.Router({ mergeParams: true }); // root endpoint used to search objects router.get('/', (req, res) => { @@ -12,17 +13,7 @@ router.get('/', (req, res) => { }); // information about a group (members, ... [TODO DOC]) -router.get('/:id', (req, res) => { - res.json({ - id: req.params.id, - assignment: '0', - students: [ '0' ], - submissions: [ '0' ], - // reference to other endpoint - // should be less hardcoded - questions: `/group/${req.params.id}/question`, - }); -}) +router.get('/:groupid', getGroupHandler); // the list of questions a group has made router.get('/:id/question', (req, res) => { diff --git a/backend/src/services/groups.ts b/backend/src/services/groups.ts new file mode 100644 index 00000000..c1b6cf33 --- /dev/null +++ b/backend/src/services/groups.ts @@ -0,0 +1,36 @@ +import { getAssignmentRepository, getClassRepository, getGroupRepository } from "../data/repositories"; +import { GroupDTO, mapToGroupDTO, mapToGroupDTOId } from "../interfaces/groups"; + +export async function getGroup( + classId: string, + assignmentNumber: number, + groupNumber: number, + full: boolean, +): Promise { + const classRepository = getClassRepository(); + const cls = await classRepository.findById(classId); + + if (!cls) { + return null; + } + + const assignmentRepository = getAssignmentRepository(); + const assignment = await assignmentRepository.findByClassAndId(cls, assignmentNumber); + + if (!assignment) { + return null; + } + + const groupRepository = getGroupRepository(); + const group = await groupRepository.findByAssignmentAndGroupNumber(assignment, groupNumber); + + if (!group) { + return null; + } + + if (full) { + return mapToGroupDTO(group); + } + + return mapToGroupDTOId(group); +} \ No newline at end of file