From 4c76a8217868f26741ba4de5fb790cb4c899f124 Mon Sep 17 00:00:00 2001 From: Adriaan Jacquet Date: Thu, 13 Mar 2025 15:49:13 +0100 Subject: [PATCH 1/2] feat: (broken) POST method voor groep --- backend/src/controllers/groups.ts | 26 +++++++++- .../src/entities/assignments/group.entity.ts | 4 +- backend/src/interfaces/group.ts | 4 +- backend/src/interfaces/teacher-invitation.ts | 2 +- backend/src/routes/groups.ts | 4 +- backend/src/services/groups.ts | 48 +++++++++++++++++++ 6 files changed, 81 insertions(+), 7 deletions(-) diff --git a/backend/src/controllers/groups.ts b/backend/src/controllers/groups.ts index 8b26b810..5fd90553 100644 --- a/backend/src/controllers/groups.ts +++ b/backend/src/controllers/groups.ts @@ -1,5 +1,6 @@ import { Request, Response } from 'express'; -import { getAllGroups, getGroup, getGroupSubmissions } from '../services/groups.js'; +import { createGroup, getAllGroups, getGroup, getGroupSubmissions } from '../services/groups.js'; +import { GroupDTO } from '../interfaces/group.js'; // Typescript is annoywith with parameter forwarding from class.ts interface GroupParams { @@ -54,6 +55,29 @@ export async function getAllGroupsHandler( }); } +export async function createGroupHandler( + req: Request, + res: Response, +): Promise { + const classid = req.params.classid; + const assignmentId = +req.params.assignmentid; + + if (isNaN(assignmentId)) { + res.status(400).json({ error: 'Assignment id must be a number' }); + return; + } + + const groupData = req.body as GroupDTO; + const group = createGroup(groupData, classid, assignmentId); + + if (!group) { + res.status(500).json({ error: "Something went wrong while creating group" }); + return + } + + res.status(201).json({ group: group }); +} + export async function getGroupSubmissionsHandler( req: Request, res: Response, diff --git a/backend/src/entities/assignments/group.entity.ts b/backend/src/entities/assignments/group.entity.ts index 9c2ed2cf..0db4f6b0 100644 --- a/backend/src/entities/assignments/group.entity.ts +++ b/backend/src/entities/assignments/group.entity.ts @@ -17,8 +17,8 @@ export class Group { }) assignment!: Assignment; - @PrimaryKey({ type: 'integer' }) - groupNumber!: number; + @PrimaryKey({ type: 'integer', autoincrement: true }) + groupNumber?: number; @ManyToMany({ entity: () => { diff --git a/backend/src/interfaces/group.ts b/backend/src/interfaces/group.ts index ca7f687a..2dd3f2c1 100644 --- a/backend/src/interfaces/group.ts +++ b/backend/src/interfaces/group.ts @@ -11,7 +11,7 @@ export interface GroupDTO { export function mapToGroupDTO(group: Group): GroupDTO { return { assignment: mapToAssignmentDTO(group.assignment), // ERROR: , group.assignment.within), - groupNumber: group.groupNumber, + groupNumber: group.groupNumber!, members: group.members.map(mapToStudentDTO), }; } @@ -19,7 +19,7 @@ export function mapToGroupDTO(group: Group): GroupDTO { export function mapToGroupDTOId(group: Group): GroupDTO { return { assignment: group.assignment.id!, - groupNumber: group.groupNumber, + groupNumber: group.groupNumber!, members: group.members.map((member) => { return member.username; }), diff --git a/backend/src/interfaces/teacher-invitation.ts b/backend/src/interfaces/teacher-invitation.ts index badbbbd7..d29e7476 100644 --- a/backend/src/interfaces/teacher-invitation.ts +++ b/backend/src/interfaces/teacher-invitation.ts @@ -24,6 +24,6 @@ export function mapToTeacherInvitationDTOIds( return { sender: invitation.sender.username, receiver: invitation.receiver.username, - class: invitation.class.classId, + class: invitation.class.classId!, }; } diff --git a/backend/src/routes/groups.ts b/backend/src/routes/groups.ts index d17a330e..b3be0f7a 100644 --- a/backend/src/routes/groups.ts +++ b/backend/src/routes/groups.ts @@ -1,11 +1,13 @@ import express from 'express'; -import { getAllGroupsHandler, getGroupHandler, getGroupSubmissionsHandler } from '../controllers/groups.js'; +import { createGroupHandler, getAllGroupsHandler, getGroupHandler, getGroupSubmissionsHandler } from '../controllers/groups.js'; const router = express.Router({ mergeParams: true }); // Root endpoint used to search objects router.get('/', getAllGroupsHandler); +router.post('/', createGroupHandler); + // Information about a group (members, ... [TODO DOC]) router.get('/:groupid', getGroupHandler); diff --git a/backend/src/services/groups.ts b/backend/src/services/groups.ts index a2af8e4a..65e111fb 100644 --- a/backend/src/services/groups.ts +++ b/backend/src/services/groups.ts @@ -1,9 +1,12 @@ +import { GroupRepository } from '../data/assignments/group-repository.js'; import { getAssignmentRepository, getClassRepository, getGroupRepository, + getStudentRepository, getSubmissionRepository, } from '../data/repositories.js'; +import { Group } from '../entities/assignments/group.entity.js'; import { GroupDTO, mapToGroupDTO, @@ -51,6 +54,51 @@ export async function getGroup( return mapToGroupDTOId(group); } +export async function createGroup( + groupData: GroupDTO, + classid: string, + assignmentNumber: number, +): Promise { + const studentRepository = getStudentRepository(); + + const memberUsernames = groupData.members as string[] || []; // TODO check if groupdata.members is a list + const members = (await Promise.all([...memberUsernames].map(id => studentRepository.findByUsername(id)))) + .filter(student => student != null); + + console.log(members); + + 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(); + try { + console.log('EEEEE'); + const newGroup = groupRepository.create({ + assignment: assignment, + members: members, + }); + console.log('OOOOOO'); + await groupRepository.save(newGroup); + console.log('AAAAAA'); + + return newGroup; + } catch(e) { + console.log(e); + return null; + } +} + export async function getAllGroups( classId: string, assignmentNumber: number, From 53c85eadb09706eeeb4f1c04e2a31dbf224f5c6d Mon Sep 17 00:00:00 2001 From: Adriaan Jacquet Date: Thu, 13 Mar 2025 16:39:59 +0100 Subject: [PATCH 2/2] feat: (BROKEN) kolossale bug in POST group aan het fixen --- backend/src/data/users/student-repository.ts | 15 +++++++++++++-- backend/src/data/users/teacher-repository.ts | 10 +++++++++- .../src/entities/assignments/assignment.entity.ts | 3 ++- backend/src/entities/assignments/group.entity.ts | 10 ++++------ backend/src/entities/users/student.entity.ts | 8 ++++++++ backend/src/services/groups.ts | 3 --- 6 files changed, 36 insertions(+), 13 deletions(-) diff --git a/backend/src/data/users/student-repository.ts b/backend/src/data/users/student-repository.ts index 6835e430..d3be9081 100644 --- a/backend/src/data/users/student-repository.ts +++ b/backend/src/data/users/student-repository.ts @@ -1,4 +1,15 @@ import { Student } from '../../entities/users/student.entity.js'; -import { UserRepository } from './user-repository.js'; +import { User } from '../../entities/users/user.entity.js'; +import { DwengoEntityRepository } from '../dwengo-entity-repository.js'; +// import { UserRepository } from './user-repository.js'; -export class StudentRepository extends UserRepository {} +// export class StudentRepository extends UserRepository {} + +export class StudentRepository extends DwengoEntityRepository { + public findByUsername(username: string): Promise { + return this.findOne({ username: username }); + } + public deleteByUsername(username: string): Promise { + return this.deleteWhere({ username: username }); + } +} \ No newline at end of file diff --git a/backend/src/data/users/teacher-repository.ts b/backend/src/data/users/teacher-repository.ts index 4c4f7687..23ba559e 100644 --- a/backend/src/data/users/teacher-repository.ts +++ b/backend/src/data/users/teacher-repository.ts @@ -1,4 +1,12 @@ import { Teacher } from '../../entities/users/teacher.entity.js'; +import { DwengoEntityRepository } from '../dwengo-entity-repository.js'; import { UserRepository } from './user-repository.js'; -export class TeacherRepository extends UserRepository {} +export class TeacherRepository extends DwengoEntityRepository { + public findByUsername(username: string): Promise { + return this.findOne({ username: username }); + } + public deleteByUsername(username: string): Promise { + return this.deleteWhere({ username: username }); + } +} \ No newline at end of file diff --git a/backend/src/entities/assignments/assignment.entity.ts b/backend/src/entities/assignments/assignment.entity.ts index ecb02b90..015dcdc5 100644 --- a/backend/src/entities/assignments/assignment.entity.ts +++ b/backend/src/entities/assignments/assignment.entity.ts @@ -1,4 +1,5 @@ import { + Collection, Entity, Enum, ManyToOne, @@ -50,5 +51,5 @@ export class Assignment { }, mappedBy: 'assignment', }) - groups!: Group[]; + groups!: Collection; } diff --git a/backend/src/entities/assignments/group.entity.ts b/backend/src/entities/assignments/group.entity.ts index 0db4f6b0..446c0c0d 100644 --- a/backend/src/entities/assignments/group.entity.ts +++ b/backend/src/entities/assignments/group.entity.ts @@ -1,4 +1,4 @@ -import { Entity, ManyToMany, ManyToOne, PrimaryKey } from '@mikro-orm/core'; +import { Collection, Entity, ManyToMany, ManyToOne, PrimaryKey } from '@mikro-orm/core'; import { Assignment } from './assignment.entity.js'; import { Student } from '../users/student.entity.js'; import { GroupRepository } from '../../data/assignments/group-repository.js'; @@ -20,10 +20,8 @@ export class Group { @PrimaryKey({ type: 'integer', autoincrement: true }) groupNumber?: number; - @ManyToMany({ - entity: () => { - return Student; - }, + @ManyToMany(() => { + return Student; }) - members!: Student[]; + members!: Collection; } diff --git a/backend/src/entities/users/student.entity.ts b/backend/src/entities/users/student.entity.ts index 7ad8c9b3..c5632e84 100644 --- a/backend/src/entities/users/student.entity.ts +++ b/backend/src/entities/users/student.entity.ts @@ -19,4 +19,12 @@ export class Student extends User { return Group; }) groups!: Collection; + + constructor( + public username: string, + public firstName: string, + public lastName: string + ) { + super(); + } } diff --git a/backend/src/services/groups.ts b/backend/src/services/groups.ts index 65e111fb..2f2d0a14 100644 --- a/backend/src/services/groups.ts +++ b/backend/src/services/groups.ts @@ -83,14 +83,11 @@ export async function createGroup( const groupRepository = getGroupRepository(); try { - console.log('EEEEE'); const newGroup = groupRepository.create({ assignment: assignment, members: members, }); - console.log('OOOOOO'); await groupRepository.save(newGroup); - console.log('AAAAAA'); return newGroup; } catch(e) {