fix: import errors van gabe gefixt, teacher en student abstractie weggedaan
This commit is contained in:
parent
6404335040
commit
b5390258e3
36 changed files with 9754 additions and 180 deletions
|
@ -5,7 +5,7 @@ import themeRoutes from './routes/themes.js';
|
|||
import learningPathRoutes from './routes/learning-paths.js';
|
||||
import learningObjectRoutes from './routes/learning-objects.js';
|
||||
|
||||
import studentRouter from './routes/student.js';
|
||||
import studentRouter from './routes/students.js';
|
||||
import groupRouter from './routes/groups.js';
|
||||
import assignmentRouter from './routes/assignments.js';
|
||||
import submissionRouter from './routes/submissions.js';
|
||||
|
|
|
@ -12,7 +12,7 @@ import {LearningObjectIdentifier} from "../entities/content/learning-object-iden
|
|||
import {Language} from "../entities/content/language.js";
|
||||
|
||||
function getObjectId(req: Request, res: Response): LearningObjectIdentifier | null {
|
||||
const { hruid, version} = req.params
|
||||
const { hruid, version } = req.params
|
||||
const lang = req.query.lang
|
||||
|
||||
if (!hruid || !version ) {
|
||||
|
@ -23,7 +23,7 @@ function getObjectId(req: Request, res: Response): LearningObjectIdentifier | nu
|
|||
return {
|
||||
hruid,
|
||||
language: lang as Language || FALLBACK_LANG,
|
||||
version
|
||||
version: +version
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,49 +1,106 @@
|
|||
import { Request, Response } from 'express';
|
||||
import {
|
||||
createStudent,
|
||||
deleteStudent,
|
||||
getStudent,
|
||||
getStudentAssignments,
|
||||
getStudentClasses,
|
||||
getStudentGroups,
|
||||
getStudentSubmissions,
|
||||
StudentService,
|
||||
} from '../services/students.js';
|
||||
import { ClassDTO } from '../interfaces/class.js';
|
||||
import { getAllAssignments } from '../services/assignments.js';
|
||||
import {
|
||||
createUserHandler,
|
||||
deleteUserHandler,
|
||||
getAllUsersHandler,
|
||||
getUserHandler,
|
||||
} from './users.js';
|
||||
import { Student } from '../entities/users/student.entity.js';
|
||||
import { StudentDTO } from '../interfaces/student.js';
|
||||
import { getStudentRepository } from '../data/repositories.js';
|
||||
import { UserDTO } from '../interfaces/user.js';
|
||||
|
||||
// TODO: accept arguments (full, ...)
|
||||
// TODO: endpoints
|
||||
export async function getAllStudentsHandler(
|
||||
req: Request,
|
||||
res: Response
|
||||
res: Response,
|
||||
): Promise<void> {
|
||||
await getAllUsersHandler<Student>(req, res, new StudentService());
|
||||
const full = req.query.full === 'true';
|
||||
|
||||
const studentRepository = getStudentRepository();
|
||||
|
||||
const students: StudentDTO[] | string[] = full
|
||||
? await getAllStudents()
|
||||
: await getAllStudents();
|
||||
|
||||
if (!students) {
|
||||
res.status(404).json({ error: `Student not found.` });
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(201).json(students);
|
||||
}
|
||||
|
||||
|
||||
export async function getStudentHandler(
|
||||
req: Request,
|
||||
res: Response
|
||||
res: Response,
|
||||
): Promise<void> {
|
||||
await getUserHandler<Student>(req, res, new StudentService());
|
||||
const username = req.params.username;
|
||||
|
||||
if (!username) {
|
||||
res.status(400).json({ error: 'Missing required field: username' });
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await getStudent(username);
|
||||
|
||||
if (!user) {
|
||||
res.status(404).json({
|
||||
error: `User with username '${username}' not found.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(201).json(user);
|
||||
}
|
||||
|
||||
export async function createStudentHandler(
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
await createUserHandler<Student>(req, res, new StudentService(), Student);
|
||||
res: Response,
|
||||
) {
|
||||
const userData = req.body as StudentDTO;
|
||||
|
||||
if (!userData.username || !userData.firstName || !userData.lastName) {
|
||||
res.status(400).json({
|
||||
error: 'Missing required fields: username, firstName, lastName',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const newUser = await createStudent(userData);
|
||||
res.status(201).json(newUser);
|
||||
}
|
||||
|
||||
export async function deleteStudentHandler(
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
await deleteUserHandler<Student>(req, res, new StudentService());
|
||||
res: Response,
|
||||
) {
|
||||
const username = req.params.username;
|
||||
|
||||
if (!username) {
|
||||
res.status(400).json({ error: 'Missing required field: username' });
|
||||
return;
|
||||
}
|
||||
|
||||
const deletedUser = await deleteStudent(username);
|
||||
if (!deletedUser) {
|
||||
res.status(404).json({
|
||||
error: `User with username '${username}' not found.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(200).json(deletedUser);
|
||||
}
|
||||
|
||||
export async function getStudentClassesHandler(
|
||||
|
@ -115,3 +172,7 @@ export async function getStudentSubmissionsHandler(
|
|||
submissions: submissions,
|
||||
});
|
||||
}
|
||||
function getAllStudents(): StudentDTO[] | string[] | PromiseLike<StudentDTO[] | string[]> {
|
||||
throw new Error('Function not implemented.');
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ export async function getSubmissionHandler(
|
|||
}
|
||||
|
||||
let lang = languageMap[req.query.language as string] || Language.Dutch;
|
||||
let version = req.query.version as string || '1';
|
||||
let version = (req.query.version || 1) as number;
|
||||
|
||||
const submission = await getSubmission(lohruid, lang, version, submissionNumber);
|
||||
|
||||
|
@ -49,7 +49,7 @@ export async function deleteSubmissionHandler(req: Request, res: Response){
|
|||
const submissionNumber = +req.params.id;
|
||||
|
||||
let lang = languageMap[req.query.language as string] || Language.Dutch;
|
||||
let version = req.query.version as string || '1';
|
||||
let version = (req.query.version || 1) as number;
|
||||
|
||||
const submission = await deleteSubmission(hruid, lang, version, submissionNumber);
|
||||
|
||||
|
|
|
@ -1,49 +1,96 @@
|
|||
import { Request, Response } from 'express';
|
||||
import { TeacherUserService, TeacherService } from '../services/teachers.js';
|
||||
import { createTeacher, deleteTeacher, getAllTeachers, getClassesByTeacher, getClassIdsByTeacher, getQuestionIdsByTeacher, getQuestionsByTeacher, getStudentIdsByTeacher, getStudentsByTeacher, getTeacher } from '../services/teachers.js';
|
||||
import { ClassDTO } from '../interfaces/class.js';
|
||||
import { StudentDTO } from '../interfaces/student.js';
|
||||
import { QuestionDTO, QuestionId } from '../interfaces/question.js';
|
||||
import {
|
||||
createUserHandler,
|
||||
deleteUserHandler,
|
||||
getAllUsersHandler,
|
||||
getUserHandler,
|
||||
} from './users.js';
|
||||
import { Teacher } from '../entities/users/teacher.entity.js';
|
||||
import { TeacherDTO } from '../interfaces/teacher.js';
|
||||
import { getTeacherRepository } from '../data/repositories.js';
|
||||
|
||||
export async function getAllTeachersHandler(
|
||||
req: Request,
|
||||
res: Response
|
||||
res: Response,
|
||||
): Promise<void> {
|
||||
await getAllUsersHandler<Teacher>(req, res, new TeacherUserService());
|
||||
const full = req.query.full === 'true';
|
||||
|
||||
const teacherRepository = getTeacherRepository();
|
||||
|
||||
const teachers: TeacherDTO[] | string[] = full
|
||||
? await getAllTeachers()
|
||||
: await getAllTeachers();
|
||||
|
||||
if (!teachers) {
|
||||
res.status(404).json({ error: `Teacher not found.` });
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(201).json(teachers);
|
||||
}
|
||||
|
||||
|
||||
export async function getTeacherHandler(
|
||||
req: Request,
|
||||
res: Response
|
||||
res: Response,
|
||||
): Promise<void> {
|
||||
await getUserHandler<Teacher>(req, res, new TeacherUserService());
|
||||
const username = req.params.username;
|
||||
|
||||
if (!username) {
|
||||
res.status(400).json({ error: 'Missing required field: username' });
|
||||
return;
|
||||
}
|
||||
|
||||
const user = await getTeacher(username);
|
||||
|
||||
if (!user) {
|
||||
res.status(404).json({
|
||||
error: `User with username '${username}' not found.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(201).json(user);
|
||||
}
|
||||
|
||||
export async function createTeacherHandler(
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
await createUserHandler<Teacher>(
|
||||
req,
|
||||
res,
|
||||
new TeacherUserService(),
|
||||
Teacher
|
||||
);
|
||||
res: Response,
|
||||
) {
|
||||
const userData = req.body as TeacherDTO;
|
||||
|
||||
if (!userData.username || !userData.firstName || !userData.lastName) {
|
||||
res.status(400).json({
|
||||
error: 'Missing required fields: username, firstName, lastName',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const newUser = await createTeacher(userData);
|
||||
res.status(201).json(newUser);
|
||||
}
|
||||
|
||||
export async function deleteTeacherHandler(
|
||||
req: Request,
|
||||
res: Response
|
||||
): Promise<void> {
|
||||
await deleteUserHandler<Teacher>(req, res, new TeacherUserService());
|
||||
res: Response,
|
||||
) {
|
||||
const username = req.params.username;
|
||||
|
||||
if (!username) {
|
||||
res.status(400).json({ error: 'Missing required field: username' });
|
||||
return;
|
||||
}
|
||||
|
||||
const deletedUser = await deleteTeacher(username);
|
||||
if (!deletedUser) {
|
||||
res.status(404).json({
|
||||
error: `User with username '${username}' not found.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
res.status(200).json(deletedUser);
|
||||
}
|
||||
|
||||
|
||||
export async function getTeacherClassHandler(
|
||||
req: Request,
|
||||
res: Response
|
||||
|
@ -57,11 +104,9 @@ export async function getTeacherClassHandler(
|
|||
return;
|
||||
}
|
||||
|
||||
const teacherService = new TeacherService();
|
||||
|
||||
const classes: ClassDTO[] | string[] = full
|
||||
? await teacherService.getClassesByTeacher(username)
|
||||
: await teacherService.getClassIdsByTeacher(username);
|
||||
? await getClassesByTeacher(username)
|
||||
: await getClassIdsByTeacher(username);
|
||||
|
||||
res.status(201).json(classes);
|
||||
} catch (error) {
|
||||
|
@ -83,11 +128,9 @@ export async function getTeacherStudentHandler(
|
|||
return;
|
||||
}
|
||||
|
||||
const teacherService = new TeacherService();
|
||||
|
||||
const students: StudentDTO[] | string[] = full
|
||||
? await teacherService.getStudentsByTeacher(username)
|
||||
: await teacherService.getStudentIdsByTeacher(username);
|
||||
? await getStudentsByTeacher(username)
|
||||
: await getStudentIdsByTeacher(username);
|
||||
|
||||
res.status(201).json(students);
|
||||
} catch (error) {
|
||||
|
@ -109,11 +152,9 @@ export async function getTeacherQuestionHandler(
|
|||
return;
|
||||
}
|
||||
|
||||
const teacherService = new TeacherService();
|
||||
|
||||
const questions: QuestionDTO[] | QuestionId[] = full
|
||||
? await teacherService.getQuestionsByTeacher(username)
|
||||
: await teacherService.getQuestionIdsByTeacher(username);
|
||||
? await getQuestionsByTeacher(username)
|
||||
: await getQuestionIdsByTeacher(username);
|
||||
|
||||
res.status(201).json(questions);
|
||||
} catch (error) {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { Request, Response } from 'express';
|
||||
import { themes } from '../data/themes.js';
|
||||
import { loadTranslations } from '../util/translationHelper.js';
|
||||
import { loadTranslations } from '../util/translation-helper.js';
|
||||
|
||||
interface Translations {
|
||||
curricula_page: {
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
|
||||
import { LearningObject } from '../../entities/content/learning-object.entity.js';
|
||||
import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js';
|
||||
import { Language } from '../../entities/content/language.js';
|
||||
import { Teacher } from '../../entities/users/teacher.entity.js';
|
||||
|
||||
export class LearningObjectRepository extends DwengoEntityRepository<LearningObject> {
|
||||
public findByIdentifier(identifier: LearningObjectIdentifier): Promise<LearningObject | null> {
|
||||
|
@ -30,4 +32,11 @@ export class LearningObjectRepository extends DwengoEntityRepository<LearningObj
|
|||
}
|
||||
);
|
||||
}
|
||||
|
||||
public findAllByTeacher(teacher: Teacher): Promise<LearningObject[]> {
|
||||
return this.find(
|
||||
{ admins: teacher },
|
||||
{ populate: ['admins'] } // Make sure to load admin relations
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@ import { DwengoEntityRepository } from '../dwengo-entity-repository.js';
|
|||
import { Question } from '../../entities/questions/question.entity.js';
|
||||
import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js';
|
||||
import { Student } from '../../entities/users/student.entity.js';
|
||||
import { LearningObject } from '../../entities/content/learning-object.entity.js';
|
||||
|
||||
export class QuestionRepository extends DwengoEntityRepository<Question> {
|
||||
public createQuestion(question: { loId: LearningObjectIdentifier; author: Student; content: string }): Promise<Question> {
|
||||
|
|
|
@ -56,7 +56,6 @@ function repositoryGetter<T extends AnyEntity, R extends EntityRepository<T>>(
|
|||
}
|
||||
|
||||
/* Users */
|
||||
export const getUserRepository = repositoryGetter<User, UserRepository>(User);
|
||||
export const getStudentRepository = repositoryGetter<Student, StudentRepository>(Student);
|
||||
export const getTeacherRepository = repositoryGetter<Teacher, TeacherRepository>(Teacher);
|
||||
|
||||
|
|
|
@ -51,5 +51,5 @@ export class Assignment {
|
|||
},
|
||||
mappedBy: 'assignment',
|
||||
})
|
||||
groups!: Collection<Group>;
|
||||
groups!: Group[];
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { Collection, Entity, ManyToMany, ManyToOne, PrimaryKey } from '@mikro-orm/core';
|
||||
import { Assignment } from './assignment.entity.js';
|
||||
import { Student } from '../users/student.entity.js';
|
||||
import { GroupRepository } from '../../data/assignments/group-repository.js';
|
||||
|
||||
@Entity({
|
||||
repository: () => {
|
||||
|
|
|
@ -8,6 +8,7 @@ import {
|
|||
import { v4 } from 'uuid';
|
||||
import { Teacher } from '../users/teacher.entity.js';
|
||||
import { Student } from '../users/student.entity.js';
|
||||
import { ClassRepository } from '../../data/classes/class-repository.js';
|
||||
|
||||
@Entity({
|
||||
repository: () => {
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import { Entity, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core';
|
||||
import { LearningObject } from './learning-object.entity.js';
|
||||
import { AttachmentRepository } from '../../data/content/attachment-repository.js';
|
||||
|
||||
@Entity({
|
||||
repository: () => {
|
||||
|
|
|
@ -189,5 +189,5 @@ export const languageMap: Record<string, Language> = {
|
|||
nl: Language.Dutch,
|
||||
fr: Language.French,
|
||||
en: Language.English,
|
||||
de: Language.Germany,
|
||||
de: Language.German,
|
||||
};
|
|
@ -17,7 +17,7 @@ export function mapToAnswerDTO(answer: Answer): AnswerDTO {
|
|||
return {
|
||||
author: mapToUserDTO(answer.author),
|
||||
toQuestion: mapToQuestionDTO(answer.toQuestion),
|
||||
sequenceNumber: answer.sequenceNumber,
|
||||
sequenceNumber: answer.sequenceNumber!,
|
||||
timestamp: answer.timestamp.toISOString(),
|
||||
content: answer.content,
|
||||
};
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
import { Question } from '../entities/questions/question.entity.js';
|
||||
import {UserDTO} from "./user.js";
|
||||
import {LearningObjectIdentifier} from "../entities/content/learning-object-identifier.js";
|
||||
import { mapToStudentDTO, StudentDTO } from './student.js';
|
||||
import { TeacherDTO } from './teacher.js';
|
||||
|
||||
export interface QuestionDTO {
|
||||
learningObjectIdentifier: LearningObjectIdentifier;
|
||||
sequenceNumber?: number;
|
||||
author: UserDTO;
|
||||
author: StudentDTO;
|
||||
timestamp?: string;
|
||||
content: string;
|
||||
}
|
||||
|
@ -23,7 +25,7 @@ export function mapToQuestionDTO(question: Question): QuestionDTO {
|
|||
return {
|
||||
learningObjectIdentifier,
|
||||
sequenceNumber: question.sequenceNumber!,
|
||||
author: question.author,
|
||||
author: mapToStudentDTO(question.author),
|
||||
timestamp: question.timestamp.toISOString(),
|
||||
content: question.content,
|
||||
};
|
||||
|
|
|
@ -23,10 +23,11 @@ export function mapToStudentDTO(student: Student): StudentDTO {
|
|||
}
|
||||
|
||||
export function mapToStudent(studentData: StudentDTO): Student {
|
||||
const student = new Student();
|
||||
student.username = studentData.username;
|
||||
student.firstName = studentData.firstName;
|
||||
student.lastName = studentData.lastName;
|
||||
const student = new Student(
|
||||
studentData.username,
|
||||
studentData.firstName,
|
||||
studentData.lastName,
|
||||
);
|
||||
|
||||
return student;
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ import {Student} from "../entities/users/student.entity";
|
|||
export interface SubmissionDTO {
|
||||
learningObjectHruid: string,
|
||||
learningObjectLanguage: Language,
|
||||
learningObjectVersion: string,
|
||||
learningObjectVersion: number,
|
||||
|
||||
submissionNumber?: number,
|
||||
submitter: StudentDTO,
|
||||
|
|
33
backend/src/interfaces/teacher.ts
Normal file
33
backend/src/interfaces/teacher.ts
Normal file
|
@ -0,0 +1,33 @@
|
|||
import { Teacher } from '../entities/users/teacher.entity.js';
|
||||
|
||||
export interface TeacherDTO {
|
||||
id: string;
|
||||
username: string;
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
endpoints?: {
|
||||
classes: string;
|
||||
questions: string;
|
||||
invitations: string;
|
||||
groups: string;
|
||||
};
|
||||
}
|
||||
|
||||
export function mapToTeacherDTO(teacher: Teacher): TeacherDTO {
|
||||
return {
|
||||
id: teacher.username,
|
||||
username: teacher.username,
|
||||
firstName: teacher.firstName,
|
||||
lastName: teacher.lastName,
|
||||
};
|
||||
}
|
||||
|
||||
export function mapToTeacher(TeacherData: TeacherDTO): Teacher {
|
||||
const teacher = new Teacher(
|
||||
TeacherData.username,
|
||||
TeacherData.firstName,
|
||||
TeacherData.lastName,
|
||||
);
|
||||
|
||||
return teacher;
|
||||
}
|
|
@ -1,7 +1,9 @@
|
|||
import express from 'express';
|
||||
import {
|
||||
getAllLearningObjects,
|
||||
getAttachment,
|
||||
getLearningObject,
|
||||
getLearningObjectHTML,
|
||||
} from '../controllers/learning-objects.js';
|
||||
|
||||
import submissionRoutes from './submissions.js';
|
||||
|
|
|
@ -5,8 +5,7 @@ import {
|
|||
LearningObjectMetadata,
|
||||
LearningObjectNode,
|
||||
LearningPathResponse,
|
||||
} from '../interfaces/learning-path.js';
|
||||
import { fetchLearningPaths } from './learning-paths.js';
|
||||
} from '../interfaces/learning-content.js';
|
||||
|
||||
function filterData(
|
||||
data: LearningObjectMetadata,
|
||||
|
@ -132,3 +131,7 @@ export async function getLearningObjectIdsFromPath(
|
|||
): Promise<string[]> {
|
||||
return (await fetchLearningObjects(hruid, false, language)) as string[];
|
||||
}
|
||||
function fetchLearningPaths(arg0: string[], language: string, arg2: string): LearningPathResponse | PromiseLike<LearningPathResponse> {
|
||||
throw new Error('Function not implemented.');
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { DWENGO_API_BASE } from '../../config.js';
|
||||
import { fetchWithLogging } from '../../util/apiHelper.js';
|
||||
import { fetchWithLogging } from '../../util/api-helper.js';
|
||||
import {
|
||||
FilteredLearningObject,
|
||||
LearningObjectIdentifier,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { fetchWithLogging } from '../../util/apiHelper.js';
|
||||
import { fetchWithLogging } from '../../util/api-helper.js';
|
||||
import { DWENGO_API_BASE } from '../../config.js';
|
||||
import { LearningPath, LearningPathResponse } from '../../interfaces/learning-content.js';
|
||||
import { LearningPathProvider } from './learning-path-provider.js';
|
||||
|
|
|
@ -7,6 +7,7 @@ import {QuestionRepository} from "../data/questions/question-repository.js";
|
|||
import {LearningObjectIdentifier} from "../entities/content/learning-object-identifier.js";
|
||||
import {mapToUser} from "../interfaces/user.js";
|
||||
import {Student} from "../entities/users/student.entity.js";
|
||||
import { mapToStudent } from "../interfaces/student.js";
|
||||
|
||||
export async function getAllQuestions(
|
||||
id: LearningObjectIdentifier, full: boolean
|
||||
|
@ -72,7 +73,7 @@ export async function getAnswersByQuestion(questionId: QuestionId, full: boolean
|
|||
export async function createQuestion(questionDTO: QuestionDTO) {
|
||||
const questionRepository = getQuestionRepository();
|
||||
|
||||
const author = mapToUser<Student>(questionDTO.author, new Student())
|
||||
const author = mapToStudent(questionDTO.author);
|
||||
|
||||
try {
|
||||
await questionRepository.createQuestion({
|
||||
|
|
|
@ -9,13 +9,61 @@ import { Student } from '../entities/users/student.entity.js';
|
|||
import { AssignmentDTO } from '../interfaces/assignment.js';
|
||||
import { ClassDTO, mapToClassDTO } from '../interfaces/class.js';
|
||||
import { GroupDTO, mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js';
|
||||
import { mapToStudent, mapToStudentDTO, StudentDTO } from '../interfaces/student.js';
|
||||
import { mapToSubmissionDTO, SubmissionDTO } from '../interfaces/submission.js';
|
||||
import { getAllAssignments } from './assignments.js';
|
||||
import { UserService } from './users.js';
|
||||
|
||||
export class StudentService extends UserService<Student> {
|
||||
constructor() {
|
||||
super(getStudentRepository());
|
||||
|
||||
export async function getAllStudents(): Promise<StudentDTO[]> {
|
||||
const studentRepository = getStudentRepository();
|
||||
const users = await studentRepository.findAll();
|
||||
return users.map(mapToStudentDTO);
|
||||
}
|
||||
|
||||
export async function getAllStudentIds(): Promise<string[]> {
|
||||
const users = await getAllStudents();
|
||||
return users.map((user) => {
|
||||
return user.username;
|
||||
});
|
||||
}
|
||||
|
||||
export async function getStudent(username: string): Promise<StudentDTO | null> {
|
||||
const studentRepository = getStudentRepository();
|
||||
const user = await studentRepository.findByUsername(username);
|
||||
return user ? mapToStudentDTO(user) : null;
|
||||
}
|
||||
|
||||
export async function createStudent(userData: StudentDTO): Promise<StudentDTO | null> {
|
||||
const studentRepository = getStudentRepository();
|
||||
|
||||
try {
|
||||
const newStudent = studentRepository.create(mapToStudent(userData));
|
||||
await studentRepository.save(newStudent);
|
||||
|
||||
return mapToStudentDTO(newStudent);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function deleteStudent(username: string): Promise<StudentDTO | null> {
|
||||
const studentRepository = getStudentRepository();
|
||||
|
||||
const user = await studentRepository.findByUsername(username);
|
||||
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
await studentRepository.deleteByUsername(username);
|
||||
|
||||
return mapToStudentDTO(user);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import {mapToSubmission, mapToSubmissionDTO, SubmissionDTO} from "../interfaces/
|
|||
export async function getSubmission(
|
||||
learningObjectHruid: string,
|
||||
language: Language,
|
||||
version: string,
|
||||
version: number,
|
||||
submissionNumber: number,
|
||||
): Promise<SubmissionDTO | null> {
|
||||
const loId = new LearningObjectIdentifier(learningObjectHruid, language, version);
|
||||
|
@ -38,7 +38,7 @@ export async function createSubmission(submissionDTO: SubmissionDTO) {
|
|||
export async function deleteSubmission(
|
||||
learningObjectHruid: string,
|
||||
language: Language,
|
||||
version: string,
|
||||
version: number,
|
||||
submissionNumber: number
|
||||
) {
|
||||
const submissionRepository = getSubmissionRepository();
|
||||
|
|
|
@ -17,43 +17,85 @@ import {
|
|||
} from '../interfaces/question.js';
|
||||
import { UserService } from './users.js';
|
||||
import { mapToUser } from '../interfaces/user.js';
|
||||
import { mapToTeacher, mapToTeacherDTO, TeacherDTO } from '../interfaces/teacher.js';
|
||||
|
||||
export class TeacherUserService extends UserService<Teacher> {
|
||||
constructor() {
|
||||
super(getTeacherRepository());
|
||||
export async function getAllTeachers(): Promise<TeacherDTO[]> {
|
||||
const teacherRepository = getTeacherRepository();
|
||||
const users = await teacherRepository.findAll();
|
||||
return users.map(mapToTeacherDTO);
|
||||
}
|
||||
|
||||
export async function getAllTeacherIds(): Promise<string[]> {
|
||||
const users = await getAllTeachers();
|
||||
return users.map((user) => {
|
||||
return user.username;
|
||||
});
|
||||
}
|
||||
|
||||
export async function getTeacher(username: string): Promise<TeacherDTO | null> {
|
||||
const teacherRepository = getTeacherRepository();
|
||||
const user = await teacherRepository.findByUsername(username);
|
||||
return user ? mapToTeacherDTO(user) : null;
|
||||
}
|
||||
|
||||
export async function createTeacher(userData: TeacherDTO): Promise<TeacherDTO | null> {
|
||||
const teacherRepository = getTeacherRepository();
|
||||
|
||||
try {
|
||||
const newTeacher = teacherRepository.create(mapToTeacher(userData));
|
||||
await teacherRepository.save(newTeacher);
|
||||
|
||||
return mapToTeacherDTO(newTeacher);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export class TeacherService {
|
||||
protected teacherService = new TeacherUserService();
|
||||
protected teacherRepository = getTeacherRepository();
|
||||
protected classRepository = getClassRepository();
|
||||
protected learningObjectRepository = getLearningObjectRepository();
|
||||
protected questionRepository = getQuestionRepository();
|
||||
export async function deleteTeacher(username: string): Promise<TeacherDTO | null> {
|
||||
const teacherRepository = getTeacherRepository();
|
||||
|
||||
async fetchClassesByTeacher(username: string): Promise<ClassDTO[]> {
|
||||
const teacher = await this.teacherRepository.findByUsername(username);
|
||||
const user = await teacherRepository.findByUsername(username);
|
||||
|
||||
if (!user) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
await teacherRepository.deleteByUsername(username);
|
||||
|
||||
return mapToTeacherDTO(user);
|
||||
} catch(e) {
|
||||
console.log(e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
export async function fetchClassesByTeacher(username: string): Promise<ClassDTO[]> {
|
||||
const teacherRepository = getTeacherRepository();
|
||||
const teacher = await teacherRepository.findByUsername(username);
|
||||
if (!teacher) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const classes = await this.classRepository.findByTeacher(teacher);
|
||||
const classRepository = getClassRepository();
|
||||
const classes = await classRepository.findByTeacher(teacher);
|
||||
return classes.map(mapToClassDTO);
|
||||
}
|
||||
}
|
||||
|
||||
async getClassesByTeacher(username: string): Promise<ClassDTO[]> {
|
||||
return await this.fetchClassesByTeacher(username);
|
||||
}
|
||||
export async function getClassesByTeacher(username: string): Promise<ClassDTO[]> {
|
||||
return await fetchClassesByTeacher(username);
|
||||
}
|
||||
|
||||
async getClassIdsByTeacher(username: string): Promise<string[]> {
|
||||
const classes = await this.fetchClassesByTeacher(username);
|
||||
export async function getClassIdsByTeacher(username: string): Promise<string[]> {
|
||||
const classes = await fetchClassesByTeacher(username);
|
||||
return classes.map((cls) => {
|
||||
return cls.id;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async fetchStudentsByTeacher(username: string) {
|
||||
const classes = await this.getClassIdsByTeacher(username);
|
||||
export async function fetchStudentsByTeacher(username: string) {
|
||||
const classes = await getClassIdsByTeacher(username);
|
||||
|
||||
return (
|
||||
await Promise.all(
|
||||
|
@ -62,48 +104,46 @@ export class TeacherService {
|
|||
})
|
||||
)
|
||||
).flat();
|
||||
}
|
||||
}
|
||||
|
||||
async getStudentsByTeacher(username: string): Promise<StudentDTO[]> {
|
||||
return await this.fetchStudentsByTeacher(username);
|
||||
}
|
||||
export async function getStudentsByTeacher(username: string): Promise<StudentDTO[]> {
|
||||
return await fetchStudentsByTeacher(username);
|
||||
}
|
||||
|
||||
async getStudentIdsByTeacher(username: string): Promise<string[]> {
|
||||
const students = await this.fetchStudentsByTeacher(username);
|
||||
export async function getStudentIdsByTeacher(username: string): Promise<string[]> {
|
||||
const students = await fetchStudentsByTeacher(username);
|
||||
return students.map((student) => {
|
||||
return student.username;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async fetchTeacherQuestions(username: string): Promise<QuestionDTO[]> {
|
||||
const teacherDTO =
|
||||
await this.teacherService.getUserByUsername(username);
|
||||
if (!teacherDTO) {
|
||||
export async function fetchTeacherQuestions(username: string): Promise<QuestionDTO[]> {
|
||||
const teacherRepository = getTeacherRepository();
|
||||
const teacher = await teacherRepository.findByUsername(username);
|
||||
if (!teacher) {
|
||||
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);
|
||||
const learningObjectRepository = getLearningObjectRepository();
|
||||
const learningObjects = await learningObjectRepository.findAllByTeacher(teacher);
|
||||
|
||||
// Fetch all questions related to these learning objects
|
||||
const questionRepository = getQuestionRepository();
|
||||
const questions =
|
||||
await this.questionRepository.findAllByLearningObjects(
|
||||
await questionRepository.findAllByLearningObjects(
|
||||
learningObjects
|
||||
);
|
||||
|
||||
return questions.map(mapToQuestionDTO);
|
||||
}
|
||||
}
|
||||
|
||||
async getQuestionsByTeacher(username: string): Promise<QuestionDTO[]> {
|
||||
return await this.fetchTeacherQuestions(username);
|
||||
}
|
||||
export async function getQuestionsByTeacher(username: string): Promise<QuestionDTO[]> {
|
||||
return await fetchTeacherQuestions(username);
|
||||
}
|
||||
|
||||
async getQuestionIdsByTeacher(username: string): Promise<QuestionId[]> {
|
||||
const questions = await this.fetchTeacherQuestions(username);
|
||||
export async function getQuestionIdsByTeacher(username: string): Promise<QuestionId[]> {
|
||||
const questions = await fetchTeacherQuestions(username);
|
||||
|
||||
return questions.map(mapToQuestionId);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ describe('SubmissionRepository', () => {
|
|||
});
|
||||
|
||||
it('should find the requested submission', async () => {
|
||||
const id = new LearningObjectIdentifier('id03', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id03', Language.English, 1);
|
||||
const submission = await submissionRepository.findSubmissionByLearningObjectAndSubmissionNumber(id, 1);
|
||||
|
||||
expect(submission).toBeTruthy();
|
||||
|
@ -40,7 +40,7 @@ describe('SubmissionRepository', () => {
|
|||
});
|
||||
|
||||
it('should find the most recent submission for a student', async () => {
|
||||
const id = new LearningObjectIdentifier('id02', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id02', Language.English, 1);
|
||||
const student = await studentRepository.findByUsername('Noordkaap');
|
||||
const submission = await submissionRepository.findMostRecentSubmissionForStudent(id, student!);
|
||||
|
||||
|
@ -49,7 +49,7 @@ describe('SubmissionRepository', () => {
|
|||
});
|
||||
|
||||
it('should find the most recent submission for a group', async () => {
|
||||
const id = new LearningObjectIdentifier('id03', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id03', Language.English, 1);
|
||||
const class_ = await classRepository.findById('id01');
|
||||
const assignment = await assignmentRepository.findByClassAndId(class_!, 1);
|
||||
const group = await groupRepository.findByAssignmentAndGroupNumber(assignment!, 1);
|
||||
|
@ -60,7 +60,7 @@ describe('SubmissionRepository', () => {
|
|||
});
|
||||
|
||||
it('should not find a deleted submission', async () => {
|
||||
const id = new LearningObjectIdentifier('id01', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id01', Language.English, 1);
|
||||
await submissionRepository.deleteSubmissionByLearningObjectAndSubmissionNumber(id, 1);
|
||||
|
||||
const submission = await submissionRepository.findSubmissionByLearningObjectAndSubmissionNumber(id, 1);
|
||||
|
|
|
@ -17,11 +17,11 @@ describe('AttachmentRepository', () => {
|
|||
});
|
||||
|
||||
it('should return the requested attachment', async () => {
|
||||
const id = new LearningObjectIdentifier('id02', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id02', Language.English, 1);
|
||||
const learningObject = await learningObjectRepository.findByIdentifier(id);
|
||||
|
||||
const attachment = await attachmentRepository.findByMostRecentVersionOfLearningObjectAndName(
|
||||
learningObject!,
|
||||
learningObject!.hruid,
|
||||
Language.English,
|
||||
'attachment01'
|
||||
);
|
||||
|
|
|
@ -13,8 +13,8 @@ describe('LearningObjectRepository', () => {
|
|||
learningObjectRepository = getLearningObjectRepository();
|
||||
});
|
||||
|
||||
const id01 = new LearningObjectIdentifier('id01', Language.English, '1');
|
||||
const id02 = new LearningObjectIdentifier('test_id', Language.English, '1');
|
||||
const id01 = new LearningObjectIdentifier('id01', Language.English, 1);
|
||||
const id02 = new LearningObjectIdentifier('test_id', Language.English, 1);
|
||||
|
||||
it('should return the learning object that matches identifier 1', async () => {
|
||||
const learningObject = await learningObjectRepository.findByIdentifier(id01);
|
||||
|
|
|
@ -20,7 +20,7 @@ describe('AnswerRepository', () => {
|
|||
});
|
||||
|
||||
it('should find all answers to a question', async () => {
|
||||
const id = new LearningObjectIdentifier('id05', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id05', Language.English, 1);
|
||||
const questions = await questionRepository.findAllQuestionsAboutLearningObject(id);
|
||||
|
||||
const question = questions.filter((it) => it.sequenceNumber == 2)[0];
|
||||
|
@ -35,7 +35,7 @@ describe('AnswerRepository', () => {
|
|||
|
||||
it('should create an answer to a question', async () => {
|
||||
const teacher = await teacherRepository.findByUsername('FooFighters');
|
||||
const id = new LearningObjectIdentifier('id05', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id05', Language.English, 1);
|
||||
const questions = await questionRepository.findAllQuestionsAboutLearningObject(id);
|
||||
|
||||
const question = questions[0];
|
||||
|
@ -54,7 +54,7 @@ describe('AnswerRepository', () => {
|
|||
});
|
||||
|
||||
it('should not find a removed answer', async () => {
|
||||
const id = new LearningObjectIdentifier('id04', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id04', Language.English, 1);
|
||||
const questions = await questionRepository.findAllQuestionsAboutLearningObject(id);
|
||||
|
||||
await answerRepository.removeAnswerByQuestionAndSequenceNumber(questions[0], 1);
|
||||
|
|
|
@ -20,7 +20,7 @@ describe('QuestionRepository', () => {
|
|||
});
|
||||
|
||||
it('should return all questions part of the given learning object', async () => {
|
||||
const id = new LearningObjectIdentifier('id05', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id05', Language.English, 1);
|
||||
const questions = await questionRepository.findAllQuestionsAboutLearningObject(id);
|
||||
|
||||
expect(questions).toBeTruthy();
|
||||
|
@ -28,7 +28,7 @@ describe('QuestionRepository', () => {
|
|||
});
|
||||
|
||||
it('should create new question', async () => {
|
||||
const id = new LearningObjectIdentifier('id03', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id03', Language.English, 1);
|
||||
const student = await studentRepository.findByUsername('Noordkaap');
|
||||
await questionRepository.createQuestion({
|
||||
loId: id,
|
||||
|
@ -42,7 +42,7 @@ describe('QuestionRepository', () => {
|
|||
});
|
||||
|
||||
it('should not find removed question', async () => {
|
||||
const id = new LearningObjectIdentifier('id04', Language.English, '1');
|
||||
const id = new LearningObjectIdentifier('id04', Language.English, 1);
|
||||
await questionRepository.removeQuestionByLearningObjectAndSequenceNumber(id, 1);
|
||||
|
||||
const question = await questionRepository.findAllQuestionsAboutLearningObject(id);
|
||||
|
|
|
@ -12,7 +12,7 @@ export function makeTestSubmissions(
|
|||
const submission01 = em.create(Submission, {
|
||||
learningObjectHruid: 'id03',
|
||||
learningObjectLanguage: Language.English,
|
||||
learningObjectVersion: '1',
|
||||
learningObjectVersion: 1,
|
||||
submissionNumber: 1,
|
||||
submitter: students[0],
|
||||
submissionTime: new Date(2025, 2, 20),
|
||||
|
@ -23,7 +23,7 @@ export function makeTestSubmissions(
|
|||
const submission02 = em.create(Submission, {
|
||||
learningObjectHruid: 'id03',
|
||||
learningObjectLanguage: Language.English,
|
||||
learningObjectVersion: '1',
|
||||
learningObjectVersion: 1,
|
||||
submissionNumber: 2,
|
||||
submitter: students[0],
|
||||
submissionTime: new Date(2025, 2, 25),
|
||||
|
@ -34,7 +34,7 @@ export function makeTestSubmissions(
|
|||
const submission03 = em.create(Submission, {
|
||||
learningObjectHruid: 'id02',
|
||||
learningObjectLanguage: Language.English,
|
||||
learningObjectVersion: '1',
|
||||
learningObjectVersion: 1,
|
||||
submissionNumber: 1,
|
||||
submitter: students[0],
|
||||
submissionTime: new Date(2025, 2, 20),
|
||||
|
@ -44,7 +44,7 @@ export function makeTestSubmissions(
|
|||
const submission04 = em.create(Submission, {
|
||||
learningObjectHruid: 'id02',
|
||||
learningObjectLanguage: Language.English,
|
||||
learningObjectVersion: '1',
|
||||
learningObjectVersion: 1,
|
||||
submissionNumber: 2,
|
||||
submitter: students[0],
|
||||
submissionTime: new Date(2025, 2, 25),
|
||||
|
@ -54,7 +54,7 @@ export function makeTestSubmissions(
|
|||
const submission05 = em.create(Submission, {
|
||||
learningObjectHruid: 'id01',
|
||||
learningObjectLanguage: Language.English,
|
||||
learningObjectVersion: '1',
|
||||
learningObjectVersion: 1,
|
||||
submissionNumber: 1,
|
||||
submitter: students[1],
|
||||
submissionTime: new Date(2025, 2, 20),
|
||||
|
|
|
@ -77,7 +77,7 @@ export function makeTestLearningPaths(em: EntityManager<IDatabaseDriver<Connecti
|
|||
admins: [],
|
||||
title: 'repertoire Tool',
|
||||
description: 'all about Tool',
|
||||
image: '',
|
||||
image: null,
|
||||
nodes: nodes01,
|
||||
});
|
||||
|
||||
|
@ -92,7 +92,7 @@ export function makeTestLearningPaths(em: EntityManager<IDatabaseDriver<Connecti
|
|||
admins: [],
|
||||
title: 'repertoire Dire Straits',
|
||||
description: 'all about Dire Straits',
|
||||
image: '',
|
||||
image: null,
|
||||
nodes: nodes02,
|
||||
});
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ import { Student } from '../../../src/entities/users/student.entity';
|
|||
export function makeTestQuestions(em: EntityManager<IDatabaseDriver<Connection>>, students: Array<Student>): Array<Question> {
|
||||
const question01 = em.create(Question, {
|
||||
learningObjectLanguage: Language.English,
|
||||
learningObjectVersion: '1',
|
||||
learningObjectVersion: 1,
|
||||
learningObjectHruid: 'id05',
|
||||
sequenceNumber: 1,
|
||||
author: students[0],
|
||||
|
@ -16,7 +16,7 @@ export function makeTestQuestions(em: EntityManager<IDatabaseDriver<Connection>>
|
|||
|
||||
const question02 = em.create(Question, {
|
||||
learningObjectLanguage: Language.English,
|
||||
learningObjectVersion: '1',
|
||||
learningObjectVersion: 1,
|
||||
learningObjectHruid: 'id05',
|
||||
sequenceNumber: 2,
|
||||
author: students[2],
|
||||
|
@ -26,7 +26,7 @@ export function makeTestQuestions(em: EntityManager<IDatabaseDriver<Connection>>
|
|||
|
||||
const question03 = em.create(Question, {
|
||||
learningObjectLanguage: Language.English,
|
||||
learningObjectVersion: '1',
|
||||
learningObjectVersion: 1,
|
||||
learningObjectHruid: 'id04',
|
||||
sequenceNumber: 1,
|
||||
author: students[0],
|
||||
|
@ -36,7 +36,7 @@ export function makeTestQuestions(em: EntityManager<IDatabaseDriver<Connection>>
|
|||
|
||||
const question04 = em.create(Question, {
|
||||
learningObjectLanguage: Language.English,
|
||||
learningObjectVersion: '1',
|
||||
learningObjectVersion: 1,
|
||||
learningObjectHruid: 'id01',
|
||||
sequenceNumber: 1,
|
||||
author: students[1],
|
||||
|
|
9330
package-lock.json
generated
Normal file
9330
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue