Merge branch 'feat/service-layer' into feat/service-layer-adriaan

# Conflicts:
#	backend/src/controllers/classes.ts
#	backend/src/controllers/students.ts
#	backend/src/data/users/teacher-repository.ts
#	backend/src/interfaces/assignment.ts
#	backend/src/interfaces/teacher.ts
#	backend/src/routes/classes.ts
#	backend/src/services/assignments.ts
#	backend/src/services/class.ts
#	backend/src/services/students.ts
#	backend/src/util/translation-helper.ts
This commit is contained in:
Gabriellvl 2025-03-09 22:30:15 +01:00
commit 6c4ea0eefb
33 changed files with 454 additions and 137 deletions

View file

@ -1,7 +1,7 @@
import { getClassRepository, getTeacherInvitationRepository } from "../data/repositories.js";
import { ClassDTO, mapToClassDTO } from "../interfaces/classes.js";
import { mapToStudentDTO, StudentDTO } from "../interfaces/students.js";
import { mapToTeacherInvitationDTO, mapToTeacherInvitationDTOIds, TeacherInvitationDTO } from "../interfaces/teacher-invitation.js";
import { getClassRepository } from "../data/repositories";
import { Class } from "../entities/classes/class.entity";
import { ClassDTO, mapToClassDTO } from "../interfaces/class";
import { mapToStudentDTO, StudentDTO } from "../interfaces/student";
export async function getAllClasses(full: boolean): Promise<ClassDTO[] | string[]> {
const classRepository = getClassRepository();
@ -28,41 +28,21 @@ export async function getClass(classId: string): Promise<ClassDTO | null> {
}
}
export async function getClassStudents(classId: string, full: boolean): Promise<StudentDTO[] | string[]> {
async function fetchClassStudents(classId: string, full: boolean): Promise<StudentDTO[] | string[]> {
const classRepository = getClassRepository();
const cls = await classRepository.findById(classId);
if (!cls) {
if (!cls)
return [];
}
if (full) {
return cls.students.map(mapToStudentDTO);
} else {
return cls.students.map((student) => student.username);
}
return cls.students.map(mapToStudentDTO);
}
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);
export async function getClassStudents(classId: string): Promise<StudentDTO[]> {
return await fetchClassStudents(classId);
}
export async function getClassStudentsIds(classId: string): Promise<string[]> {
return await fetchClassStudents(classId).map((student) => student.username);
}

View file

@ -1,12 +1,12 @@
import { DWENGO_API_BASE } from '../config.js';
import { fetchWithLogging } from '../util/apiHelper.js';
import { fetchWithLogging } from '../util/api-helper.js';
import {
FilteredLearningObject,
LearningObjectMetadata,
LearningObjectNode,
LearningPathResponse,
} from '../interfaces/learningPath.js';
import { fetchLearningPaths } from './learningPaths.js';
} from '../interfaces/learning-path.js';
import { fetchLearningPaths } from './learning-paths.js';
function filterData(
data: LearningObjectMetadata,

View file

@ -1,9 +1,9 @@
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/learningPath.js';
} from '../interfaces/learning-path.js';
export async function fetchLearningPaths(
hruids: string[],

View file

@ -0,0 +1,131 @@
import {
getClassRepository,
getLearningObjectRepository,
getQuestionRepository,
getTeacherRepository
} from "../data/repositories.js";
import {mapToTeacher, mapToTeacherDTO, TeacherDTO} from "../interfaces/teacher.js";
import { Teacher } from "../entities/users/teacher.entity";
import {ClassDTO, mapToClassDTO} from "../interfaces/class";
import {getClassStudents, getClassStudentsIds} from "./class";
import {StudentDTO} from "../interfaces/student";
import {mapToQuestionDTO, QuestionDTO, QuestionId} from "../interfaces/question";
async function fetchAllTeachers(): Promise<TeacherDTO[]> {
const teacherRepository = getTeacherRepository();
const teachers = await teacherRepository.find({});
return teachers.map(mapToTeacherDTO);
}
export async function getAllTeachers(): Promise<TeacherDTO[]> {
return await fetchAllTeachers();
}
export async function getAllTeachersIds(): Promise<string[]> {
return await fetchAllTeachers().map((teacher) => teacher.username)
}
export async function createTeacher(teacherData: TeacherDTO): Promise<Teacher> {
const teacherRepository = getTeacherRepository();
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);
return classes.map(mapToClassDTO);
}
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
const learningObjects = await learningObjectRepository.findAllByTeacher(teacher);
// Fetch all questions related to these learning objects
const questions = await questionRepository.findAllByLearningObjects(learningObjects);
return questions.map(mapToQuestionDTO);
}
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
}));
}