fix: integratie user + errors gefixt zodat het runt + format
This commit is contained in:
parent
6c4ea0eefb
commit
1b096b411b
55 changed files with 858 additions and 594 deletions
|
@ -7,7 +7,7 @@ import learningPathRoutes from './routes/learning-paths.js';
|
||||||
import learningObjectRoutes from './routes/learning-objects.js';
|
import learningObjectRoutes from './routes/learning-objects.js';
|
||||||
|
|
||||||
import studentRoutes from './routes/students.js';
|
import studentRoutes from './routes/students.js';
|
||||||
import teacherRoutes from './routes/teachers.js'
|
import teacherRoutes from './routes/teachers.js';
|
||||||
import groupRoutes from './routes/groups.js';
|
import groupRoutes from './routes/groups.js';
|
||||||
import submissionRoutes from './routes/submissions.js';
|
import submissionRoutes from './routes/submissions.js';
|
||||||
import classRoutes from './routes/classes.js';
|
import classRoutes from './routes/classes.js';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Request, Response } from 'express'
|
import { Request, Response } from 'express';
|
||||||
import { getAllAssignments, getAssignment } from '../services/assignments.js';
|
import { getAllAssignments, getAssignment } from '../services/assignments.js';
|
||||||
|
|
||||||
// typescript is annoy with with parameter forwarding from class.ts
|
// Typescript is annoy with with parameter forwarding from class.ts
|
||||||
interface AssignmentParams {
|
interface AssignmentParams {
|
||||||
classid: string;
|
classid: string;
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -9,7 +9,7 @@ interface AssignmentParams {
|
||||||
|
|
||||||
export async function getAllAssignmentsHandler(
|
export async function getAllAssignmentsHandler(
|
||||||
req: Request<AssignmentParams>,
|
req: Request<AssignmentParams>,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const classid = req.params.classid;
|
const classid = req.params.classid;
|
||||||
const full = req.query.full === 'true';
|
const full = req.query.full === 'true';
|
||||||
|
@ -23,20 +23,20 @@ export async function getAllAssignmentsHandler(
|
||||||
|
|
||||||
export async function getAssignmentHandler(
|
export async function getAssignmentHandler(
|
||||||
req: Request<AssignmentParams>,
|
req: Request<AssignmentParams>,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const id = +req.params.id;
|
const id = +req.params.id;
|
||||||
const classid = req.params.classid;
|
const classid = req.params.classid;
|
||||||
|
|
||||||
if (isNaN(id)) {
|
if (isNaN(id)) {
|
||||||
res.status(400).json({ error: "Assignment id must be a number" });
|
res.status(400).json({ error: 'Assignment id must be a number' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const assignment = await getAssignment(classid, id);
|
const assignment = await getAssignment(classid, id);
|
||||||
|
|
||||||
if (!assignment) {
|
if (!assignment) {
|
||||||
res.status(404).json({ error: "Assignment not found" });
|
res.status(404).json({ error: 'Assignment not found' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,40 +1,44 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { getAllClasses, getClass, getClassStudents, getClassStudentsIds, getClassTeacherInvitations } from '../services/class.js';
|
import {
|
||||||
import { ClassDTO } from '../interfaces/classes.js';
|
getAllClasses,
|
||||||
|
getClass,
|
||||||
|
getClassStudents,
|
||||||
|
getClassStudentsIds,
|
||||||
|
getClassTeacherInvitations,
|
||||||
|
} from '../services/class.js';
|
||||||
|
|
||||||
export async function getAllClassesHandler(
|
export async function getAllClassesHandler(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const full = req.query.full === "true";
|
const full = req.query.full === 'true';
|
||||||
const classes = await getAllClasses(full);
|
const classes = await getAllClasses(full);
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
classes: classes
|
classes: classes,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getClassHandler(
|
export async function getClassHandler(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const classId = req.params.id;
|
const classId = req.params.id;
|
||||||
const cls = await getClass(classId);
|
const cls = await getClass(classId);
|
||||||
|
|
||||||
if (!cls) {
|
if (!cls) {
|
||||||
res.status(404).json({ error: "Student not found" });
|
res.status(404).json({ error: 'Student not found' });
|
||||||
return;
|
return;
|
||||||
} else {
|
|
||||||
cls.endpoints = {
|
|
||||||
self: `${req.baseUrl}/${req.params.id}`,
|
|
||||||
invitations: `${req.baseUrl}/${req.params.id}/invitations`,
|
|
||||||
assignments: `${req.baseUrl}/${req.params.id}/assignments`,
|
|
||||||
students: `${req.baseUrl}/${req.params.id}/students`,
|
|
||||||
}
|
|
||||||
|
|
||||||
res.json(cls);
|
|
||||||
}
|
}
|
||||||
|
cls.endpoints = {
|
||||||
|
self: `${req.baseUrl}/${req.params.id}`,
|
||||||
|
invitations: `${req.baseUrl}/${req.params.id}/invitations`,
|
||||||
|
assignments: `${req.baseUrl}/${req.params.id}/assignments`,
|
||||||
|
students: `${req.baseUrl}/${req.params.id}/students`,
|
||||||
|
};
|
||||||
|
|
||||||
|
res.json(cls);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching learning objects:', error);
|
console.error('Error fetching learning objects:', error);
|
||||||
res.status(500).json({ error: 'Internal server error' });
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
|
@ -43,12 +47,12 @@ export async function getClassHandler(
|
||||||
|
|
||||||
export async function getClassStudentsHandler(
|
export async function getClassStudentsHandler(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const classId = req.params.id;
|
const classId = req.params.id;
|
||||||
const full = req.query.full === "true";
|
const full = req.query.full === 'true';
|
||||||
|
|
||||||
let students = full
|
const students = full
|
||||||
? await getClassStudents(classId)
|
? await getClassStudents(classId)
|
||||||
: await getClassStudentsIds(classId);
|
: await getClassStudentsIds(classId);
|
||||||
|
|
||||||
|
@ -59,10 +63,10 @@ export async function getClassStudentsHandler(
|
||||||
|
|
||||||
export async function getTeacherInvitationsHandler(
|
export async function getTeacherInvitationsHandler(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const classId = req.params.id;
|
const classId = req.params.id;
|
||||||
const full = req.query.full === "true"; // TODO: not implemented yet
|
const full = req.query.full === 'true'; // TODO: not implemented yet
|
||||||
|
|
||||||
const invitations = await getClassTeacherInvitations(classId, full);
|
const invitations = await getClassTeacherInvitations(classId, full);
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { getAllGroups, getGroup } from '../services/groups.js';
|
import { getAllGroups, getGroup } from '../services/groups.js';
|
||||||
|
|
||||||
// typescript is annoywith with parameter forwarding from class.ts
|
// Typescript is annoywith with parameter forwarding from class.ts
|
||||||
interface GroupParams {
|
interface GroupParams {
|
||||||
classid: string;
|
classid: string;
|
||||||
assignmentid: string;
|
assignmentid: string;
|
||||||
|
@ -10,21 +10,21 @@ interface GroupParams {
|
||||||
|
|
||||||
export async function getGroupHandler(
|
export async function getGroupHandler(
|
||||||
req: Request<GroupParams>,
|
req: Request<GroupParams>,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const classId = req.params.classid;
|
const classId = req.params.classid;
|
||||||
const full = req.query.full === "true";
|
const full = req.query.full === 'true';
|
||||||
const assignmentId = +req.params.assignmentid;
|
const assignmentId = +req.params.assignmentid;
|
||||||
|
|
||||||
if (isNaN(assignmentId)) {
|
if (isNaN(assignmentId)) {
|
||||||
res.status(400).json({ error: "Assignment id must be a number" });
|
res.status(400).json({ error: 'Assignment id must be a number' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupId = +req.params.groupid!; // can't be undefined
|
const groupId = +req.params.groupid!; // Can't be undefined
|
||||||
|
|
||||||
if (isNaN(groupId)) {
|
if (isNaN(groupId)) {
|
||||||
res.status(400).json({ error: "Group id must be a number" });
|
res.status(400).json({ error: 'Group id must be a number' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,15 +35,15 @@ export async function getGroupHandler(
|
||||||
|
|
||||||
export async function getAllGroupsHandler(
|
export async function getAllGroupsHandler(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const classId = req.params.classid;
|
const classId = req.params.classid;
|
||||||
const full = req.query.full === "true";
|
const full = req.query.full === 'true';
|
||||||
|
|
||||||
const assignmentId = +req.params.assignmentid;
|
const assignmentId = +req.params.assignmentid;
|
||||||
|
|
||||||
if (isNaN(assignmentId)) {
|
if (isNaN(assignmentId)) {
|
||||||
res.status(400).json({ error: "Assignment id must be a number" });
|
res.status(400).json({ error: 'Assignment id must be a number' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
getLearningObjectsFromPath,
|
getLearningObjectsFromPath,
|
||||||
} from '../services/learning-objects.js';
|
} from '../services/learning-objects.js';
|
||||||
import { FALLBACK_LANG } from '../config.js';
|
import { FALLBACK_LANG } from '../config.js';
|
||||||
import { FilteredLearningObject } from '../interfaces/learning-path';
|
import { FilteredLearningObject } from '../interfaces/learning-path.js';
|
||||||
|
|
||||||
export async function getAllLearningObjects(
|
export async function getAllLearningObjects(
|
||||||
req: Request,
|
req: Request,
|
||||||
|
|
|
@ -2,43 +2,62 @@ import { Request, Response } from 'express';
|
||||||
import {
|
import {
|
||||||
getStudentClasses,
|
getStudentClasses,
|
||||||
getStudentClassIds,
|
getStudentClassIds,
|
||||||
StudentService
|
StudentService,
|
||||||
} from '../services/students.js';
|
} from '../services/students.js';
|
||||||
import { ClassDTO } from '../interfaces/classes.js';
|
import { ClassDTO } from '../interfaces/class.js';
|
||||||
import { getAllAssignments } from '../services/assignments.js';
|
import { getAllAssignments } from '../services/assignments.js';
|
||||||
import {createUserHandler, deleteUserHandler, getAllUsersHandler, getUserHandler} from "./users.js";
|
import {
|
||||||
import { Student } from "../entities/users/student.entity.js";
|
createUserHandler,
|
||||||
|
deleteUserHandler,
|
||||||
|
getAllUsersHandler,
|
||||||
|
getUserHandler,
|
||||||
|
} from './users.js';
|
||||||
|
import { Student } from '../entities/users/student.entity.js';
|
||||||
|
|
||||||
// TODO: accept arguments (full, ...)
|
// TODO: accept arguments (full, ...)
|
||||||
// TODO: endpoints
|
// TODO: endpoints
|
||||||
export async function getAllStudentsHandler (req: Request, res: Response): Promise<void> {
|
export async function getAllStudentsHandler(
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
await getAllUsersHandler<Student>(req, res, new StudentService());
|
await getAllUsersHandler<Student>(req, res, new StudentService());
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getStudentHandler(req: Request, res: Response): Promise<void> {
|
export async function getStudentHandler(
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
await getUserHandler<Student>(req, res, new StudentService());
|
await getUserHandler<Student>(req, res, new StudentService());
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createStudentHandler(req: Request, res: Response): Promise<void> {
|
export async function createStudentHandler(
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
await createUserHandler<Student>(req, res, new StudentService(), Student);
|
await createUserHandler<Student>(req, res, new StudentService(), Student);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteStudentHandler(req: Request, res: Response): Promise<void> {
|
export async function deleteStudentHandler(
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
await deleteUserHandler<Student>(req, res, new StudentService());
|
await deleteUserHandler<Student>(req, res, new StudentService());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getStudentClassesHandler(
|
||||||
export async function getStudentClassesHandler (
|
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const full = req.query.full === 'true';
|
const full = req.query.full === 'true';
|
||||||
const username = req.params.id;
|
const username = req.params.id;
|
||||||
|
|
||||||
let classes: ClassDTO[] | string[];
|
let classes: ClassDTO[] | string[];
|
||||||
if (full) classes = await getStudentClasses(username);
|
if (full) {
|
||||||
else classes = await getStudentClassIds(username);
|
classes = await getStudentClasses(username);
|
||||||
|
} else {
|
||||||
|
classes = await getStudentClassIds(username);
|
||||||
|
}
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
classes: classes,
|
classes: classes,
|
||||||
|
@ -47,7 +66,7 @@ export async function getStudentClassesHandler (
|
||||||
classes: `${req.baseUrl}/${req.params.id}/invitations`,
|
classes: `${req.baseUrl}/${req.params.id}/invitations`,
|
||||||
questions: `${req.baseUrl}/${req.params.id}/assignments`,
|
questions: `${req.baseUrl}/${req.params.id}/assignments`,
|
||||||
students: `${req.baseUrl}/${req.params.id}/students`,
|
students: `${req.baseUrl}/${req.params.id}/students`,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching learning objects:', error);
|
console.error('Error fetching learning objects:', error);
|
||||||
|
@ -57,22 +76,26 @@ export async function getStudentClassesHandler (
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
// Might not be fully correct depending on if
|
// Might not be fully correct depending on if
|
||||||
// a class has an assignment, that all students
|
// A class has an assignment, that all students
|
||||||
// have this assignment.
|
// Have this assignment.
|
||||||
export async function getStudentAssignmentsHandler(
|
export async function getStudentAssignmentsHandler(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const full = req.query.full === 'true';
|
const full = req.query.full === 'true';
|
||||||
const username = req.params.id;
|
const username = req.params.id;
|
||||||
|
|
||||||
const classes = await getStudentClasses(username);
|
const classes = await getStudentClasses(username);
|
||||||
|
|
||||||
const assignments = (await Promise.all(classes.map(async cls => await getAllAssignments(cls.id, full)))).flat();
|
const assignments = (
|
||||||
|
await Promise.all(
|
||||||
|
classes.map(async (cls) => {
|
||||||
|
return await getAllAssignments(cls.id, full);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
).flat();
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
assignments: assignments
|
assignments: assignments,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,92 +1,53 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
|
import { TeacherUserService, TeacherService } from '../services/teachers.js';
|
||||||
|
import { ClassDTO } from '../interfaces/class.js';
|
||||||
|
import { StudentDTO } from '../interfaces/student.js';
|
||||||
|
import { QuestionDTO, QuestionId } from '../interfaces/question.js';
|
||||||
import {
|
import {
|
||||||
createTeacher,
|
createUserHandler,
|
||||||
deleteTeacher,
|
deleteUserHandler,
|
||||||
getTeacherByUsername,
|
getAllUsersHandler,
|
||||||
getClassesByTeacher,
|
getUserHandler,
|
||||||
getClassIdsByTeacher,
|
} from './users.js';
|
||||||
getAllTeachers,
|
import { Teacher } from '../entities/users/teacher.entity.js';
|
||||||
getAllTeachersIds, getStudentsByTeacher, getStudentIdsByTeacher, getQuestionsByTeacher, getQuestionIdsByTeacher
|
|
||||||
} from '../services/teachers.js';
|
|
||||||
import {TeacherDTO} from "../interfaces/teacher";
|
|
||||||
import {ClassDTO} from "../interfaces/class";
|
|
||||||
import {StudentDTO} from "../interfaces/student";
|
|
||||||
import {QuestionDTO, QuestionId} from "../interfaces/question";
|
|
||||||
|
|
||||||
export async function getTeacherHandler(req: Request, res: Response): Promise<void> {
|
export async function getAllTeachersHandler(
|
||||||
try {
|
req: Request,
|
||||||
const full = req.query.full === 'true';
|
res: Response
|
||||||
const username = req.query.username as string;
|
): Promise<void> {
|
||||||
|
await getAllUsersHandler<Teacher>(req, res, new TeacherUserService());
|
||||||
|
}
|
||||||
|
|
||||||
if (username){
|
export async function getTeacherHandler(
|
||||||
const teacher = await getTeacherByUsername(username);
|
req: Request,
|
||||||
if (!teacher){
|
res: Response
|
||||||
res.status(404).json({ error: `Teacher with username '${username}' not found.` });
|
): Promise<void> {
|
||||||
return;
|
await getUserHandler<Teacher>(req, res, new TeacherUserService());
|
||||||
}
|
|
||||||
res.json(teacher);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let teachers: TeacherDTO[] | string[];
|
|
||||||
|
|
||||||
if (full) teachers = await getAllTeachers();
|
|
||||||
else teachers = await getAllTeachersIds();
|
|
||||||
|
|
||||||
res.json(teachers);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("❌ Error fetching teachers:", error);
|
|
||||||
res.status(500).json({ error: "Internal server error" });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createTeacherHandler(
|
export async function createTeacherHandler(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
await createUserHandler<Teacher>(
|
||||||
const teacherData = req.body as TeacherDTO;
|
req,
|
||||||
|
res,
|
||||||
if (!teacherData.username || !teacherData.firstName || !teacherData.lastName) {
|
new TeacherUserService(),
|
||||||
res.status(400).json({ error: 'Missing required fields: username, firstName, lastName' });
|
Teacher
|
||||||
return;
|
);
|
||||||
}
|
|
||||||
|
|
||||||
const newTeacher = await createTeacher(teacherData);
|
|
||||||
res.status(201).json(newTeacher);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error creating teacher:', error);
|
|
||||||
res.status(500).json({ error: 'Internal server error' });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteTeacherHandler(
|
export async function deleteTeacherHandler(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response
|
res: Response
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
await deleteUserHandler<Teacher>(req, res, new TeacherUserService());
|
||||||
const username = req.params.username as string;
|
|
||||||
|
|
||||||
if (!username) {
|
|
||||||
res.status(400).json({ error: 'Missing required field: username' });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const deletedTeacher = await deleteTeacher(username);
|
|
||||||
|
|
||||||
if (!deletedTeacher) {
|
|
||||||
res.status(400).json({ error: `Did not find teacher with username ${username}` });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
res.status(201).json(deletedTeacher);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error deleting teacher:', error);
|
|
||||||
res.status(500).json({ error: 'Internal server error' });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTeacherClassHandler(req: Request, res: Response): Promise<void> {
|
export async function getTeacherClassHandler(
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const username = req.params.username as string;
|
const username = req.params.username as string;
|
||||||
const full = req.query.full === 'true';
|
const full = req.query.full === 'true';
|
||||||
|
@ -96,10 +57,11 @@ export async function getTeacherClassHandler(req: Request, res: Response): Promi
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let classes: ClassDTO[] | string[];
|
const teacherService = new TeacherService();
|
||||||
|
|
||||||
if (full) classes = await getClassesByTeacher(username);
|
const classes: ClassDTO[] | string[] = full
|
||||||
else classes = await getClassIdsByTeacher(username);
|
? await teacherService.getClassesByTeacher(username)
|
||||||
|
: await teacherService.getClassIdsByTeacher(username);
|
||||||
|
|
||||||
res.status(201).json(classes);
|
res.status(201).json(classes);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -108,7 +70,10 @@ export async function getTeacherClassHandler(req: Request, res: Response): Promi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTeacherStudentHandler(req: Request, res: Response): Promise<void> {
|
export async function getTeacherStudentHandler(
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const username = req.params.username as string;
|
const username = req.params.username as string;
|
||||||
const full = req.query.full === 'true';
|
const full = req.query.full === 'true';
|
||||||
|
@ -118,10 +83,11 @@ export async function getTeacherStudentHandler(req: Request, res: Response): Pro
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let students: StudentDTO[] | string[];
|
const teacherService = new TeacherService();
|
||||||
|
|
||||||
if (full) students = await getStudentsByTeacher(username);
|
const students: StudentDTO[] | string[] = full
|
||||||
else students = await getStudentIdsByTeacher(username);
|
? await teacherService.getStudentsByTeacher(username)
|
||||||
|
: await teacherService.getStudentIdsByTeacher(username);
|
||||||
|
|
||||||
res.status(201).json(students);
|
res.status(201).json(students);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -130,7 +96,10 @@ export async function getTeacherStudentHandler(req: Request, res: Response): Pro
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getTeacherQuestionHandler(req: Request, res: Response): Promise<void> {
|
export async function getTeacherQuestionHandler(
|
||||||
|
req: Request,
|
||||||
|
res: Response
|
||||||
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const username = req.params.username as string;
|
const username = req.params.username as string;
|
||||||
const full = req.query.full === 'true';
|
const full = req.query.full === 'true';
|
||||||
|
@ -140,10 +109,11 @@ export async function getTeacherQuestionHandler(req: Request, res: Response): Pr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let questions: QuestionDTO[] | QuestionId[];
|
const teacherService = new TeacherService();
|
||||||
|
|
||||||
if (full) questions = await getQuestionsByTeacher(username);
|
const questions: QuestionDTO[] | QuestionId[] = full
|
||||||
else questions = await getQuestionIdsByTeacher(username);
|
? await teacherService.getQuestionsByTeacher(username)
|
||||||
|
: await teacherService.getQuestionIdsByTeacher(username);
|
||||||
|
|
||||||
res.status(201).json(questions);
|
res.status(201).json(questions);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -151,5 +121,3 @@ export async function getTeacherQuestionHandler(req: Request, res: Response): Pr
|
||||||
res.status(500).json({ error: 'Internal server error' });
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { themes } from '../data/themes.js';
|
import { themes } from '../data/themes.js';
|
||||||
import { loadTranslations } from "../util/translation-helper.js";
|
import { loadTranslations } from '../util/translation-helper.js';
|
||||||
import { FALLBACK_LANG } from '../config.js';
|
|
||||||
|
|
||||||
interface Translations {
|
interface Translations {
|
||||||
curricula_page: {
|
curricula_page: {
|
||||||
|
|
|
@ -1,30 +1,29 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { UserService } from "../services/users.js";
|
import { UserService } from '../services/users.js';
|
||||||
import {UserDTO} from "../interfaces/user.js";
|
import { UserDTO } from '../interfaces/user.js';
|
||||||
import {User} from "../entities/users/user.entity.js";
|
import { User } from '../entities/users/user.entity.js';
|
||||||
|
|
||||||
export async function getAllUsersHandler<T extends User>(
|
export async function getAllUsersHandler<T extends User>(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
service: UserService<T>
|
service: UserService<T>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const full = req.query.full === 'true';
|
const full = req.query.full === 'true';
|
||||||
|
|
||||||
let users: UserDTO[] | string[] = full
|
const users: UserDTO[] | string[] = full
|
||||||
? await service.getAllUsers()
|
? await service.getAllUsers()
|
||||||
: await service.getAllUserIds();
|
: await service.getAllUserIds();
|
||||||
|
|
||||||
if (!users){
|
if (!users) {
|
||||||
res.status(404).json({ error: `Users not found.` });
|
res.status(404).json({ error: `Users not found.` });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(201).json(users);
|
res.status(201).json(users);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Error fetching users:", error);
|
console.error('❌ Error fetching users:', error);
|
||||||
res.status(500).json({ error: "Internal server error" });
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,7 +31,7 @@ export async function getUserHandler<T extends User>(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
service: UserService<T>
|
service: UserService<T>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
try {
|
try {
|
||||||
const username = req.params.username as string;
|
const username = req.params.username as string;
|
||||||
|
|
||||||
|
@ -43,16 +42,17 @@ export async function getUserHandler<T extends User>(
|
||||||
|
|
||||||
const user = await service.getUserByUsername(username);
|
const user = await service.getUserByUsername(username);
|
||||||
|
|
||||||
if (!user){
|
if (!user) {
|
||||||
res.status(404).json({ error: `User with username '${username}' not found.` });
|
res.status(404).json({
|
||||||
|
error: `User with username '${username}' not found.`,
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(201).json(user);
|
res.status(201).json(user);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Error fetching users:", error);
|
console.error('❌ Error fetching users:', error);
|
||||||
res.status(500).json({ error: "Internal server error" });
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,23 +63,25 @@ export async function createUserHandler<T extends User>(
|
||||||
UserClass: new () => T
|
UserClass: new () => T
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
console.log("req", req)
|
console.log('req', req);
|
||||||
const userData = req.body as UserDTO;
|
const userData = req.body as UserDTO;
|
||||||
|
|
||||||
if (!userData.username || !userData.firstName || !userData.lastName) {
|
if (!userData.username || !userData.firstName || !userData.lastName) {
|
||||||
res.status(400).json({ error: "Missing required fields: username, firstName, lastName" });
|
res.status(400).json({
|
||||||
|
error: 'Missing required fields: username, firstName, lastName',
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newUser = await service.createUser(userData, UserClass);
|
const newUser = await service.createUser(userData, UserClass);
|
||||||
res.status(201).json(newUser);
|
res.status(201).json(newUser);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Error creating user:", error);
|
console.error('❌ Error creating user:', error);
|
||||||
res.status(500).json({ error: "Internal server error" });
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteUserHandler<T extends User> (
|
export async function deleteUserHandler<T extends User>(
|
||||||
req: Request,
|
req: Request,
|
||||||
res: Response,
|
res: Response,
|
||||||
service: UserService<T>
|
service: UserService<T>
|
||||||
|
@ -88,19 +90,21 @@ export async function deleteUserHandler<T extends User> (
|
||||||
const username = req.params.username;
|
const username = req.params.username;
|
||||||
|
|
||||||
if (!username) {
|
if (!username) {
|
||||||
res.status(400).json({ error: "Missing required field: username" });
|
res.status(400).json({ error: 'Missing required field: username' });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const deletedUser = await service.deleteUser(username);
|
const deletedUser = await service.deleteUser(username);
|
||||||
if (!deletedUser) {
|
if (!deletedUser) {
|
||||||
res.status(404).json({ error: `User with username '${username}' not found.` });
|
res.status(404).json({
|
||||||
|
error: `User with username '${username}' not found.`,
|
||||||
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
res.status(200).json(deletedUser);
|
res.status(200).json(deletedUser);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("❌ Error deleting user:", error);
|
console.error('❌ Error deleting user:', error);
|
||||||
res.status(500).json({ error: "Internal server error" });
|
res.status(500).json({ error: 'Internal server error' });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,21 +8,20 @@ export class GroupRepository extends DwengoEntityRepository<Group> {
|
||||||
groupNumber: number
|
groupNumber: number
|
||||||
): Promise<Group | null> {
|
): Promise<Group | null> {
|
||||||
return this.findOne(
|
return this.findOne(
|
||||||
{
|
{
|
||||||
assignment: assignment,
|
assignment: assignment,
|
||||||
groupNumber: groupNumber,
|
groupNumber: groupNumber,
|
||||||
},
|
},
|
||||||
{ populate: ["members"] },
|
{ populate: ['members'] }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public findAllGroupsForAssignment(
|
public findAllGroupsForAssignment(
|
||||||
assignment: Assignment
|
assignment: Assignment
|
||||||
): Promise<Group[]> {
|
): Promise<Group[]> {
|
||||||
return this.findAll({
|
return this.findAll({
|
||||||
where: { assignment: assignment },
|
where: { assignment: assignment },
|
||||||
populate: ["members"]
|
populate: ['members'],
|
||||||
},
|
});
|
||||||
);
|
|
||||||
}
|
}
|
||||||
public deleteByAssignmentAndGroupNumber(
|
public deleteByAssignmentAndGroupNumber(
|
||||||
assignment: Assignment,
|
assignment: Assignment,
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
|
import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
|
||||||
import { Class } from '../../entities/classes/class.entity.js';
|
import { Class } from '../../entities/classes/class.entity.js';
|
||||||
import { Student } from '../../entities/users/student.entity.js';
|
import { Student } from '../../entities/users/student.entity.js';
|
||||||
import {Teacher} from "../../entities/users/teacher.entity";
|
import { Teacher } from '../../entities/users/teacher.entity';
|
||||||
|
|
||||||
export class ClassRepository extends DwengoEntityRepository<Class> {
|
export class ClassRepository extends DwengoEntityRepository<Class> {
|
||||||
public findById(id: string): Promise<Class | null> {
|
public findById(id: string): Promise<Class | null> {
|
||||||
return this.findOne(
|
return this.findOne(
|
||||||
{ classId: id },
|
{ classId: id },
|
||||||
{ populate: ["students", "teachers"] },
|
{ populate: ['students', 'teachers'] }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
public deleteById(id: string): Promise<void> {
|
public deleteById(id: string): Promise<void> {
|
||||||
|
@ -16,14 +16,14 @@ export class ClassRepository extends DwengoEntityRepository<Class> {
|
||||||
public findByStudent(student: Student): Promise<Class[]> {
|
public findByStudent(student: Student): Promise<Class[]> {
|
||||||
return this.find(
|
return this.find(
|
||||||
{ students: student },
|
{ students: student },
|
||||||
{ populate: ["students", "teachers"] } // voegt student en teacher objecten toe
|
{ populate: ['students', 'teachers'] } // Voegt student en teacher objecten toe
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public findByTeacher(teacher: Teacher): Promise<Class[]> {
|
public findByTeacher(teacher: Teacher): Promise<Class[]> {
|
||||||
return this.find(
|
return this.find(
|
||||||
{ teachers: teacher },
|
{ teachers: teacher },
|
||||||
{ populate: ["students", "teachers"] }
|
{ populate: ['students', 'teachers'] }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
|
import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
|
||||||
import { LearningObject } from '../../entities/content/learning-object.entity.js';
|
import { LearningObject } from '../../entities/content/learning-object.entity.js';
|
||||||
import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js';
|
import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js';
|
||||||
import {Teacher} from "../../entities/users/teacher.entity";
|
import { Teacher } from '../../entities/users/teacher.entity';
|
||||||
|
|
||||||
export class LearningObjectRepository extends DwengoEntityRepository<LearningObject> {
|
export class LearningObjectRepository extends DwengoEntityRepository<LearningObject> {
|
||||||
public findByIdentifier(
|
public findByIdentifier(
|
||||||
|
|
|
@ -4,13 +4,13 @@ export abstract class DwengoEntityRepository<
|
||||||
T extends object,
|
T extends object,
|
||||||
> extends EntityRepository<T> {
|
> extends EntityRepository<T> {
|
||||||
public async save(entity: T) {
|
public async save(entity: T) {
|
||||||
let em = this.getEntityManager();
|
const em = this.getEntityManager();
|
||||||
em.persist(entity);
|
em.persist(entity);
|
||||||
await em.flush();
|
await em.flush();
|
||||||
}
|
}
|
||||||
public async deleteWhere(query: FilterQuery<T>) {
|
public async deleteWhere(query: FilterQuery<T>) {
|
||||||
let toDelete = await this.findOne(query);
|
const toDelete = await this.findOne(query);
|
||||||
let em = this.getEntityManager();
|
const em = this.getEntityManager();
|
||||||
if (toDelete) {
|
if (toDelete) {
|
||||||
em.remove(toDelete);
|
em.remove(toDelete);
|
||||||
await em.flush();
|
await em.flush();
|
||||||
|
|
|
@ -9,7 +9,7 @@ export class AnswerRepository extends DwengoEntityRepository<Answer> {
|
||||||
author: Teacher;
|
author: Teacher;
|
||||||
content: string;
|
content: string;
|
||||||
}): Promise<Answer> {
|
}): Promise<Answer> {
|
||||||
let answerEntity = new Answer();
|
const answerEntity = new Answer();
|
||||||
answerEntity.toQuestion = answer.toQuestion;
|
answerEntity.toQuestion = answer.toQuestion;
|
||||||
answerEntity.author = answer.author;
|
answerEntity.author = answer.author;
|
||||||
answerEntity.content = answer.content;
|
answerEntity.content = answer.content;
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
|
||||||
import { Question } from '../../entities/questions/question.entity.js';
|
import { Question } from '../../entities/questions/question.entity.js';
|
||||||
import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js';
|
import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js';
|
||||||
import { Student } from '../../entities/users/student.entity.js';
|
import { Student } from '../../entities/users/student.entity.js';
|
||||||
import {LearningObject} from "../../entities/content/learning-object.entity";
|
import { LearningObject } from '../../entities/content/learning-object.entity';
|
||||||
|
|
||||||
export class QuestionRepository extends DwengoEntityRepository<Question> {
|
export class QuestionRepository extends DwengoEntityRepository<Question> {
|
||||||
public createQuestion(question: {
|
public createQuestion(question: {
|
||||||
|
@ -10,7 +10,7 @@ export class QuestionRepository extends DwengoEntityRepository<Question> {
|
||||||
author: Student;
|
author: Student;
|
||||||
content: string;
|
content: string;
|
||||||
}): Promise<Question> {
|
}): Promise<Question> {
|
||||||
let questionEntity = new Question();
|
const questionEntity = new Question();
|
||||||
questionEntity.learningObjectHruid = question.loId.hruid;
|
questionEntity.learningObjectHruid = question.loId.hruid;
|
||||||
questionEntity.learningObjectLanguage = question.loId.language;
|
questionEntity.learningObjectLanguage = question.loId.language;
|
||||||
questionEntity.learningObjectVersion = question.loId.version;
|
questionEntity.learningObjectVersion = question.loId.version;
|
||||||
|
@ -44,12 +44,16 @@ export class QuestionRepository extends DwengoEntityRepository<Question> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async findAllByLearningObjects(learningObjects: LearningObject[]): Promise<Question[]> {
|
public async findAllByLearningObjects(
|
||||||
const objectIdentifiers = learningObjects.map(lo => ({
|
learningObjects: LearningObject[]
|
||||||
|
): Promise<Question[]> {
|
||||||
|
const objectIdentifiers = learningObjects.map((lo) => {
|
||||||
|
return {
|
||||||
learningObjectHruid: lo.hruid,
|
learningObjectHruid: lo.hruid,
|
||||||
learningObjectLanguage: lo.language,
|
learningObjectLanguage: lo.language,
|
||||||
learningObjectVersion: lo.version
|
learningObjectVersion: lo.version,
|
||||||
}));
|
};
|
||||||
|
});
|
||||||
|
|
||||||
return this.findAll({
|
return this.findAll({
|
||||||
where: { $or: objectIdentifiers },
|
where: { $or: objectIdentifiers },
|
||||||
|
|
|
@ -59,7 +59,9 @@ function repositoryGetter<T extends AnyEntity, R extends EntityRepository<T>>(
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Users */
|
/* Users */
|
||||||
export const getUserRepository = repositoryGetter<User, UserRepository<User>>(User);
|
export const getUserRepository = repositoryGetter<User, UserRepository<User>>(
|
||||||
|
User
|
||||||
|
);
|
||||||
export const getStudentRepository = repositoryGetter<
|
export const getStudentRepository = repositoryGetter<
|
||||||
Student,
|
Student,
|
||||||
StudentRepository
|
StudentRepository
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Student } from '../../entities/users/student.entity.js';
|
import { Student } from '../../entities/users/student.entity.js';
|
||||||
import {UserRepository} from "./user-repository.js";
|
import { UserRepository } from './user-repository.js';
|
||||||
|
|
||||||
export class StudentRepository extends UserRepository<Student> {}
|
export class StudentRepository extends UserRepository<Student> {}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Teacher } from '../../entities/users/teacher.entity.js';
|
import { Teacher } from '../../entities/users/teacher.entity.js';
|
||||||
import {UserRepository} from "./user-repository.js";
|
import { UserRepository } from './user-repository.js';
|
||||||
|
|
||||||
export class TeacherRepository extends UserRepository<Teacher> {}
|
export class TeacherRepository extends UserRepository<Teacher> {}
|
||||||
|
|
|
@ -11,9 +11,18 @@ import { Group } from './group.entity.js';
|
||||||
import { Language } from '../content/language.js';
|
import { Language } from '../content/language.js';
|
||||||
import { AssignmentRepository } from '../../data/assignments/assignment-repository.js';
|
import { AssignmentRepository } from '../../data/assignments/assignment-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => AssignmentRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return AssignmentRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class Assignment {
|
export class Assignment {
|
||||||
@ManyToOne({ entity: () => Class, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Class;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
within!: Class;
|
within!: Class;
|
||||||
|
|
||||||
@PrimaryKey({ type: 'number' })
|
@PrimaryKey({ type: 'number' })
|
||||||
|
@ -28,9 +37,18 @@ export class Assignment {
|
||||||
@Property({ type: 'string' })
|
@Property({ type: 'string' })
|
||||||
learningPathHruid!: string;
|
learningPathHruid!: string;
|
||||||
|
|
||||||
@Enum({ items: () => Language })
|
@Enum({
|
||||||
|
items: () => {
|
||||||
|
return Language;
|
||||||
|
},
|
||||||
|
})
|
||||||
learningPathLanguage!: Language;
|
learningPathLanguage!: Language;
|
||||||
|
|
||||||
@OneToMany({ entity: () => Group, mappedBy: 'assignment' })
|
@OneToMany({
|
||||||
|
entity: () => {
|
||||||
|
return Group;
|
||||||
|
},
|
||||||
|
mappedBy: 'assignment',
|
||||||
|
})
|
||||||
groups!: Group[];
|
groups!: Group[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,27 @@ 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';
|
||||||
|
|
||||||
@Entity({ repository: () => GroupRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return GroupRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class Group {
|
export class Group {
|
||||||
@ManyToOne({ entity: () => Assignment, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Assignment;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
assignment!: Assignment;
|
assignment!: Assignment;
|
||||||
|
|
||||||
@PrimaryKey({ type: 'integer' })
|
@PrimaryKey({ type: 'integer' })
|
||||||
groupNumber!: number;
|
groupNumber!: number;
|
||||||
|
|
||||||
@ManyToMany({ entity: () => Student })
|
@ManyToMany({
|
||||||
|
entity: () => {
|
||||||
|
return Student;
|
||||||
|
},
|
||||||
|
})
|
||||||
members!: Student[];
|
members!: Student[];
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,21 @@ import { Entity, Enum, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
|
||||||
import { Language } from '../content/language.js';
|
import { Language } from '../content/language.js';
|
||||||
import { SubmissionRepository } from '../../data/assignments/submission-repository.js';
|
import { SubmissionRepository } from '../../data/assignments/submission-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => SubmissionRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return SubmissionRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class Submission {
|
export class Submission {
|
||||||
@PrimaryKey({ type: 'string' })
|
@PrimaryKey({ type: 'string' })
|
||||||
learningObjectHruid!: string;
|
learningObjectHruid!: string;
|
||||||
|
|
||||||
@Enum({ items: () => Language, primary: true })
|
@Enum({
|
||||||
|
items: () => {
|
||||||
|
return Language;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
learningObjectLanguage!: Language;
|
learningObjectLanguage!: Language;
|
||||||
|
|
||||||
@PrimaryKey({ type: 'string' })
|
@PrimaryKey({ type: 'string' })
|
||||||
|
@ -18,13 +27,22 @@ export class Submission {
|
||||||
@PrimaryKey({ type: 'integer' })
|
@PrimaryKey({ type: 'integer' })
|
||||||
submissionNumber!: number;
|
submissionNumber!: number;
|
||||||
|
|
||||||
@ManyToOne({ entity: () => Student })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Student;
|
||||||
|
},
|
||||||
|
})
|
||||||
submitter!: Student;
|
submitter!: Student;
|
||||||
|
|
||||||
@Property({ type: 'datetime' })
|
@Property({ type: 'datetime' })
|
||||||
submissionTime!: Date;
|
submissionTime!: Date;
|
||||||
|
|
||||||
@ManyToOne({ entity: () => Group, nullable: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Group;
|
||||||
|
},
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
onBehalfOf?: Group;
|
onBehalfOf?: Group;
|
||||||
|
|
||||||
@Property({ type: 'json' })
|
@Property({ type: 'json' })
|
||||||
|
|
|
@ -3,15 +3,31 @@ import { Student } from '../users/student.entity.js';
|
||||||
import { Class } from './class.entity.js';
|
import { Class } from './class.entity.js';
|
||||||
import { ClassJoinRequestRepository } from '../../data/classes/class-join-request-repository.js';
|
import { ClassJoinRequestRepository } from '../../data/classes/class-join-request-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => ClassJoinRequestRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return ClassJoinRequestRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class ClassJoinRequest {
|
export class ClassJoinRequest {
|
||||||
@ManyToOne({ entity: () => Student, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Student;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
requester!: Student;
|
requester!: Student;
|
||||||
|
|
||||||
@ManyToOne({ entity: () => Class, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Class;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
class!: Class;
|
class!: Class;
|
||||||
|
|
||||||
@Enum(() => ClassJoinRequestStatus)
|
@Enum(() => {
|
||||||
|
return ClassJoinRequestStatus;
|
||||||
|
})
|
||||||
status!: ClassJoinRequestStatus;
|
status!: ClassJoinRequestStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,11 @@ import { Teacher } from '../users/teacher.entity.js';
|
||||||
import { Student } from '../users/student.entity.js';
|
import { Student } from '../users/student.entity.js';
|
||||||
import { ClassRepository } from '../../data/classes/class-repository.js';
|
import { ClassRepository } from '../../data/classes/class-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => ClassRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return ClassRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class Class {
|
export class Class {
|
||||||
@PrimaryKey()
|
@PrimaryKey()
|
||||||
classId = v4();
|
classId = v4();
|
||||||
|
@ -18,9 +22,13 @@ export class Class {
|
||||||
@Property({ type: 'string' })
|
@Property({ type: 'string' })
|
||||||
displayName!: string;
|
displayName!: string;
|
||||||
|
|
||||||
@ManyToMany(() => Teacher)
|
@ManyToMany(() => {
|
||||||
|
return Teacher;
|
||||||
|
})
|
||||||
teachers!: Collection<Teacher>;
|
teachers!: Collection<Teacher>;
|
||||||
|
|
||||||
@ManyToMany(() => Student)
|
@ManyToMany(() => {
|
||||||
|
return Student;
|
||||||
|
})
|
||||||
students!: Collection<Student>;
|
students!: Collection<Student>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,14 +6,33 @@ import { TeacherInvitationRepository } from '../../data/classes/teacher-invitati
|
||||||
/**
|
/**
|
||||||
* Invitation of a teacher into a class (in order to teach it).
|
* Invitation of a teacher into a class (in order to teach it).
|
||||||
*/
|
*/
|
||||||
@Entity({ repository: () => TeacherInvitationRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return TeacherInvitationRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class TeacherInvitation {
|
export class TeacherInvitation {
|
||||||
@ManyToOne({ entity: () => Teacher, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Teacher;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
sender!: Teacher;
|
sender!: Teacher;
|
||||||
|
|
||||||
@ManyToOne({ entity: () => Teacher, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Teacher;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
receiver!: Teacher;
|
receiver!: Teacher;
|
||||||
|
|
||||||
@ManyToOne({ entity: () => Class, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Class;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
class!: Class;
|
class!: Class;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,18 @@ import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
|
||||||
import { LearningObject } from './learning-object.entity.js';
|
import { LearningObject } from './learning-object.entity.js';
|
||||||
import { AttachmentRepository } from '../../data/content/attachment-repository.js';
|
import { AttachmentRepository } from '../../data/content/attachment-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => AttachmentRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return AttachmentRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class Attachment {
|
export class Attachment {
|
||||||
@ManyToOne({ entity: () => LearningObject, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return LearningObject;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
learningObject!: LearningObject;
|
learningObject!: LearningObject;
|
||||||
|
|
||||||
@PrimaryKey({ type: 'integer' })
|
@PrimaryKey({ type: 'integer' })
|
||||||
|
|
|
@ -22,18 +22,31 @@ export class ReturnValue {
|
||||||
callbackSchema!: string;
|
callbackSchema!: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Entity({ repository: () => LearningObjectRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return LearningObjectRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class LearningObject {
|
export class LearningObject {
|
||||||
@PrimaryKey({ type: 'string' })
|
@PrimaryKey({ type: 'string' })
|
||||||
hruid!: string;
|
hruid!: string;
|
||||||
|
|
||||||
@Enum({ items: () => Language, primary: true })
|
@Enum({
|
||||||
|
items: () => {
|
||||||
|
return Language;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
language!: Language;
|
language!: Language;
|
||||||
|
|
||||||
@PrimaryKey({ type: 'string' })
|
@PrimaryKey({ type: 'string' })
|
||||||
version: string = '1';
|
version: string = '1';
|
||||||
|
|
||||||
@ManyToMany({ entity: () => Teacher })
|
@ManyToMany({
|
||||||
|
entity: () => {
|
||||||
|
return Teacher;
|
||||||
|
},
|
||||||
|
})
|
||||||
admins!: Teacher[];
|
admins!: Teacher[];
|
||||||
|
|
||||||
@Property({ type: 'string' })
|
@Property({ type: 'string' })
|
||||||
|
@ -57,7 +70,12 @@ export class LearningObject {
|
||||||
@Property({ type: 'array' })
|
@Property({ type: 'array' })
|
||||||
skosConcepts!: string[];
|
skosConcepts!: string[];
|
||||||
|
|
||||||
@Embedded({ entity: () => EducationalGoal, array: true })
|
@Embedded({
|
||||||
|
entity: () => {
|
||||||
|
return EducationalGoal;
|
||||||
|
},
|
||||||
|
array: true,
|
||||||
|
})
|
||||||
educationalGoals: EducationalGoal[] = [];
|
educationalGoals: EducationalGoal[] = [];
|
||||||
|
|
||||||
@Property({ type: 'string' })
|
@Property({ type: 'string' })
|
||||||
|
@ -72,7 +90,11 @@ export class LearningObject {
|
||||||
@Property({ type: 'integer' })
|
@Property({ type: 'integer' })
|
||||||
estimatedTime!: number;
|
estimatedTime!: number;
|
||||||
|
|
||||||
@Embedded({ entity: () => ReturnValue })
|
@Embedded({
|
||||||
|
entity: () => {
|
||||||
|
return ReturnValue;
|
||||||
|
},
|
||||||
|
})
|
||||||
returnValue!: ReturnValue;
|
returnValue!: ReturnValue;
|
||||||
|
|
||||||
@Property({ type: 'bool' })
|
@Property({ type: 'bool' })
|
||||||
|
@ -81,7 +103,12 @@ export class LearningObject {
|
||||||
@Property({ type: 'string', nullable: true })
|
@Property({ type: 'string', nullable: true })
|
||||||
contentLocation?: string;
|
contentLocation?: string;
|
||||||
|
|
||||||
@OneToMany({ entity: () => Attachment, mappedBy: 'learningObject' })
|
@OneToMany({
|
||||||
|
entity: () => {
|
||||||
|
return Attachment;
|
||||||
|
},
|
||||||
|
mappedBy: 'learningObject',
|
||||||
|
})
|
||||||
attachments: Attachment[] = [];
|
attachments: Attachment[] = [];
|
||||||
|
|
||||||
@Property({ type: 'blob' })
|
@Property({ type: 'blob' })
|
||||||
|
|
|
@ -12,15 +12,28 @@ import { Language } from './language.js';
|
||||||
import { Teacher } from '../users/teacher.entity.js';
|
import { Teacher } from '../users/teacher.entity.js';
|
||||||
import { LearningPathRepository } from '../../data/content/learning-path-repository.js';
|
import { LearningPathRepository } from '../../data/content/learning-path-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => LearningPathRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return LearningPathRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class LearningPath {
|
export class LearningPath {
|
||||||
@PrimaryKey({ type: 'string' })
|
@PrimaryKey({ type: 'string' })
|
||||||
hruid!: string;
|
hruid!: string;
|
||||||
|
|
||||||
@Enum({ items: () => Language, primary: true })
|
@Enum({
|
||||||
|
items: () => {
|
||||||
|
return Language;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
language!: Language;
|
language!: Language;
|
||||||
|
|
||||||
@ManyToMany({ entity: () => Teacher })
|
@ManyToMany({
|
||||||
|
entity: () => {
|
||||||
|
return Teacher;
|
||||||
|
},
|
||||||
|
})
|
||||||
admins!: Teacher[];
|
admins!: Teacher[];
|
||||||
|
|
||||||
@Property({ type: 'string' })
|
@Property({ type: 'string' })
|
||||||
|
@ -32,7 +45,12 @@ export class LearningPath {
|
||||||
@Property({ type: 'blob' })
|
@Property({ type: 'blob' })
|
||||||
image!: string;
|
image!: string;
|
||||||
|
|
||||||
@Embedded({ entity: () => LearningPathNode, array: true })
|
@Embedded({
|
||||||
|
entity: () => {
|
||||||
|
return LearningPathNode;
|
||||||
|
},
|
||||||
|
array: true,
|
||||||
|
})
|
||||||
nodes: LearningPathNode[] = [];
|
nodes: LearningPathNode[] = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +59,11 @@ export class LearningPathNode {
|
||||||
@Property({ type: 'string' })
|
@Property({ type: 'string' })
|
||||||
learningObjectHruid!: string;
|
learningObjectHruid!: string;
|
||||||
|
|
||||||
@Enum({ items: () => Language })
|
@Enum({
|
||||||
|
items: () => {
|
||||||
|
return Language;
|
||||||
|
},
|
||||||
|
})
|
||||||
language!: Language;
|
language!: Language;
|
||||||
|
|
||||||
@Property({ type: 'string' })
|
@Property({ type: 'string' })
|
||||||
|
@ -53,7 +75,12 @@ export class LearningPathNode {
|
||||||
@Property({ type: 'bool' })
|
@Property({ type: 'bool' })
|
||||||
startNode!: boolean;
|
startNode!: boolean;
|
||||||
|
|
||||||
@Embedded({ entity: () => LearningPathTransition, array: true })
|
@Embedded({
|
||||||
|
entity: () => {
|
||||||
|
return LearningPathTransition;
|
||||||
|
},
|
||||||
|
array: true,
|
||||||
|
})
|
||||||
transitions!: LearningPathTransition[];
|
transitions!: LearningPathTransition[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,6 +89,10 @@ export class LearningPathTransition {
|
||||||
@Property({ type: 'string' })
|
@Property({ type: 'string' })
|
||||||
condition!: string;
|
condition!: string;
|
||||||
|
|
||||||
@OneToOne({ entity: () => LearningPathNode })
|
@OneToOne({
|
||||||
|
entity: () => {
|
||||||
|
return LearningPathNode;
|
||||||
|
},
|
||||||
|
})
|
||||||
next!: LearningPathNode;
|
next!: LearningPathNode;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,12 +3,26 @@ import { Question } from './question.entity.js';
|
||||||
import { Teacher } from '../users/teacher.entity.js';
|
import { Teacher } from '../users/teacher.entity.js';
|
||||||
import { AnswerRepository } from '../../data/questions/answer-repository.js';
|
import { AnswerRepository } from '../../data/questions/answer-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => AnswerRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return AnswerRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class Answer {
|
export class Answer {
|
||||||
@ManyToOne({ entity: () => Teacher, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Teacher;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
author!: Teacher;
|
author!: Teacher;
|
||||||
|
|
||||||
@ManyToOne({ entity: () => Question, primary: true })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Question;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
toQuestion!: Question;
|
toQuestion!: Question;
|
||||||
|
|
||||||
@PrimaryKey({ type: 'integer' })
|
@PrimaryKey({ type: 'integer' })
|
||||||
|
|
|
@ -3,12 +3,21 @@ import { Language } from '../content/language.js';
|
||||||
import { Student } from '../users/student.entity.js';
|
import { Student } from '../users/student.entity.js';
|
||||||
import { QuestionRepository } from '../../data/questions/question-repository.js';
|
import { QuestionRepository } from '../../data/questions/question-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => QuestionRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return QuestionRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class Question {
|
export class Question {
|
||||||
@PrimaryKey({ type: 'string' })
|
@PrimaryKey({ type: 'string' })
|
||||||
learningObjectHruid!: string;
|
learningObjectHruid!: string;
|
||||||
|
|
||||||
@Enum({ items: () => Language, primary: true })
|
@Enum({
|
||||||
|
items: () => {
|
||||||
|
return Language;
|
||||||
|
},
|
||||||
|
primary: true,
|
||||||
|
})
|
||||||
learningObjectLanguage!: Language;
|
learningObjectLanguage!: Language;
|
||||||
|
|
||||||
@PrimaryKey({ type: 'string' })
|
@PrimaryKey({ type: 'string' })
|
||||||
|
@ -17,7 +26,11 @@ export class Question {
|
||||||
@PrimaryKey({ type: 'integer' })
|
@PrimaryKey({ type: 'integer' })
|
||||||
sequenceNumber!: number;
|
sequenceNumber!: number;
|
||||||
|
|
||||||
@ManyToOne({ entity: () => Student })
|
@ManyToOne({
|
||||||
|
entity: () => {
|
||||||
|
return Student;
|
||||||
|
},
|
||||||
|
})
|
||||||
author!: Student;
|
author!: Student;
|
||||||
|
|
||||||
@Property({ type: 'datetime' })
|
@Property({ type: 'datetime' })
|
||||||
|
|
|
@ -4,11 +4,19 @@ import { Class } from '../classes/class.entity.js';
|
||||||
import { Group } from '../assignments/group.entity.js';
|
import { Group } from '../assignments/group.entity.js';
|
||||||
import { StudentRepository } from '../../data/users/student-repository.js';
|
import { StudentRepository } from '../../data/users/student-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => StudentRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return StudentRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class Student extends User {
|
export class Student extends User {
|
||||||
@ManyToMany(() => Class)
|
@ManyToMany(() => {
|
||||||
|
return Class;
|
||||||
|
})
|
||||||
classes!: Collection<Class>;
|
classes!: Collection<Class>;
|
||||||
|
|
||||||
@ManyToMany(() => Group)
|
@ManyToMany(() => {
|
||||||
|
return Group;
|
||||||
|
})
|
||||||
groups!: Collection<Group>;
|
groups!: Collection<Group>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,8 +3,14 @@ import { User } from './user.entity.js';
|
||||||
import { Class } from '../classes/class.entity.js';
|
import { Class } from '../classes/class.entity.js';
|
||||||
import { TeacherRepository } from '../../data/users/teacher-repository.js';
|
import { TeacherRepository } from '../../data/users/teacher-repository.js';
|
||||||
|
|
||||||
@Entity({ repository: () => TeacherRepository })
|
@Entity({
|
||||||
|
repository: () => {
|
||||||
|
return TeacherRepository;
|
||||||
|
},
|
||||||
|
})
|
||||||
export class Teacher extends User {
|
export class Teacher extends User {
|
||||||
@ManyToMany(() => Class)
|
@ManyToMany(() => {
|
||||||
|
return Class;
|
||||||
|
})
|
||||||
classes!: Collection<Class>;
|
classes!: Collection<Class>;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
import { Assignment } from "../entities/assignments/assignment.entity.js";
|
import { Assignment } from '../entities/assignments/assignment.entity.js';
|
||||||
import { GroupDTO, mapToGroupDTO } from "./groups.js";
|
import { GroupDTO, mapToGroupDTO } from './group.js';
|
||||||
|
|
||||||
export interface AssignmentDTO {
|
export interface AssignmentDTO {
|
||||||
id: number,
|
id: number;
|
||||||
class: string, // id of class 'within'
|
class: string; // Id of class 'within'
|
||||||
title: string,
|
title: string;
|
||||||
description: string,
|
description: string;
|
||||||
learningPath: string,
|
learningPath: string;
|
||||||
language: string,
|
language: string;
|
||||||
groups?: GroupDTO[] | string[], // TODO
|
groups?: GroupDTO[] | string[]; // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapToAssignmentDTOId(assignment: Assignment): AssignmentDTO {
|
export function mapToAssignmentDTOId(assignment: Assignment): AssignmentDTO {
|
||||||
|
@ -19,8 +19,8 @@ export function mapToAssignmentDTOId(assignment: Assignment): AssignmentDTO {
|
||||||
description: assignment.description,
|
description: assignment.description,
|
||||||
learningPath: assignment.learningPathHruid,
|
learningPath: assignment.learningPathHruid,
|
||||||
language: assignment.learningPathLanguage,
|
language: assignment.learningPathLanguage,
|
||||||
// groups: assignment.groups.map(group => group.groupNumber),
|
// Groups: assignment.groups.map(group => group.groupNumber),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapToAssignmentDTO(assignment: Assignment): AssignmentDTO {
|
export function mapToAssignmentDTO(assignment: Assignment): AssignmentDTO {
|
||||||
|
@ -31,6 +31,6 @@ export function mapToAssignmentDTO(assignment: Assignment): AssignmentDTO {
|
||||||
description: assignment.description,
|
description: assignment.description,
|
||||||
learningPath: assignment.learningPathHruid,
|
learningPath: assignment.learningPathHruid,
|
||||||
language: assignment.learningPathLanguage,
|
language: assignment.learningPathLanguage,
|
||||||
// groups: assignment.groups.map(mapToGroupDTO),
|
// Groups: assignment.groups.map(mapToGroupDTO),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Class } from "../entities/classes/class.entity.js";
|
import { Class } from '../entities/classes/class.entity.js';
|
||||||
|
|
||||||
export interface ClassDTO {
|
export interface ClassDTO {
|
||||||
id: string;
|
id: string;
|
||||||
|
@ -18,8 +18,12 @@ export function mapToClassDTO(cls: Class): ClassDTO {
|
||||||
return {
|
return {
|
||||||
id: cls.classId,
|
id: cls.classId,
|
||||||
displayName: cls.displayName,
|
displayName: cls.displayName,
|
||||||
teachers: cls.teachers.map(teacher => teacher.username),
|
teachers: cls.teachers.map((teacher) => {
|
||||||
students: cls.students.map(student => student.username),
|
return teacher.username;
|
||||||
|
}),
|
||||||
|
students: cls.students.map((student) => {
|
||||||
|
return student.username;
|
||||||
|
}),
|
||||||
joinRequests: [], // TODO
|
joinRequests: [], // TODO
|
||||||
}
|
};
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,25 +1,27 @@
|
||||||
import { Group } from "../entities/assignments/group.entity.js";
|
import { Group } from '../entities/assignments/group.entity.js';
|
||||||
import { AssignmentDTO, mapToAssignmentDTO } from "./assignments.js";
|
import { AssignmentDTO, mapToAssignmentDTO } from './assignment.js';
|
||||||
import { mapToStudentDTO, StudentDTO } from "./students.js";
|
import { mapToStudentDTO, StudentDTO } from './student.js';
|
||||||
|
|
||||||
export interface GroupDTO {
|
export interface GroupDTO {
|
||||||
assignment: number | AssignmentDTO,
|
assignment: number | AssignmentDTO;
|
||||||
groupNumber: number,
|
groupNumber: number;
|
||||||
members: string[] | StudentDTO[],
|
members: string[] | StudentDTO[];
|
||||||
};
|
}
|
||||||
|
|
||||||
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),
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
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 => member.username),
|
members: group.members.map((member) => {
|
||||||
}
|
return member.username;
|
||||||
|
}),
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
// TODO: implement something like this but with named endpoints
|
// TODO: implement something like this but with named endpoints
|
||||||
export interface List<T> {
|
export interface List<T> {
|
||||||
items: T[],
|
items: T[];
|
||||||
endpoints?: string[],
|
endpoints?: string[];
|
||||||
};
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
import {Question} from "../entities/questions/question.entity";
|
import { Question } from '../entities/questions/question.entity.js';
|
||||||
import {Enum, PrimaryKey} from "@mikro-orm/core";
|
|
||||||
import {Language} from "../entities/content/language";
|
|
||||||
|
|
||||||
export interface QuestionDTO {
|
export interface QuestionDTO {
|
||||||
learningObjectHruid: string;
|
learningObjectHruid: string;
|
||||||
|
@ -34,8 +32,17 @@ export function mapToQuestionDTO(question: Question): QuestionDTO {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuestionId {
|
export interface QuestionId {
|
||||||
learningObjectHruid: string,
|
learningObjectHruid: string;
|
||||||
learningObjectLanguage: Language,
|
learningObjectLanguage: string;
|
||||||
learningObjectVersion: string,
|
learningObjectVersion: string;
|
||||||
sequenceNumber: number
|
sequenceNumber: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function mapToQuestionId(question: QuestionDTO): QuestionId {
|
||||||
|
return {
|
||||||
|
learningObjectHruid: question.learningObjectHruid,
|
||||||
|
learningObjectLanguage: question.learningObjectLanguage,
|
||||||
|
learningObjectVersion: question.learningObjectVersion,
|
||||||
|
sequenceNumber: question.sequenceNumber,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Student } from "../entities/users/student.entity.js";
|
import { Student } from '../entities/users/student.entity.js';
|
||||||
|
|
||||||
export interface StudentDTO {
|
export interface StudentDTO {
|
||||||
id: string;
|
id: string;
|
||||||
|
|
|
@ -1,22 +1,26 @@
|
||||||
import { TeacherInvitation } from "../entities/classes/teacher-invitation.entity.js";
|
import { TeacherInvitation } from '../entities/classes/teacher-invitation.entity.js';
|
||||||
import { ClassDTO, mapToClassDTO } from "./classes.js";
|
import { ClassDTO, mapToClassDTO } from './class.js';
|
||||||
import { mapToTeacherDTO, TeacherDTO } from "./teacher.js";
|
import { mapToUserDTO, UserDTO } from './user.js';
|
||||||
|
|
||||||
export interface TeacherInvitationDTO {
|
export interface TeacherInvitationDTO {
|
||||||
sender: string | TeacherDTO,
|
sender: string | UserDTO;
|
||||||
receiver: string | TeacherDTO,
|
receiver: string | UserDTO;
|
||||||
class: string | ClassDTO,
|
class: string | ClassDTO;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapToTeacherInvitationDTO(invitation: TeacherInvitation): TeacherInvitationDTO {
|
export function mapToTeacherInvitationDTO(
|
||||||
|
invitation: TeacherInvitation
|
||||||
|
): TeacherInvitationDTO {
|
||||||
return {
|
return {
|
||||||
sender: mapToTeacherDTO(invitation.sender),
|
sender: mapToUserDTO(invitation.sender),
|
||||||
receiver: mapToTeacherDTO(invitation.receiver),
|
receiver: mapToUserDTO(invitation.receiver),
|
||||||
class: mapToClassDTO(invitation.class),
|
class: mapToClassDTO(invitation.class),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapToTeacherInvitationDTOIds(invitation: TeacherInvitation): TeacherInvitationDTO {
|
export function mapToTeacherInvitationDTOIds(
|
||||||
|
invitation: TeacherInvitation
|
||||||
|
): TeacherInvitationDTO {
|
||||||
return {
|
return {
|
||||||
sender: invitation.sender.username,
|
sender: invitation.sender.username,
|
||||||
receiver: invitation.receiver.username,
|
receiver: invitation.receiver.username,
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
import { Teacher } from "../entities/users/teacher.entity.js";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Teacher Data Transfer Object
|
|
||||||
*/
|
|
||||||
export interface TeacherDTO {
|
|
||||||
username: string;
|
|
||||||
firstName: string;
|
|
||||||
lastName: string;
|
|
||||||
endpoints?: {
|
|
||||||
self: string;
|
|
||||||
classes: string;
|
|
||||||
questions: string;
|
|
||||||
invitations: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Maps a Teacher entity to a TeacherDTO
|
|
||||||
*/
|
|
||||||
export function mapToTeacherDTO(teacher: Teacher): TeacherDTO {
|
|
||||||
return {
|
|
||||||
username: teacher.username,
|
|
||||||
firstName: teacher.firstName,
|
|
||||||
lastName: teacher.lastName,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToTeacher(teacherData: TeacherDTO): Teacher {
|
|
||||||
const teacher = new Teacher();
|
|
||||||
teacher.username = teacherData.username;
|
|
||||||
teacher.firstName = teacherData.firstName;
|
|
||||||
teacher.lastName = teacherData.lastName;
|
|
||||||
|
|
||||||
return teacher;
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { User } from "../entities/users/user.entity.js";
|
import { User } from '../entities/users/user.entity.js';
|
||||||
|
|
||||||
export interface UserDTO {
|
export interface UserDTO {
|
||||||
id?: string,
|
id?: string;
|
||||||
username: string;
|
username: string;
|
||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
|
@ -22,7 +22,10 @@ export function mapToUserDTO(user: User): UserDTO {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapToUser<T extends User>(userData: UserDTO, userInstance: T): T {
|
export function mapToUser<T extends User>(
|
||||||
|
userData: UserDTO,
|
||||||
|
userInstance: T
|
||||||
|
): T {
|
||||||
userInstance.username = userData.username;
|
userInstance.username = userData.username;
|
||||||
userInstance.firstName = userData.firstName;
|
userInstance.firstName = userData.firstName;
|
||||||
userInstance.lastName = userData.lastName;
|
userInstance.lastName = userData.lastName;
|
||||||
|
|
|
@ -24,11 +24,20 @@ import { Answer } from './entities/questions/answer.entity.js';
|
||||||
import { Question } from './entities/questions/question.entity.js';
|
import { Question } from './entities/questions/question.entity.js';
|
||||||
|
|
||||||
const entities = [
|
const entities = [
|
||||||
User, Student, Teacher,
|
User,
|
||||||
Assignment, Group, Submission,
|
Student,
|
||||||
Class, ClassJoinRequest, TeacherInvitation,
|
Teacher,
|
||||||
Attachment, LearningObject, LearningPath,
|
Assignment,
|
||||||
Answer, Question
|
Group,
|
||||||
|
Submission,
|
||||||
|
Class,
|
||||||
|
ClassJoinRequest,
|
||||||
|
TeacherInvitation,
|
||||||
|
Attachment,
|
||||||
|
LearningObject,
|
||||||
|
LearningPath,
|
||||||
|
Answer,
|
||||||
|
Question,
|
||||||
];
|
];
|
||||||
|
|
||||||
function config(testingMode: boolean = false): Options {
|
function config(testingMode: boolean = false): Options {
|
||||||
|
@ -37,25 +46,26 @@ function config(testingMode: boolean = false): Options {
|
||||||
driver: SqliteDriver,
|
driver: SqliteDriver,
|
||||||
dbName: getEnvVar(EnvVars.DbName),
|
dbName: getEnvVar(EnvVars.DbName),
|
||||||
entities: entities,
|
entities: entities,
|
||||||
// entitiesTs: entitiesTs,
|
// EntitiesTs: entitiesTs,
|
||||||
|
|
||||||
// Workaround: vitest: `TypeError: Unknown file extension ".ts"` (ERR_UNKNOWN_FILE_EXTENSION)
|
// Workaround: vitest: `TypeError: Unknown file extension ".ts"` (ERR_UNKNOWN_FILE_EXTENSION)
|
||||||
// (see https://mikro-orm.io/docs/guide/project-setup#testing-the-endpoint)
|
// (see https://mikro-orm.io/docs/guide/project-setup#testing-the-endpoint)
|
||||||
dynamicImportProvider: (id) => import(id),
|
dynamicImportProvider: (id) => {
|
||||||
};
|
return import(id);
|
||||||
} else {
|
},
|
||||||
return {
|
|
||||||
driver: PostgreSqlDriver,
|
|
||||||
host: getEnvVar(EnvVars.DbHost),
|
|
||||||
port: getNumericEnvVar(EnvVars.DbPort),
|
|
||||||
dbName: getEnvVar(EnvVars.DbName),
|
|
||||||
user: getEnvVar(EnvVars.DbUsername),
|
|
||||||
password: getEnvVar(EnvVars.DbPassword),
|
|
||||||
entities: entities,
|
|
||||||
//entitiesTs: entitiesTs,
|
|
||||||
debug: true,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
return {
|
||||||
|
driver: PostgreSqlDriver,
|
||||||
|
host: getEnvVar(EnvVars.DbHost),
|
||||||
|
port: getNumericEnvVar(EnvVars.DbPort),
|
||||||
|
dbName: getEnvVar(EnvVars.DbName),
|
||||||
|
user: getEnvVar(EnvVars.DbUsername),
|
||||||
|
password: getEnvVar(EnvVars.DbPassword),
|
||||||
|
entities: entities,
|
||||||
|
//EntitiesTs: entitiesTs,
|
||||||
|
debug: true,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export default config;
|
export default config;
|
||||||
|
|
|
@ -1,31 +1,30 @@
|
||||||
import express from 'express'
|
import express from 'express';
|
||||||
import { getAllAssignmentsHandler, getAssignmentHandler } from '../controllers/assignments.js';
|
import {
|
||||||
import groupRouter from './group.js';
|
getAllAssignmentsHandler,
|
||||||
|
getAssignmentHandler,
|
||||||
|
} from '../controllers/assignments.js';
|
||||||
|
import groupRouter from './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('/', getAllAssignmentsHandler);
|
router.get('/', getAllAssignmentsHandler);
|
||||||
|
|
||||||
// information about an assignment with id 'id'
|
// Information about an assignment with id 'id'
|
||||||
router.get('/:id', getAssignmentHandler);
|
router.get('/:id', getAssignmentHandler);
|
||||||
|
|
||||||
router.get('/:id/submissions', (req, res) => {
|
router.get('/:id/submissions', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
submissions: [
|
submissions: ['0'],
|
||||||
'0'
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/:id/questions', (req, res) => {
|
router.get('/:id/questions', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
questions: [
|
questions: ['0'],
|
||||||
'0'
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
router.use('/:assignmentid/groups', groupRouter);
|
router.use('/:assignmentid/groups', groupRouter);
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
|
@ -1,13 +1,18 @@
|
||||||
import express from 'express'
|
import express from 'express';
|
||||||
import { getAllClassesHandler, getClassHandler, getClassStudentsHandler, getTeacherInvitationsHandler } from '../controllers/classes.js';
|
import {
|
||||||
import assignmentRouter from './assignment.js';
|
getAllClassesHandler,
|
||||||
|
getClassHandler,
|
||||||
|
getClassStudentsHandler,
|
||||||
|
getTeacherInvitationsHandler,
|
||||||
|
} from '../controllers/classes.js';
|
||||||
|
import assignmentRouter from './assignments.js';
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// root endpoint used to search objects
|
// Root endpoint used to search objects
|
||||||
router.get('/', getAllClassesHandler);
|
router.get('/', getAllClassesHandler);
|
||||||
|
|
||||||
// information about an class with id 'id'
|
// Information about an class with id 'id'
|
||||||
router.get('/:id', getClassHandler);
|
router.get('/:id', getClassHandler);
|
||||||
|
|
||||||
router.get('/:id/teacher-invitations', getTeacherInvitationsHandler);
|
router.get('/:id/teacher-invitations', getTeacherInvitationsHandler);
|
||||||
|
@ -16,4 +21,4 @@ router.get('/:id/students', getClassStudentsHandler);
|
||||||
|
|
||||||
router.use('/:classid/assignments', assignmentRouter);
|
router.use('/:classid/assignments', assignmentRouter);
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
|
@ -1,18 +1,19 @@
|
||||||
import express from 'express'
|
import express from 'express';
|
||||||
import { getAllGroupsHandler, getGroupHandler } from '../controllers/groups.js';
|
import { getAllGroupsHandler, getGroupHandler } 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);
|
||||||
|
|
||||||
// information about a group (members, ... [TODO DOC])
|
// Information about a group (members, ... [TODO DOC])
|
||||||
router.get('/:groupid', getGroupHandler);
|
router.get('/:groupid', getGroupHandler);
|
||||||
|
|
||||||
// the list of questions a group has made
|
// The list of questions a group has made
|
||||||
router.get('/:id/question', (req, res) => {
|
router.get('/:id/question', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
questions: [ '0' ],
|
questions: ['0'],
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
|
@ -1,38 +1,34 @@
|
||||||
import express from 'express'
|
import express from 'express';
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// root endpoint used to search objects
|
// Root endpoint used to search objects
|
||||||
router.get('/', (req, res) => {
|
router.get('/', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
questions: [
|
questions: ['0', '1'],
|
||||||
'0',
|
|
||||||
'1',
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// information about an question with id 'id'
|
// Information about an question with id 'id'
|
||||||
router.get('/:id', (req, res) => {
|
router.get('/:id', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
id: req.params.id,
|
id: req.params.id,
|
||||||
student: '0',
|
student: '0',
|
||||||
group: '0',
|
group: '0',
|
||||||
time: new Date(2025, 1, 1),
|
time: new Date(2025, 1, 1),
|
||||||
content: 'Zijn alle gehele getallen groter dan 2 gelijk aan de som van 2 priemgetallen????',
|
content:
|
||||||
|
'Zijn alle gehele getallen groter dan 2 gelijk aan de som van 2 priemgetallen????',
|
||||||
learningObject: '0',
|
learningObject: '0',
|
||||||
links: {
|
links: {
|
||||||
self: `${req.baseUrl}/${req.params.id}`,
|
self: `${req.baseUrl}/${req.params.id}`,
|
||||||
answers: `${req.baseUrl}/${req.params.id}/answers`,
|
answers: `${req.baseUrl}/${req.params.id}/answers`,
|
||||||
}
|
},
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
router.get('/:id/answers', (req, res) => {
|
router.get('/:id/answers', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
answers: [
|
answers: ['0'],
|
||||||
'0'
|
});
|
||||||
],
|
});
|
||||||
})
|
|
||||||
})
|
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
|
@ -1,51 +1,49 @@
|
||||||
import express from 'express'
|
import express from 'express';
|
||||||
import {
|
import {
|
||||||
createStudentHandler, deleteStudentHandler,
|
createStudentHandler,
|
||||||
|
deleteStudentHandler,
|
||||||
getAllStudentsHandler,
|
getAllStudentsHandler,
|
||||||
getStudentAssignmentsHandler,
|
getStudentAssignmentsHandler,
|
||||||
getStudentClassesHandler,
|
getStudentClassesHandler,
|
||||||
getStudentHandler
|
getStudentHandler,
|
||||||
} from '../controllers/students.js';
|
} from '../controllers/students.js';
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// root endpoint used to search objects
|
// Root endpoint used to search objects
|
||||||
router.get('/', getAllStudentsHandler);
|
router.get('/', getAllStudentsHandler);
|
||||||
|
|
||||||
router.post('/', createStudentHandler);
|
router.post('/', createStudentHandler);
|
||||||
|
|
||||||
router.delete('/:username', deleteStudentHandler);
|
router.delete('/:username', deleteStudentHandler);
|
||||||
|
|
||||||
// information about a student's profile
|
// Information about a student's profile
|
||||||
router.get('/:username', getStudentHandler);
|
router.get('/:username', getStudentHandler);
|
||||||
|
|
||||||
|
// The list of classes a student is in
|
||||||
|
|
||||||
// the list of classes a student is in
|
|
||||||
router.get('/:id/classes', getStudentClassesHandler);
|
router.get('/:id/classes', getStudentClassesHandler);
|
||||||
|
|
||||||
// the list of submissions a student has made
|
// The list of submissions a student has made
|
||||||
router.get('/:id/submissions', (req, res) => {
|
router.get('/:id/submissions', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
submissions: [ '0' ],
|
submissions: ['0'],
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
|
// The list of assignments a student has
|
||||||
// the list of assignments a student has
|
|
||||||
router.get('/:id/assignments', getStudentAssignmentsHandler);
|
router.get('/:id/assignments', getStudentAssignmentsHandler);
|
||||||
|
|
||||||
// the list of groups a student is in
|
// The list of groups a student is in
|
||||||
router.get('/:id/groups', (req, res) => {
|
router.get('/:id/groups', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
groups: [ '0' ],
|
groups: ['0'],
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
// a list of questions a user has created
|
// A list of questions a user has created
|
||||||
router.get('/:id/questions', (req, res) => {
|
router.get('/:id/questions', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
questions: [ '0' ],
|
questions: ['0'],
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
import express from 'express'
|
import express from 'express';
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// root endpoint used to search objects
|
// Root endpoint used to search objects
|
||||||
router.get('/', (req, res) => {
|
router.get('/', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
submissions: [
|
submissions: ['0', '1'],
|
||||||
'0',
|
|
||||||
'1',
|
|
||||||
]
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// information about an submission with id 'id'
|
// Information about an submission with id 'id'
|
||||||
router.get('/:id', (req, res) => {
|
router.get('/:id', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
id: req.params.id,
|
id: req.params.id,
|
||||||
|
@ -21,6 +18,6 @@ router.get('/:id', (req, res) => {
|
||||||
content: 'Wortel 2 is rationeel',
|
content: 'Wortel 2 is rationeel',
|
||||||
learningObject: '0',
|
learningObject: '0',
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
export default router
|
export default router;
|
||||||
|
|
|
@ -1,17 +1,22 @@
|
||||||
import express from 'express'
|
import express from 'express';
|
||||||
import {
|
import {
|
||||||
createTeacherHandler,
|
createTeacherHandler,
|
||||||
deleteTeacherHandler,
|
deleteTeacherHandler,
|
||||||
|
getAllTeachersHandler,
|
||||||
getTeacherClassHandler,
|
getTeacherClassHandler,
|
||||||
getTeacherHandler, getTeacherQuestionHandler, getTeacherStudentHandler
|
getTeacherHandler,
|
||||||
} from "../controllers/teachers.js";
|
getTeacherQuestionHandler,
|
||||||
|
getTeacherStudentHandler,
|
||||||
|
} from '../controllers/teachers.js';
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
|
|
||||||
// root endpoint used to search objects
|
// Root endpoint used to search objects
|
||||||
router.get('/', getTeacherHandler);
|
router.get('/', getAllTeachersHandler);
|
||||||
|
|
||||||
router.post('/', createTeacherHandler);
|
router.post('/', createTeacherHandler);
|
||||||
|
|
||||||
|
router.get('/:username', getTeacherHandler);
|
||||||
|
|
||||||
router.delete('/:username', deleteTeacherHandler);
|
router.delete('/:username', deleteTeacherHandler);
|
||||||
|
|
||||||
router.get('/:username/classes', getTeacherClassHandler);
|
router.get('/:username/classes', getTeacherClassHandler);
|
||||||
|
@ -20,15 +25,11 @@ router.get('/:username/students', getTeacherStudentHandler);
|
||||||
|
|
||||||
router.get('/:username/questions', getTeacherQuestionHandler);
|
router.get('/:username/questions', getTeacherQuestionHandler);
|
||||||
|
|
||||||
// invitations to other classes a teacher received
|
// Invitations to other classes a teacher received
|
||||||
router.get('/:id/invitations', (req, res) => {
|
router.get('/:id/invitations', (req, res) => {
|
||||||
res.json({
|
res.json({
|
||||||
invitations: [
|
invitations: ['0'],
|
||||||
'0'
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default router;
|
||||||
|
|
||||||
export default router
|
|
||||||
|
|
|
@ -1,7 +1,17 @@
|
||||||
import { getAssignmentRepository, getClassRepository } from "../data/repositories.js";
|
import {
|
||||||
import { AssignmentDTO, mapToAssignmentDTO, mapToAssignmentDTOId } from "../interfaces/assignments.js";
|
getAssignmentRepository,
|
||||||
|
getClassRepository,
|
||||||
|
} from '../data/repositories.js';
|
||||||
|
import {
|
||||||
|
AssignmentDTO,
|
||||||
|
mapToAssignmentDTO,
|
||||||
|
mapToAssignmentDTOId,
|
||||||
|
} from '../interfaces/assignment.js';
|
||||||
|
|
||||||
export async function getAllAssignments(classid: string, full: boolean): Promise<AssignmentDTO[]> {
|
export async function getAllAssignments(
|
||||||
|
classid: string,
|
||||||
|
full: boolean
|
||||||
|
): Promise<AssignmentDTO[]> {
|
||||||
const classRepository = getClassRepository();
|
const classRepository = getClassRepository();
|
||||||
const cls = await classRepository.findById(classid);
|
const cls = await classRepository.findById(classid);
|
||||||
|
|
||||||
|
@ -10,7 +20,8 @@ export async function getAllAssignments(classid: string, full: boolean): Promise
|
||||||
}
|
}
|
||||||
|
|
||||||
const assignmentRepository = getAssignmentRepository();
|
const assignmentRepository = getAssignmentRepository();
|
||||||
const assignments = await assignmentRepository.findAllAssignmentsInClass(cls);
|
const assignments =
|
||||||
|
await assignmentRepository.findAllAssignmentsInClass(cls);
|
||||||
|
|
||||||
if (full) {
|
if (full) {
|
||||||
return assignments.map(mapToAssignmentDTO);
|
return assignments.map(mapToAssignmentDTO);
|
||||||
|
@ -19,7 +30,10 @@ export async function getAllAssignments(classid: string, full: boolean): Promise
|
||||||
return assignments.map(mapToAssignmentDTOId);
|
return assignments.map(mapToAssignmentDTOId);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAssignment(classid: string, id: number): Promise<AssignmentDTO | null> {
|
export async function getAssignment(
|
||||||
|
classid: string,
|
||||||
|
id: number
|
||||||
|
): Promise<AssignmentDTO | null> {
|
||||||
const classRepository = getClassRepository();
|
const classRepository = getClassRepository();
|
||||||
const cls = await classRepository.findById(classid);
|
const cls = await classRepository.findById(classid);
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,23 @@
|
||||||
import { getClassRepository } from "../data/repositories";
|
import {
|
||||||
import { Class } from "../entities/classes/class.entity";
|
getClassRepository,
|
||||||
import { ClassDTO, mapToClassDTO } from "../interfaces/class";
|
getTeacherInvitationRepository,
|
||||||
import { mapToStudentDTO, StudentDTO } from "../interfaces/student";
|
} from '../data/repositories.js';
|
||||||
|
import { ClassDTO, mapToClassDTO } from '../interfaces/class.js';
|
||||||
|
import { mapToStudentDTO, StudentDTO } from '../interfaces/student.js';
|
||||||
|
import {
|
||||||
|
mapToTeacherInvitationDTO,
|
||||||
|
mapToTeacherInvitationDTOIds,
|
||||||
|
TeacherInvitationDTO,
|
||||||
|
} from '../interfaces/teacher-invitation.js';
|
||||||
|
|
||||||
export async function getAllClasses(full: boolean): Promise<ClassDTO[] | string[]> {
|
export async function getAllClasses(
|
||||||
|
full: boolean
|
||||||
|
): Promise<ClassDTO[] | string[]> {
|
||||||
const classRepository = getClassRepository();
|
const classRepository = getClassRepository();
|
||||||
const classes = await classRepository.find({}, { populate: ["students", "teachers"] });
|
const classes = await classRepository.find(
|
||||||
|
{},
|
||||||
|
{ populate: ['students', 'teachers'] }
|
||||||
|
);
|
||||||
|
|
||||||
if (!classes) {
|
if (!classes) {
|
||||||
return [];
|
return [];
|
||||||
|
@ -13,27 +25,30 @@ export async function getAllClasses(full: boolean): Promise<ClassDTO[] | string[
|
||||||
|
|
||||||
if (full) {
|
if (full) {
|
||||||
return classes.map(mapToClassDTO);
|
return classes.map(mapToClassDTO);
|
||||||
} else {
|
|
||||||
return classes.map((cls) => cls.classId);
|
|
||||||
}
|
}
|
||||||
|
return classes.map((cls) => {
|
||||||
|
return cls.classId;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getClass(classId: string): Promise<ClassDTO | null> {
|
export async function getClass(classId: string): Promise<ClassDTO | null> {
|
||||||
const classRepository = getClassRepository();
|
const classRepository = getClassRepository();
|
||||||
const cls = await classRepository.findById(classId);
|
const cls = await classRepository.findById(classId);
|
||||||
|
|
||||||
if (!cls) return null;
|
if (!cls) {
|
||||||
else {
|
return null;
|
||||||
return mapToClassDTO(cls);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return mapToClassDTO(cls);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchClassStudents(classId: string, full: boolean): Promise<StudentDTO[] | string[]> {
|
async function fetchClassStudents(classId: string): Promise<StudentDTO[]> {
|
||||||
const classRepository = getClassRepository();
|
const classRepository = getClassRepository();
|
||||||
const cls = await classRepository.findById(classId);
|
const cls = await classRepository.findById(classId);
|
||||||
|
|
||||||
if (!cls)
|
if (!cls) {
|
||||||
return [];
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
return cls.students.map(mapToStudentDTO);
|
return cls.students.map(mapToStudentDTO);
|
||||||
}
|
}
|
||||||
|
@ -43,6 +58,36 @@ export async function getClassStudents(classId: string): Promise<StudentDTO[]> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getClassStudentsIds(classId: string): Promise<string[]> {
|
export async function getClassStudentsIds(classId: string): Promise<string[]> {
|
||||||
return await fetchClassStudents(classId).map((student) => student.username);
|
const students: StudentDTO[] = await fetchClassStudents(classId);
|
||||||
|
return students.map((student) => {
|
||||||
|
return student.username;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getClassTeacherInvitations(
|
||||||
|
classId: string,
|
||||||
|
full: boolean
|
||||||
|
): Promise<TeacherInvitationDTO[]> {
|
||||||
|
const classRepository = getClassRepository();
|
||||||
|
const cls = await classRepository.findById(classId);
|
||||||
|
|
||||||
|
if (!cls) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const teacherInvitationRepository = getTeacherInvitationRepository();
|
||||||
|
const invitations =
|
||||||
|
await teacherInvitationRepository.findAllInvitationsForClass(cls);
|
||||||
|
|
||||||
|
console.log(invitations);
|
||||||
|
|
||||||
|
if (!invitations) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (full) {
|
||||||
|
return invitations.map(mapToTeacherInvitationDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
return invitations.map(mapToTeacherInvitationDTOIds);
|
||||||
|
}
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
import { getAssignmentRepository, getClassRepository, getGroupRepository } from "../data/repositories.js";
|
import {
|
||||||
import { GroupDTO, mapToGroupDTO, mapToGroupDTOId } from "../interfaces/groups.js";
|
getAssignmentRepository,
|
||||||
|
getClassRepository,
|
||||||
|
getGroupRepository,
|
||||||
|
} from '../data/repositories.js';
|
||||||
|
import {
|
||||||
|
GroupDTO,
|
||||||
|
mapToGroupDTO,
|
||||||
|
mapToGroupDTOId,
|
||||||
|
} from '../interfaces/group.js';
|
||||||
|
|
||||||
export async function getGroup(
|
export async function getGroup(
|
||||||
classId: string,
|
classId: string,
|
||||||
assignmentNumber: number,
|
assignmentNumber: number,
|
||||||
groupNumber: number,
|
groupNumber: number,
|
||||||
full: boolean,
|
full: boolean
|
||||||
): Promise<GroupDTO | null> {
|
): Promise<GroupDTO | null> {
|
||||||
const classRepository = getClassRepository();
|
const classRepository = getClassRepository();
|
||||||
const cls = await classRepository.findById(classId);
|
const cls = await classRepository.findById(classId);
|
||||||
|
@ -15,14 +23,20 @@ export async function getGroup(
|
||||||
}
|
}
|
||||||
|
|
||||||
const assignmentRepository = getAssignmentRepository();
|
const assignmentRepository = getAssignmentRepository();
|
||||||
const assignment = await assignmentRepository.findByClassAndId(cls, assignmentNumber);
|
const assignment = await assignmentRepository.findByClassAndId(
|
||||||
|
cls,
|
||||||
|
assignmentNumber
|
||||||
|
);
|
||||||
|
|
||||||
if (!assignment) {
|
if (!assignment) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupRepository = getGroupRepository();
|
const groupRepository = getGroupRepository();
|
||||||
const group = await groupRepository.findByAssignmentAndGroupNumber(assignment, groupNumber);
|
const group = await groupRepository.findByAssignmentAndGroupNumber(
|
||||||
|
assignment,
|
||||||
|
groupNumber
|
||||||
|
);
|
||||||
|
|
||||||
if (!group) {
|
if (!group) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -38,7 +52,7 @@ export async function getGroup(
|
||||||
export async function getAllGroups(
|
export async function getAllGroups(
|
||||||
classId: string,
|
classId: string,
|
||||||
assignmentNumber: number,
|
assignmentNumber: number,
|
||||||
full: boolean,
|
full: boolean
|
||||||
): Promise<GroupDTO[]> {
|
): Promise<GroupDTO[]> {
|
||||||
const classRepository = getClassRepository();
|
const classRepository = getClassRepository();
|
||||||
const cls = await classRepository.findById(classId);
|
const cls = await classRepository.findById(classId);
|
||||||
|
@ -48,7 +62,10 @@ export async function getAllGroups(
|
||||||
}
|
}
|
||||||
|
|
||||||
const assignmentRepository = getAssignmentRepository();
|
const assignmentRepository = getAssignmentRepository();
|
||||||
const assignment = await assignmentRepository.findByClassAndId(cls, assignmentNumber);
|
const assignment = await assignmentRepository.findByClassAndId(
|
||||||
|
cls,
|
||||||
|
assignmentNumber
|
||||||
|
);
|
||||||
|
|
||||||
if (!assignment) {
|
if (!assignment) {
|
||||||
return [];
|
return [];
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import { getClassRepository, getStudentRepository } from "../data/repositories.js";
|
import {
|
||||||
import { Class } from "../entities/classes/class.entity.js";
|
getClassRepository,
|
||||||
import { Student } from "../entities/users/student.entity.js";
|
getStudentRepository,
|
||||||
import { ClassDTO, mapToClassDTO } from "../interfaces/classes.js";
|
} from '../data/repositories.js';
|
||||||
import {UserService} from "./users.js";
|
import { Class } from '../entities/classes/class.entity.js';
|
||||||
|
import { Student } from '../entities/users/student.entity.js';
|
||||||
|
import { ClassDTO, mapToClassDTO } from '../interfaces/class.js';
|
||||||
|
import { UserService } from './users.js';
|
||||||
|
|
||||||
export class StudentService extends UserService<Student> {
|
export class StudentService extends UserService<Student> {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -14,12 +17,16 @@ async function fetchStudentClasses(username: string): Promise<Class[]> {
|
||||||
const studentRepository = getStudentRepository();
|
const studentRepository = getStudentRepository();
|
||||||
const student = await studentRepository.findByUsername(username);
|
const student = await studentRepository.findByUsername(username);
|
||||||
|
|
||||||
if (!student) return [];
|
if (!student) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
const classRepository = getClassRepository();
|
const classRepository = getClassRepository();
|
||||||
const classes = await classRepository.findByStudent(student);
|
const classes = await classRepository.findByStudent(student);
|
||||||
|
|
||||||
if (!classes) return [];
|
if (!classes) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
return classes;
|
return classes;
|
||||||
}
|
}
|
||||||
|
@ -31,6 +38,7 @@ export async function getStudentClasses(username: string): Promise<ClassDTO[]> {
|
||||||
|
|
||||||
export async function getStudentClassIds(username: string): Promise<string[]> {
|
export async function getStudentClassIds(username: string): Promise<string[]> {
|
||||||
const classes = await fetchStudentClasses(username);
|
const classes = await fetchStudentClasses(username);
|
||||||
return classes.map(cls => cls.classId); // 'class' is a native keyword
|
return classes.map((cls) => {
|
||||||
|
return cls.classId;
|
||||||
|
}); // 'class' is a native keyword
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,130 +2,108 @@ import {
|
||||||
getClassRepository,
|
getClassRepository,
|
||||||
getLearningObjectRepository,
|
getLearningObjectRepository,
|
||||||
getQuestionRepository,
|
getQuestionRepository,
|
||||||
getTeacherRepository
|
getStudentRepository,
|
||||||
} from "../data/repositories.js";
|
getTeacherRepository,
|
||||||
import {mapToTeacher, mapToTeacherDTO, TeacherDTO} from "../interfaces/teacher.js";
|
} from '../data/repositories.js';
|
||||||
import { Teacher } from "../entities/users/teacher.entity";
|
import { Teacher } from '../entities/users/teacher.entity.js';
|
||||||
import {ClassDTO, mapToClassDTO} from "../interfaces/class";
|
import { ClassDTO, mapToClassDTO } from '../interfaces/class.js';
|
||||||
import {getClassStudents, getClassStudentsIds} from "./class";
|
import { getClassStudents } from './class.js';
|
||||||
import {StudentDTO} from "../interfaces/student";
|
import { StudentDTO } from '../interfaces/student.js';
|
||||||
import {mapToQuestionDTO, QuestionDTO, QuestionId} from "../interfaces/question";
|
import {
|
||||||
|
mapToQuestionDTO,
|
||||||
|
mapToQuestionId,
|
||||||
|
QuestionDTO,
|
||||||
|
QuestionId,
|
||||||
|
} from '../interfaces/question.js';
|
||||||
|
import { UserService } from './users.js';
|
||||||
|
import { mapToUser } from '../interfaces/user.js';
|
||||||
|
|
||||||
|
export class TeacherUserService extends UserService<Teacher> {
|
||||||
async function fetchAllTeachers(): Promise<TeacherDTO[]> {
|
constructor() {
|
||||||
const teacherRepository = getTeacherRepository();
|
super(getTeacherRepository());
|
||||||
const teachers = await teacherRepository.find({});
|
}
|
||||||
|
|
||||||
return teachers.map(mapToTeacherDTO);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAllTeachers(): Promise<TeacherDTO[]> {
|
export class TeacherService {
|
||||||
return await fetchAllTeachers();
|
protected teacherService = new TeacherUserService();
|
||||||
}
|
protected teacherRepository = getTeacherRepository();
|
||||||
|
protected classRepository = getClassRepository();
|
||||||
|
protected learningObjectRepository = getLearningObjectRepository();
|
||||||
|
protected questionRepository = getQuestionRepository();
|
||||||
|
|
||||||
export async function getAllTeachersIds(): Promise<string[]> {
|
async fetchClassesByTeacher(username: string): Promise<ClassDTO[]> {
|
||||||
return await fetchAllTeachers().map((teacher) => teacher.username)
|
const teacher = await this.teacherRepository.findByUsername(username);
|
||||||
}
|
if (!teacher) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
export async function createTeacher(teacherData: TeacherDTO): Promise<Teacher> {
|
const classes = await this.classRepository.findByTeacher(teacher);
|
||||||
const teacherRepository = getTeacherRepository();
|
return classes.map(mapToClassDTO);
|
||||||
const newTeacher = mapToTeacher(teacherData);
|
|
||||||
|
|
||||||
await teacherRepository.addTeacher(newTeacher);
|
|
||||||
return newTeacher;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getTeacherByUsername(username: string): Promise<TeacherDTO | null> {
|
|
||||||
const teacherRepository = getTeacherRepository();
|
|
||||||
const teacher = await teacherRepository.findByUsername(username);
|
|
||||||
|
|
||||||
return teacher ? mapToTeacherDTO(teacher) : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deleteTeacher(username: string): Promise<TeacherDTO | null> {
|
|
||||||
const teacherRepository = getTeacherRepository();
|
|
||||||
const teacher = await teacherRepository.findByUsername(username);
|
|
||||||
|
|
||||||
if (!teacher)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
await teacherRepository.deleteByUsername(username);
|
|
||||||
return teacher;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchClassesByTeacher(username: string): Promise<ClassDTO[]> {
|
|
||||||
const teacherRepository = getTeacherRepository();
|
|
||||||
const classRepository = getClassRepository();
|
|
||||||
|
|
||||||
const teacher = await teacherRepository.findByUsername(username);
|
|
||||||
if (!teacher) {
|
|
||||||
return [];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const classes = await classRepository.findByTeacher(teacher);
|
async getClassesByTeacher(username: string): Promise<ClassDTO[]> {
|
||||||
return classes.map(mapToClassDTO);
|
return await this.fetchClassesByTeacher(username);
|
||||||
}
|
|
||||||
|
|
||||||
export async function getClassesByTeacher(username: string): Promise<ClassDTO[]> {
|
|
||||||
return await fetchClassesByTeacher(username)
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getClassIdsByTeacher(): Promise<string[]> {
|
|
||||||
return await fetchClassesByTeacher(username).map((cls) => cls.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchStudentsByTeacher(username: string) {
|
|
||||||
const classes = await getClassIdsByTeacher();
|
|
||||||
|
|
||||||
return Promise.all(
|
|
||||||
classes.map( async (id) => getClassStudents(id))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getStudentsByTeacher(username: string): Promise<StudentDTO[]> {
|
|
||||||
return await fetchStudentsByTeacher(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getStudentIdsByTeacher(): Promise<string[]> {
|
|
||||||
return await fetchStudentsByTeacher(username).map((student) => student.username);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchTeacherQuestions(username: string): Promise<QuestionDTO[]> {
|
|
||||||
const learningObjectRepository = getLearningObjectRepository();
|
|
||||||
const questionRepository = getQuestionRepository();
|
|
||||||
|
|
||||||
const teacher = getTeacherByUsername(username);
|
|
||||||
if (!teacher) {
|
|
||||||
throw new Error(`Teacher with username '${username}' not found.`);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Find all learning objects that this teacher manages
|
async getClassIdsByTeacher(username: string): Promise<string[]> {
|
||||||
const learningObjects = await learningObjectRepository.findAllByTeacher(teacher);
|
const classes = await this.fetchClassesByTeacher(username);
|
||||||
|
return classes.map((cls) => {
|
||||||
|
return cls.id;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch all questions related to these learning objects
|
async fetchStudentsByTeacher(username: string) {
|
||||||
const questions = await questionRepository.findAllByLearningObjects(learningObjects);
|
const classes = await this.getClassIdsByTeacher(username);
|
||||||
|
|
||||||
return questions.map(mapToQuestionDTO);
|
return (
|
||||||
|
await Promise.all(
|
||||||
|
classes.map(async (id) => {
|
||||||
|
return getClassStudents(id);
|
||||||
|
})
|
||||||
|
)
|
||||||
|
).flat();
|
||||||
|
}
|
||||||
|
|
||||||
|
async getStudentsByTeacher(username: string): Promise<StudentDTO[]> {
|
||||||
|
return await this.fetchStudentsByTeacher(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getStudentIdsByTeacher(username: string): Promise<string[]> {
|
||||||
|
const students = await this.fetchStudentsByTeacher(username);
|
||||||
|
return students.map((student) => {
|
||||||
|
return student.username;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchTeacherQuestions(username: string): Promise<QuestionDTO[]> {
|
||||||
|
const teacherDTO =
|
||||||
|
await this.teacherService.getUserByUsername(username);
|
||||||
|
if (!teacherDTO) {
|
||||||
|
throw new Error(`Teacher with username '${username}' not found.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const teacher = mapToUser<Teacher>(teacherDTO, new Teacher());
|
||||||
|
|
||||||
|
// Find all learning objects that this teacher manages
|
||||||
|
const learningObjects =
|
||||||
|
await this.learningObjectRepository.findAllByTeacher(teacher);
|
||||||
|
|
||||||
|
// Fetch all questions related to these learning objects
|
||||||
|
const questions =
|
||||||
|
await this.questionRepository.findAllByLearningObjects(
|
||||||
|
learningObjects
|
||||||
|
);
|
||||||
|
|
||||||
|
return questions.map(mapToQuestionDTO);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getQuestionsByTeacher(username: string): Promise<QuestionDTO[]> {
|
||||||
|
return await this.fetchTeacherQuestions(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getQuestionIdsByTeacher(username: string): Promise<QuestionId[]> {
|
||||||
|
const questions = await this.fetchTeacherQuestions(username);
|
||||||
|
|
||||||
|
return questions.map(mapToQuestionId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getQuestionsByTeacher(username: string): Promise<QuestionDTO[]> {
|
|
||||||
return await fetchTeacherQuestions(username);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getQuestionIdsByTeacher(username: string): Promise<QuestionId[]> {
|
|
||||||
const questions = await fetchTeacherQuestions(username);
|
|
||||||
|
|
||||||
return questions.map((question) => ({
|
|
||||||
learningObjectHruid: question.learningObjectHruid,
|
|
||||||
learningObjectLanguage: question.learningObjectLanguage,
|
|
||||||
learningObjectVersion: question.learningObjectVersion,
|
|
||||||
sequenceNumber: question.sequenceNumber
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { UserRepository } from "../data/users/user-repository.js";
|
import { UserRepository } from '../data/users/user-repository.js';
|
||||||
import { UserDTO, mapToUser, mapToUserDTO } from "../interfaces/user.js";
|
import { UserDTO, mapToUser, mapToUserDTO } from '../interfaces/user.js';
|
||||||
import {User} from "../entities/users/user.entity.js";
|
import { User } from '../entities/users/user.entity.js';
|
||||||
|
|
||||||
export class UserService<T extends User> {
|
export class UserService<T extends User> {
|
||||||
protected repository: UserRepository<T>;
|
protected repository: UserRepository<T>;
|
||||||
|
@ -16,11 +16,13 @@ export class UserService<T extends User> {
|
||||||
|
|
||||||
async getAllUserIds(): Promise<string[]> {
|
async getAllUserIds(): Promise<string[]> {
|
||||||
const users = await this.getAllUsers();
|
const users = await this.getAllUsers();
|
||||||
return users.map((user) => user.username);
|
return users.map((user) => {
|
||||||
|
return user.username;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async getUserByUsername(username: string): Promise<UserDTO | null> {
|
async getUserByUsername(username: string): Promise<UserDTO | null> {
|
||||||
const user = await this.repository.findByUsername(username)
|
const user = await this.repository.findByUsername(username);
|
||||||
return user ? mapToUserDTO(user) : null;
|
return user ? mapToUserDTO(user) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,8 +34,10 @@ export class UserService<T extends User> {
|
||||||
|
|
||||||
async deleteUser(username: string): Promise<UserDTO | null> {
|
async deleteUser(username: string): Promise<UserDTO | null> {
|
||||||
const user = await this.getUserByUsername(username);
|
const user = await this.getUserByUsername(username);
|
||||||
if (!user) return null;
|
if (!user) {
|
||||||
await this.repository.deleteByUsername(username)
|
return null;
|
||||||
|
}
|
||||||
|
await this.repository.deleteByUsername(username);
|
||||||
return mapToUserDTO(user);
|
return mapToUserDTO(user);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import yaml from 'js-yaml';
|
import yaml from 'js-yaml';
|
||||||
import { FALLBACK_LANG } from "../config.js";
|
import { FALLBACK_LANG } from '../config.js';
|
||||||
|
|
||||||
export function loadTranslations<T>(language: string): T {
|
export function loadTranslations<T>(language: string): T {
|
||||||
try {
|
try {
|
||||||
|
@ -13,7 +13,11 @@ export function loadTranslations<T>(language: string): T {
|
||||||
`Cannot load translation for ${language}, fallen back to dutch`
|
`Cannot load translation for ${language}, fallen back to dutch`
|
||||||
);
|
);
|
||||||
console.error(error);
|
console.error(error);
|
||||||
const fallbackPath = path.join(process.cwd(), '_i18n', `${FALLBACK_LANG}.yml`);
|
const fallbackPath = path.join(
|
||||||
|
process.cwd(),
|
||||||
|
'_i18n',
|
||||||
|
`${FALLBACK_LANG}.yml`
|
||||||
|
);
|
||||||
return yaml.load(fs.readFileSync(fallbackPath, 'utf8')) as T;
|
return yaml.load(fs.readFileSync(fallbackPath, 'utf8')) as T;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue