Merge remote-tracking branch 'origin/feat/service-layer' into feat/service-layer
This commit is contained in:
commit
a66d5e6b09
9 changed files with 113 additions and 16 deletions
|
@ -1,5 +1,6 @@
|
||||||
import { Request, Response } from 'express';
|
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
|
// Typescript is annoywith with parameter forwarding from class.ts
|
||||||
interface GroupParams {
|
interface GroupParams {
|
||||||
|
@ -54,6 +55,29 @@ export async function getAllGroupsHandler(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createGroupHandler(
|
||||||
|
req: Request,
|
||||||
|
res: Response,
|
||||||
|
): Promise<void> {
|
||||||
|
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(
|
export async function getGroupSubmissionsHandler(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
|
|
|
@ -1,4 +1,15 @@
|
||||||
import { Student } from '../../entities/users/student.entity.js';
|
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<Student> {}
|
// export class StudentRepository extends UserRepository<Student> {}
|
||||||
|
|
||||||
|
export class StudentRepository extends DwengoEntityRepository<Student> {
|
||||||
|
public findByUsername(username: string): Promise<Student | null> {
|
||||||
|
return this.findOne({ username: username });
|
||||||
|
}
|
||||||
|
public deleteByUsername(username: string): Promise<void> {
|
||||||
|
return this.deleteWhere({ username: username });
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,12 @@
|
||||||
import { Teacher } from '../../entities/users/teacher.entity.js';
|
import { Teacher } from '../../entities/users/teacher.entity.js';
|
||||||
|
import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
|
||||||
import { UserRepository } from './user-repository.js';
|
import { UserRepository } from './user-repository.js';
|
||||||
|
|
||||||
export class TeacherRepository extends UserRepository<Teacher> {}
|
export class TeacherRepository extends DwengoEntityRepository<Teacher> {
|
||||||
|
public findByUsername(username: string): Promise<Teacher | null> {
|
||||||
|
return this.findOne({ username: username });
|
||||||
|
}
|
||||||
|
public deleteByUsername(username: string): Promise<void> {
|
||||||
|
return this.deleteWhere({ username: username });
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
import {
|
import {
|
||||||
|
Collection,
|
||||||
Entity,
|
Entity,
|
||||||
Enum,
|
Enum,
|
||||||
ManyToOne,
|
ManyToOne,
|
||||||
|
@ -50,5 +51,5 @@ export class Assignment {
|
||||||
},
|
},
|
||||||
mappedBy: 'assignment',
|
mappedBy: 'assignment',
|
||||||
})
|
})
|
||||||
groups!: Group[];
|
groups!: Collection<Group>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 { Assignment } from './assignment.entity.js';
|
||||||
import { Student } from '../users/student.entity.js';
|
import { Student } from '../users/student.entity.js';
|
||||||
import { GroupRepository } from '../../data/assignments/group-repository.js';
|
import { GroupRepository } from '../../data/assignments/group-repository.js';
|
||||||
|
@ -17,13 +17,11 @@ export class Group {
|
||||||
})
|
})
|
||||||
assignment!: Assignment;
|
assignment!: Assignment;
|
||||||
|
|
||||||
@PrimaryKey({ type: 'integer' })
|
@PrimaryKey({ type: 'integer', autoincrement: true })
|
||||||
groupNumber!: number;
|
groupNumber?: number;
|
||||||
|
|
||||||
@ManyToMany({
|
@ManyToMany(() => {
|
||||||
entity: () => {
|
return Student;
|
||||||
return Student;
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
members!: Student[];
|
members!: Collection<Student>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,4 +19,12 @@ export class Student extends User {
|
||||||
return Group;
|
return Group;
|
||||||
})
|
})
|
||||||
groups!: Collection<Group>;
|
groups!: Collection<Group>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public username: string,
|
||||||
|
public firstName: string,
|
||||||
|
public lastName: string
|
||||||
|
) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ export interface GroupDTO {
|
||||||
export function mapToGroupDTO(group: Group): GroupDTO {
|
export function mapToGroupDTO(group: Group): GroupDTO {
|
||||||
return {
|
return {
|
||||||
assignment: mapToAssignmentDTO(group.assignment), // ERROR: , group.assignment.within),
|
assignment: mapToAssignmentDTO(group.assignment), // ERROR: , group.assignment.within),
|
||||||
groupNumber: group.groupNumber,
|
groupNumber: group.groupNumber!,
|
||||||
members: group.members.map(mapToStudentDTO),
|
members: group.members.map(mapToStudentDTO),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ export function mapToGroupDTO(group: Group): GroupDTO {
|
||||||
export function mapToGroupDTOId(group: Group): GroupDTO {
|
export function mapToGroupDTOId(group: Group): GroupDTO {
|
||||||
return {
|
return {
|
||||||
assignment: group.assignment.id!,
|
assignment: group.assignment.id!,
|
||||||
groupNumber: group.groupNumber,
|
groupNumber: group.groupNumber!,
|
||||||
members: group.members.map((member) => {
|
members: group.members.map((member) => {
|
||||||
return member.username;
|
return member.username;
|
||||||
}),
|
}),
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
import express from 'express';
|
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 });
|
const router = express.Router({ mergeParams: true });
|
||||||
|
|
||||||
// Root endpoint used to search objects
|
// Root endpoint used to search objects
|
||||||
router.get('/', getAllGroupsHandler);
|
router.get('/', getAllGroupsHandler);
|
||||||
|
|
||||||
|
router.post('/', createGroupHandler);
|
||||||
|
|
||||||
// Information about a group (members, ... [TODO DOC])
|
// Information about a group (members, ... [TODO DOC])
|
||||||
router.get('/:groupid', getGroupHandler);
|
router.get('/:groupid', getGroupHandler);
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,12 @@
|
||||||
|
import { GroupRepository } from '../data/assignments/group-repository.js';
|
||||||
import {
|
import {
|
||||||
getAssignmentRepository,
|
getAssignmentRepository,
|
||||||
getClassRepository,
|
getClassRepository,
|
||||||
getGroupRepository,
|
getGroupRepository,
|
||||||
|
getStudentRepository,
|
||||||
getSubmissionRepository,
|
getSubmissionRepository,
|
||||||
} from '../data/repositories.js';
|
} from '../data/repositories.js';
|
||||||
|
import { Group } from '../entities/assignments/group.entity.js';
|
||||||
import {
|
import {
|
||||||
GroupDTO,
|
GroupDTO,
|
||||||
mapToGroupDTO,
|
mapToGroupDTO,
|
||||||
|
@ -51,6 +54,48 @@ export async function getGroup(
|
||||||
return mapToGroupDTOId(group);
|
return mapToGroupDTOId(group);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createGroup(
|
||||||
|
groupData: GroupDTO,
|
||||||
|
classid: string,
|
||||||
|
assignmentNumber: number,
|
||||||
|
): Promise<Group | null> {
|
||||||
|
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 {
|
||||||
|
const newGroup = groupRepository.create({
|
||||||
|
assignment: assignment,
|
||||||
|
members: members,
|
||||||
|
});
|
||||||
|
await groupRepository.save(newGroup);
|
||||||
|
|
||||||
|
return newGroup;
|
||||||
|
} catch(e) {
|
||||||
|
console.log(e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export async function getAllGroups(
|
export async function getAllGroups(
|
||||||
classId: string,
|
classId: string,
|
||||||
assignmentNumber: number,
|
assignmentNumber: number,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue