Merge branch 'dev' into refactor/linting

This commit is contained in:
Tibo De Peuter 2025-03-30 11:27:59 +02:00
commit f9b59af2fd
Signed by: tdpeuter
GPG key ID: 38297DE43F75FFE2
22 changed files with 256 additions and 344 deletions

View file

@ -1,7 +1,7 @@
import { getAssignmentRepository, getClassRepository, getGroupRepository, getSubmissionRepository } from '../data/repositories.js';
import { Assignment } from '../entities/assignments/assignment.entity.js';
import { AssignmentDTO, mapToAssignment, mapToAssignmentDTO, mapToAssignmentDTOId } from '../interfaces/assignment.js';
import { mapToSubmissionDTO, SubmissionDTO } from '../interfaces/submission.js';
import { mapToSubmissionDTO, mapToSubmissionDTOId, SubmissionDTO, SubmissionDTOId } from '../interfaces/submission.js';
import { getLogger } from '../logging/initalize.js';
export async function getAllAssignments(classid: string, full: boolean): Promise<AssignmentDTO[]> {
const classRepository = getClassRepository();
@ -21,7 +21,7 @@ export async function getAllAssignments(classid: string, full: boolean): Promise
return assignments.map(mapToAssignmentDTOId);
}
export async function createAssignment(classid: string, assignmentData: AssignmentDTO): Promise<Assignment | null> {
export async function createAssignment(classid: string, assignmentData: AssignmentDTO): Promise<AssignmentDTO | null> {
const classRepository = getClassRepository();
const cls = await classRepository.findById(classid);
@ -36,8 +36,9 @@ export async function createAssignment(classid: string, assignmentData: Assignme
const newAssignment = assignmentRepository.create(assignment);
await assignmentRepository.save(newAssignment);
return newAssignment;
} catch (_) {
return mapToAssignmentDTO(newAssignment);
} catch (e) {
getLogger().error(e);
return null;
}
}
@ -60,7 +61,11 @@ export async function getAssignment(classid: string, id: number): Promise<Assign
return mapToAssignmentDTO(assignment);
}
export async function getAssignmentsSubmissions(classid: string, assignmentNumber: number): Promise<SubmissionDTO[]> {
export async function getAssignmentsSubmissions(
classid: string,
assignmentNumber: number,
full: boolean
): Promise<SubmissionDTO[] | SubmissionDTOId[]> {
const classRepository = getClassRepository();
const cls = await classRepository.findById(classid);
@ -81,5 +86,9 @@ export async function getAssignmentsSubmissions(classid: string, assignmentNumbe
const submissionRepository = getSubmissionRepository();
const submissions = (await Promise.all(groups.map(async (group) => submissionRepository.findAllSubmissionsForGroup(group)))).flat();
return submissions.map(mapToSubmissionDTO);
if (full) {
return submissions.map(mapToSubmissionDTO);
}
return submissions.map(mapToSubmissionDTOId);
}

View file

@ -1,5 +1,4 @@
import { getClassRepository, getStudentRepository, getTeacherInvitationRepository, getTeacherRepository } from '../data/repositories.js';
import { Class } from '../entities/classes/class.entity.js';
import { ClassDTO, mapToClassDTO } from '../interfaces/class.js';
import { mapToStudentDTO, StudentDTO } from '../interfaces/student.js';
import { mapToTeacherInvitationDTO, mapToTeacherInvitationDTOIds, TeacherInvitationDTO } from '../interfaces/teacher-invitation.js';
@ -21,7 +20,7 @@ export async function getAllClasses(full: boolean): Promise<ClassDTO[] | string[
return classes.map((cls) => cls.classId!);
}
export async function createClass(classData: ClassDTO): Promise<Class | null> {
export async function createClass(classData: ClassDTO): Promise<ClassDTO | null> {
const teacherRepository = getTeacherRepository();
const teacherUsernames = classData.teachers || [];
const teachers = (await Promise.all(teacherUsernames.map(async (id) => teacherRepository.findByUsername(id)))).filter(
@ -34,8 +33,6 @@ export async function createClass(classData: ClassDTO): Promise<Class | null> {
(student) => student !== null
);
//Const cls = mapToClass(classData, teachers, students);
const classRepository = getClassRepository();
try {
@ -46,7 +43,7 @@ export async function createClass(classData: ClassDTO): Promise<Class | null> {
});
await classRepository.save(newClass);
return newClass;
return mapToClassDTO(newClass);
} catch (e) {
logger.error(e);
return null;

View file

@ -7,7 +7,7 @@ import {
} from '../data/repositories.js';
import { Group } from '../entities/assignments/group.entity.js';
import { GroupDTO, mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js';
import { mapToSubmissionDTO, SubmissionDTO } from '../interfaces/submission.js';
import { mapToSubmissionDTO, mapToSubmissionDTOId, SubmissionDTO, SubmissionDTOId } from '../interfaces/submission.js';
import { getLogger } from '../logging/initalize.js';
export async function getGroup(classId: string, assignmentNumber: number, groupNumber: number, full: boolean): Promise<GroupDTO | null> {
@ -104,7 +104,12 @@ export async function getAllGroups(classId: string, assignmentNumber: number, fu
return groups.map(mapToGroupDTOId);
}
export async function getGroupSubmissions(classId: string, assignmentNumber: number, groupNumber: number): Promise<SubmissionDTO[]> {
export async function getGroupSubmissions(
classId: string,
assignmentNumber: number,
groupNumber: number,
full: boolean
): Promise<SubmissionDTO[] | SubmissionDTOId[]> {
const classRepository = getClassRepository();
const cls = await classRepository.findById(classId);
@ -129,5 +134,9 @@ export async function getGroupSubmissions(classId: string, assignmentNumber: num
const submissionRepository = getSubmissionRepository();
const submissions = await submissionRepository.findAllSubmissionsForGroup(group);
return submissions.map(mapToSubmissionDTO);
if (full) {
return submissions.map(mapToSubmissionDTO);
}
return submissions.map(mapToSubmissionDTOId);
}

View file

@ -46,6 +46,13 @@ export async function getLearningObjectById(hruid: string, language: string): Pr
return filterData(metadata, htmlUrl);
}
/**
* Generic function to fetch learning paths
*/
function fetchLearningPaths(_arg0: string[], _language: string, _arg2: string): LearningPathResponse | PromiseLike<LearningPathResponse> {
throw new Error('Function not implemented.');
}
/**
* Generic function to fetch learning objects (full data or just HRUIDs)
*/
@ -86,6 +93,3 @@ export async function getLearningObjectsFromPath(hruid: string, language: string
export async function getLearningObjectIdsFromPath(hruid: string, language: string): 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.');
}

View file

@ -86,7 +86,7 @@ export async function createQuestion(questionDTO: QuestionDTO): Promise<Question
return questionDTO;
}
export async function deleteQuestion(questionId: QuestionId): Promise<Question | null> {
export async function deleteQuestion(questionId: QuestionId): Promise<QuestionDTO | null> {
const questionRepository = getQuestionRepository();
const question = await fetchQuestion(questionId);
@ -101,5 +101,5 @@ export async function deleteQuestion(questionId: QuestionId): Promise<Question |
return null;
}
return question;
return mapToQuestionDTO(question);
}

View file

@ -1,21 +1,26 @@
import { getClassRepository, getGroupRepository, getStudentRepository, getSubmissionRepository } from '../data/repositories.js';
import {
getClassRepository,
getGroupRepository,
getStudentRepository,
getSubmissionRepository,
} from '../data/repositories.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 { mapToSubmissionDTO, mapToSubmissionDTOId, SubmissionDTO, SubmissionDTOId } from '../interfaces/submission.js';
import { getAllAssignments } from './assignments.js';
import { getLogger } from '../logging/initalize.js';
export async function getAllStudents(): Promise<StudentDTO[]> {
export async function getAllStudents(full: boolean): Promise<StudentDTO[] | string[]> {
const studentRepository = getStudentRepository();
const users = await studentRepository.findAll();
return users.map(mapToStudentDTO);
}
const students = await studentRepository.findAll();
export async function getAllStudentIds(): Promise<string[]> {
const users = await getAllStudents();
return users.map((user) => user.username);
if (full) {
return students.map(mapToStudentDTO);
}
return students.map((student) => student.username);
}
export async function getStudent(username: string): Promise<StudentDTO | null> {
@ -86,9 +91,7 @@ export async function getStudentAssignments(username: string, full: boolean): Pr
const classRepository = getClassRepository();
const classes = await classRepository.findByStudent(student);
const assignments = (await Promise.all(classes.map(async (cls) => await getAllAssignments(cls.classId!, full)))).flat();
return assignments;
return (await Promise.all(classes.map(async (cls) => await getAllAssignments(cls.classId!, full)))).flat();
}
export async function getStudentGroups(username: string, full: boolean): Promise<GroupDTO[]> {
@ -109,7 +112,7 @@ export async function getStudentGroups(username: string, full: boolean): Promise
return groups.map(mapToGroupDTOId);
}
export async function getStudentSubmissions(username: string): Promise<SubmissionDTO[]> {
export async function getStudentSubmissions(username: string, full: boolean): Promise<SubmissionDTO[] | SubmissionDTOId[]> {
const studentRepository = getStudentRepository();
const student = await studentRepository.findByUsername(username);
@ -120,5 +123,9 @@ export async function getStudentSubmissions(username: string): Promise<Submissio
const submissionRepository = getSubmissionRepository();
const submissions = await submissionRepository.findAllSubmissionsForStudent(student);
return submissions.map(mapToSubmissionDTO);
if (full) {
return submissions.map(mapToSubmissionDTO);
}
return submissions.map(mapToSubmissionDTOId);
}

View file

@ -2,7 +2,6 @@ import { getSubmissionRepository } from '../data/repositories.js';
import { Language } from '../entities/content/language.js';
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
import { mapToSubmission, mapToSubmissionDTO, SubmissionDTO } from '../interfaces/submission.js';
import { Submission } from '../entities/assignments/submission.entity.js';
export async function getSubmission(
learningObjectHruid: string,
@ -22,7 +21,7 @@ export async function getSubmission(
return mapToSubmissionDTO(submission);
}
export async function createSubmission(submissionDTO: SubmissionDTO): Promise<Submission | null> {
export async function createSubmission(submissionDTO: SubmissionDTO): Promise<SubmissionDTO | null> {
const submissionRepository = getSubmissionRepository();
const submission = mapToSubmission(submissionDTO);
@ -33,7 +32,7 @@ export async function createSubmission(submissionDTO: SubmissionDTO): Promise<Su
return null;
}
return submission;
return mapToSubmissionDTO(submission);
}
export async function deleteSubmission(

View file

@ -1,20 +1,25 @@
import { getClassRepository, getLearningObjectRepository, getQuestionRepository, getTeacherRepository } from '../data/repositories.js';
import {
getClassRepository,
getLearningObjectRepository,
getQuestionRepository,
getTeacherRepository,
} from '../data/repositories.js';
import { ClassDTO, mapToClassDTO } from '../interfaces/class.js';
import { getClassStudents } from './class.js';
import { getClassStudents } from './classes.js';
import { StudentDTO } from '../interfaces/student.js';
import { mapToQuestionDTO, mapToQuestionId, QuestionDTO, QuestionId } from '../interfaces/question.js';
import { mapToTeacher, mapToTeacherDTO, TeacherDTO } from '../interfaces/teacher.js';
import { getLogger } from '../logging/initalize.js';
export async function getAllTeachers(): Promise<TeacherDTO[]> {
export async function getAllTeachers(full: boolean): Promise<TeacherDTO[] | string[]> {
const teacherRepository = getTeacherRepository();
const users = await teacherRepository.findAll();
return users.map(mapToTeacherDTO);
}
const teachers = await teacherRepository.findAll();
export async function getAllTeacherIds(): Promise<string[]> {
const users = await getAllTeachers();
return users.map((user) => user.username);
if (full) {
return teachers.map(mapToTeacherDTO);
}
return teachers.map((teacher) => teacher.username);
}
export async function getTeacher(username: string): Promise<TeacherDTO | null> {
@ -56,11 +61,11 @@ export async function deleteTeacher(username: string): Promise<TeacherDTO | null
}
}
export async function fetchClassesByTeacher(username: string): Promise<ClassDTO[]> {
export async function fetchClassesByTeacher(username: string): Promise<ClassDTO[] | null> {
const teacherRepository = getTeacherRepository();
const teacher = await teacherRepository.findByUsername(username);
if (!teacher) {
return [];
return null;
}
const classRepository = getClassRepository();
@ -68,35 +73,49 @@ export async function fetchClassesByTeacher(username: string): Promise<ClassDTO[
return classes.map(mapToClassDTO);
}
export async function getClassesByTeacher(username: string): Promise<ClassDTO[]> {
return await fetchClassesByTeacher(username);
}
export async function getClassIdsByTeacher(username: string): Promise<string[]> {
export async function getClassesByTeacher(username: string, full: boolean): Promise<ClassDTO[] | string[] | null> {
const classes = await fetchClassesByTeacher(username);
if (!classes) {
return null;
}
if (full) {
return classes;
}
return classes.map((cls) => cls.id);
}
export async function fetchStudentsByTeacher(username: string): Promise<StudentDTO[]> {
const classes = await getClassIdsByTeacher(username);
export async function fetchStudentsByTeacher(username: string): Promise<StudentDTO[] | null> {
const classes = (await getClassesByTeacher(username, false)) as string[];
if (!classes) {
return null;
}
return (await Promise.all(classes.map(async (id) => getClassStudents(id)))).flat();
}
export async function getStudentsByTeacher(username: string): Promise<StudentDTO[]> {
return await fetchStudentsByTeacher(username);
}
export async function getStudentIdsByTeacher(username: string): Promise<string[]> {
export async function getStudentsByTeacher(username: string, full: boolean): Promise<StudentDTO[] | string[] | null> {
const students = await fetchStudentsByTeacher(username);
if (!students) {
return null;
}
if (full) {
return students;
}
return students.map((student) => student.username);
}
export async function fetchTeacherQuestions(username: string): Promise<QuestionDTO[]> {
export async function fetchTeacherQuestions(username: string): Promise<QuestionDTO[] | null> {
const teacherRepository = getTeacherRepository();
const teacher = await teacherRepository.findByUsername(username);
if (!teacher) {
throw new Error(`Teacher with username '${username}' not found.`);
return null;
}
// Find all learning objects that this teacher manages
@ -110,12 +129,16 @@ export async function fetchTeacherQuestions(username: string): Promise<QuestionD
return questions.map(mapToQuestionDTO);
}
export async function getQuestionsByTeacher(username: string): Promise<QuestionDTO[]> {
return await fetchTeacherQuestions(username);
}
export async function getQuestionIdsByTeacher(username: string): Promise<QuestionId[]> {
export async function getQuestionsByTeacher(username: string, full: boolean): Promise<QuestionDTO[] | QuestionId[] | null> {
const questions = await fetchTeacherQuestions(username);
if (!questions) {
return null;
}
if (full) {
return questions;
}
return questions.map(mapToQuestionId);
}

View file

@ -1,41 +0,0 @@
import { UserRepository } from '../data/users/user-repository.js';
import { UserDTO, mapToUser, mapToUserDTO } from '../interfaces/user.js';
import { User } from '../entities/users/user.entity.js';
export class UserService<T extends User> {
protected repository: UserRepository<T>;
constructor(repository: UserRepository<T>) {
this.repository = repository;
}
async getAllUsers(): Promise<UserDTO[]> {
const users = await this.repository.findAll();
return users.map(mapToUserDTO);
}
async getAllUserIds(): Promise<string[]> {
const users = await this.getAllUsers();
return users.map((user) => user.username);
}
async getUserByUsername(username: string): Promise<UserDTO | null> {
const user = await this.repository.findByUsername(username);
return user ? mapToUserDTO(user) : null;
}
async createUser(userData: UserDTO, userClass: new () => T): Promise<T> {
const newUser = mapToUser(userData, new userClass());
await this.repository.save(newUser);
return newUser;
}
async deleteUser(username: string): Promise<UserDTO | null> {
const user = await this.getUserByUsername(username);
if (!user) {
return null;
}
await this.repository.deleteByUsername(username);
return mapToUserDTO(user);
}
}