Merge remote-tracking branch 'origin/refactor/common' into feat/user-routes-test-interface-refactor
# Conflicts: # backend/src/controllers/students.ts # backend/src/controllers/teachers.ts # backend/src/interfaces/answer.ts # backend/src/interfaces/question.ts # backend/src/interfaces/student.ts # backend/src/services/classes.ts # backend/src/services/questions.ts # backend/src/services/students.ts # backend/src/services/teachers.ts
This commit is contained in:
commit
4ca568e738
57 changed files with 270 additions and 190 deletions
|
@ -1,11 +1,14 @@
|
||||||
FROM node:22 AS build-stage
|
FROM node:22
|
||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app/dwengo
|
||||||
|
|
||||||
|
COPY ./backend/i18n ./i18n
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
|
|
||||||
COPY package*.json ./
|
COPY package*.json ./
|
||||||
COPY backend/package.json ./backend/
|
COPY backend/package.json ./backend/
|
||||||
|
COPY common/package.json ./common/
|
||||||
|
|
||||||
RUN npm install --silent
|
RUN npm install --silent
|
||||||
|
|
||||||
|
@ -14,25 +17,13 @@ RUN npm install --silent
|
||||||
# Root tsconfig.json
|
# Root tsconfig.json
|
||||||
COPY tsconfig.json ./
|
COPY tsconfig.json ./
|
||||||
|
|
||||||
WORKDIR /app/backend
|
COPY backend ./backend
|
||||||
|
COPY common ./common
|
||||||
|
COPY docs ./docs
|
||||||
|
|
||||||
COPY backend ./
|
RUN npm run build --workspace=common
|
||||||
COPY docs /app/docs
|
RUN npm run build --workspace=backend
|
||||||
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
FROM node:22 AS production-stage
|
|
||||||
|
|
||||||
WORKDIR /app
|
|
||||||
|
|
||||||
COPY package-lock.json backend/package.json ./
|
|
||||||
|
|
||||||
RUN npm install --silent --only=production
|
|
||||||
|
|
||||||
COPY ./docs /docs
|
|
||||||
COPY ./backend/i18n /app/i18n
|
|
||||||
COPY --from=build-stage /app/backend/dist ./dist/
|
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
CMD ["node", "--env-file=.env", "dist/app.js"]
|
CMD ["node", "--env-file=/app/dwengo/backend/.env", "/app/dwengo/backend/dist/app.js"]
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
"cross": "^1.0.0",
|
"cross": "^1.0.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
|
"dwengo-1-common": "^0.1.1",
|
||||||
"express": "^5.0.1",
|
"express": "^5.0.1",
|
||||||
"express-jwt": "^8.5.1",
|
"express-jwt": "^8.5.1",
|
||||||
"gift-pegjs": "^1.0.2",
|
"gift-pegjs": "^1.0.2",
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { createAssignment, getAllAssignments, getAssignment, getAssignmentsSubmissions } from '../services/assignments.js';
|
import { createAssignment, getAllAssignments, getAssignment, getAssignmentsSubmissions } from '../services/assignments.js';
|
||||||
import { AssignmentDTO } from '../interfaces/assignment.js';
|
|
||||||
|
import { AssignmentDTO } from 'dwengo-1-common/src/interfaces/assignment';
|
||||||
|
|
||||||
// Typescript is annoying with parameter forwarding from class.ts
|
// Typescript is annoying with parameter forwarding from class.ts
|
||||||
interface AssignmentParams {
|
interface AssignmentParams {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { createClass, getAllClasses, getClass, getClassStudents, getClassStudentsIds, getClassTeacherInvitations } from '../services/classes.js';
|
import { createClass, getAllClasses, getClass, getClassStudents, getClassStudentsIds, getClassTeacherInvitations } from '../services/classes.js';
|
||||||
import { ClassDTO } from '../interfaces/class.js';
|
|
||||||
|
import { ClassDTO } from 'dwengo-1-common/src/interfaces/class';
|
||||||
|
|
||||||
export async function getAllClassesHandler(req: Request, res: Response): Promise<void> {
|
export async function getAllClassesHandler(req: Request, res: Response): Promise<void> {
|
||||||
const full = req.query.full === 'true';
|
const full = req.query.full === 'true';
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { createGroup, getAllGroups, getGroup, getGroupSubmissions } from '../services/groups.js';
|
import { createGroup, getAllGroups, getGroup, getGroupSubmissions } from '../services/groups.js';
|
||||||
import { GroupDTO } from '../interfaces/group.js';
|
|
||||||
|
import { GroupDTO } from 'dwengo-1-common/src/interfaces/group';
|
||||||
|
|
||||||
// Typescript is annoywith with parameter forwarding from class.ts
|
// Typescript is annoywith with parameter forwarding from class.ts
|
||||||
interface GroupParams {
|
interface GroupParams {
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { FALLBACK_LANG } from '../config.js';
|
import { FALLBACK_LANG } from '../config.js';
|
||||||
import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../interfaces/learning-content.js';
|
|
||||||
import learningObjectService from '../services/learning-objects/learning-object-service.js';
|
import learningObjectService from '../services/learning-objects/learning-object-service.js';
|
||||||
import { envVars, getEnvVar } from '../util/envVars.js';
|
import { envVars, getEnvVar } from '../util/envVars.js';
|
||||||
import { Language } from '../entities/content/language.js';
|
import { Language } from '../entities/content/language.js';
|
||||||
import attachmentService from '../services/learning-objects/attachment-service.js';
|
import attachmentService from '../services/learning-objects/attachment-service.js';
|
||||||
import { NotFoundError } from '@mikro-orm/core';
|
import { NotFoundError } from '@mikro-orm/core';
|
||||||
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
import { BadRequestException } from '../exceptions/bad-request-exception.js';
|
||||||
|
import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
function getLearningObjectIdentifierFromRequest(req: Request): LearningObjectIdentifier {
|
function getLearningObjectIdentifierFromRequest(req: Request): LearningObjectIdentifier {
|
||||||
if (!req.params.hruid) {
|
if (!req.params.hruid) {
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { createQuestion, deleteQuestion, getAllQuestions, getAnswersByQuestion, getQuestion } from '../services/questions.js';
|
import { createQuestion, deleteQuestion, getAllQuestions, getAnswersByQuestion, getQuestion } from '../services/questions.js';
|
||||||
import { QuestionDTO, QuestionId } from '../interfaces/question.js';
|
|
||||||
import { FALLBACK_LANG, FALLBACK_SEQ_NUM } from '../config.js';
|
import { FALLBACK_LANG, FALLBACK_SEQ_NUM } from '../config.js';
|
||||||
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
|
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
|
||||||
import { Language } from '../entities/content/language.js';
|
import { Language } from '../entities/content/language.js';
|
||||||
|
import { QuestionDTO, QuestionId } from 'dwengo-1-common/src/interfaces/question';
|
||||||
|
|
||||||
function getObjectId(req: Request, res: Response): LearningObjectIdentifier | null {
|
function getObjectId(req: Request, res: Response): LearningObjectIdentifier | null {
|
||||||
const { hruid, version } = req.params;
|
const { hruid, version } = req.params;
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { Request, Response } from 'express';
|
import { Request, Response } from 'express';
|
||||||
import { createSubmission, deleteSubmission, getSubmission } from '../services/submissions.js';
|
import { createSubmission, deleteSubmission, getSubmission } from '../services/submissions.js';
|
||||||
import { Language, languageMap } from '../entities/content/language.js';
|
import { Language, languageMap } from '../entities/content/language.js';
|
||||||
import { SubmissionDTO } from '../interfaces/submission';
|
|
||||||
|
import { SubmissionDTO } from 'dwengo-1-common/src/interfaces/submission';
|
||||||
|
|
||||||
interface SubmissionParams {
|
interface SubmissionParams {
|
||||||
hruid: string;
|
hruid: string;
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import { Embedded, Entity, Enum, ManyToMany, OneToMany, PrimaryKey, Property } from '@mikro-orm/core';
|
import { Embedded, Entity, Enum, ManyToMany, OneToMany, PrimaryKey, Property } from '@mikro-orm/core';
|
||||||
import { Language } from './language.js';
|
|
||||||
import { Attachment } from './attachment.entity.js';
|
import { Attachment } from './attachment.entity.js';
|
||||||
import { Teacher } from '../users/teacher.entity.js';
|
import { Teacher } from '../users/teacher.entity.js';
|
||||||
import { DwengoContentType } from '../../services/learning-objects/processing/content-type.js';
|
import { DwengoContentType } from '../../services/learning-objects/processing/content-type.js';
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { LearningObjectRepository } from '../../data/content/learning-object-repository.js';
|
import { LearningObjectRepository } from '../../data/content/learning-object-repository.js';
|
||||||
import { EducationalGoal } from './educational-goal.entity.js';
|
import { EducationalGoal } from './educational-goal.entity.js';
|
||||||
|
import { Language } from './language.js';
|
||||||
import { ReturnValue } from './return-value.entity.js';
|
import { ReturnValue } from './return-value.entity.js';
|
||||||
|
|
||||||
@Entity({ repository: () => LearningObjectRepository })
|
@Entity({ repository: () => LearningObjectRepository })
|
||||||
|
|
|
@ -1,14 +1,7 @@
|
||||||
import { mapToUserDTO, UserDTO } from './user.js';
|
import { mapToUserDTO } from './user.js';
|
||||||
import {mapToQuestionDTO, mapToQuestionDTOId, QuestionDTO, QuestionId} from './question.js';
|
import { mapToQuestionDTO, mapToQuestionDTOId } from './question.js';
|
||||||
import { Answer } from '../entities/questions/answer.entity.js';
|
import { Answer } from '../entities/questions/answer.entity.js';
|
||||||
|
import { AnswerDTO, AnswerId } from 'dwengo-1-common/src/interfaces/answer';
|
||||||
export interface AnswerDTO {
|
|
||||||
author: UserDTO;
|
|
||||||
toQuestion: QuestionDTO;
|
|
||||||
sequenceNumber: number;
|
|
||||||
timestamp: string;
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a Question entity to a DTO format.
|
* Convert a Question entity to a DTO format.
|
||||||
|
@ -23,16 +16,10 @@ export function mapToAnswerDTO(answer: Answer): AnswerDTO {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AnswerId {
|
export function mapToAnswerId(answer: AnswerDTO): AnswerId {
|
||||||
author: string;
|
|
||||||
toQuestion: QuestionId;
|
|
||||||
sequenceNumber: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToAnswerDTOId(answer: Answer): AnswerId {
|
|
||||||
return {
|
return {
|
||||||
author: answer.author.username,
|
author: answer.author.username,
|
||||||
toQuestion: mapToQuestionDTOId(answer.toQuestion),
|
toQuestion: mapToQuestionDTOId(answer.toQuestion),
|
||||||
sequenceNumber: answer.sequenceNumber!,
|
sequenceNumber: answer.sequenceNumber,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,19 +1,9 @@
|
||||||
import { FALLBACK_LANG } from '../config.js';
|
import { FALLBACK_LANG } from '../config.js';
|
||||||
import { Assignment } from '../entities/assignments/assignment.entity.js';
|
import { Assignment } from '../entities/assignments/assignment.entity.js';
|
||||||
import { Class } from '../entities/classes/class.entity.js';
|
import { Class } from '../entities/classes/class.entity.js';
|
||||||
import { languageMap } from '../entities/content/language.js';
|
|
||||||
import { GroupDTO } from './group.js';
|
|
||||||
import { getLogger } from '../logging/initalize.js';
|
import { getLogger } from '../logging/initalize.js';
|
||||||
|
import { languageMap } from '../entities/content/language.js';
|
||||||
export interface AssignmentDTO {
|
import { AssignmentDTO } from 'dwengo-1-common/src/interfaces/assignment';
|
||||||
id: number;
|
|
||||||
class: string; // Id of class 'within'
|
|
||||||
title: string;
|
|
||||||
description: string;
|
|
||||||
learningPath: string;
|
|
||||||
language: string;
|
|
||||||
groups?: GroupDTO[] | string[]; // TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToAssignmentDTOId(assignment: Assignment): AssignmentDTO {
|
export function mapToAssignmentDTOId(assignment: Assignment): AssignmentDTO {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -2,14 +2,7 @@ import { Collection } from '@mikro-orm/core';
|
||||||
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.js';
|
import { Teacher } from '../entities/users/teacher.entity.js';
|
||||||
|
import { ClassDTO } from 'dwengo-1-common/src/interfaces/class';
|
||||||
export interface ClassDTO {
|
|
||||||
id: string;
|
|
||||||
displayName: string;
|
|
||||||
teachers: string[];
|
|
||||||
students: string[];
|
|
||||||
joinRequests: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToClassDTO(cls: Class): ClassDTO {
|
export function mapToClassDTO(cls: Class): ClassDTO {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
import { Group } from '../entities/assignments/group.entity.js';
|
import { Group } from '../entities/assignments/group.entity.js';
|
||||||
import { AssignmentDTO, mapToAssignmentDTO } from './assignment.js';
|
import { mapToAssignmentDTO } from './assignment.js';
|
||||||
import { mapToStudentDTO, StudentDTO } from './student.js';
|
import { mapToStudentDTO } from './student.js';
|
||||||
|
import { GroupDTO } from 'dwengo-1-common/src/interfaces/group';
|
||||||
export interface GroupDTO {
|
|
||||||
assignment: number | AssignmentDTO;
|
|
||||||
groupNumber: number;
|
|
||||||
members: string[] | StudentDTO[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToGroupDTO(group: Group): GroupDTO {
|
export function mapToGroupDTO(group: Group): GroupDTO {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,14 +1,6 @@
|
||||||
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 { mapToStudentDTO } from './student.js';
|
||||||
import { mapToStudentDTO, StudentDTO } from './student.js';
|
import { QuestionDTO, QuestionId } from 'dwengo-1-common/src/interfaces/question';
|
||||||
|
|
||||||
export interface QuestionDTO {
|
|
||||||
learningObjectIdentifier: LearningObjectIdentifier;
|
|
||||||
sequenceNumber?: number;
|
|
||||||
author: StudentDTO;
|
|
||||||
timestamp?: string;
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
function getLearningObjectIdentifier(question: Question): LearningObjectIdentifier {
|
function getLearningObjectIdentifier(question: Question): LearningObjectIdentifier {
|
||||||
return {
|
return {
|
||||||
|
@ -33,11 +25,6 @@ export function mapToQuestionDTO(question: Question): QuestionDTO {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface QuestionId {
|
|
||||||
learningObjectIdentifier: LearningObjectIdentifier;
|
|
||||||
sequenceNumber: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToQuestionDTOId(question: Question): QuestionId {
|
export function mapToQuestionDTOId(question: Question): QuestionId {
|
||||||
const learningObjectIdentifier = getLearningObjectIdentifier(question);
|
const learningObjectIdentifier = getLearningObjectIdentifier(question);
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,6 @@
|
||||||
import { Student } from '../entities/users/student.entity.js';
|
import { Student } from '../entities/users/student.entity.js';
|
||||||
import { getStudentRepository } from '../data/repositories.js';
|
import { getStudentRepository } from '../data/repositories.js';
|
||||||
|
import { StudentDTO } from 'dwengo-1-common/src/interfaces/student';
|
||||||
export interface StudentDTO {
|
|
||||||
id: string;
|
|
||||||
username: string;
|
|
||||||
firstName: string;
|
|
||||||
lastName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToStudentDTO(student: Student): StudentDTO {
|
export function mapToStudentDTO(student: Student): StudentDTO {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,26 +1,7 @@
|
||||||
import { Submission } from '../entities/assignments/submission.entity.js';
|
import { Submission } from '../entities/assignments/submission.entity.js';
|
||||||
import { Language } from '../entities/content/language.js';
|
import { mapToGroupDTO } from './group.js';
|
||||||
import { GroupDTO, mapToGroupDTO } from './group.js';
|
import { mapToStudent, mapToStudentDTO } from './student.js';
|
||||||
import { mapToStudent, mapToStudentDTO, StudentDTO } from './student.js';
|
import { SubmissionDTO, SubmissionDTOId } from 'dwengo-1-common/src/interfaces/submission';
|
||||||
import { LearningObjectIdentifier } from './learning-content.js';
|
|
||||||
|
|
||||||
export interface SubmissionDTO {
|
|
||||||
learningObjectIdentifier: LearningObjectIdentifier;
|
|
||||||
|
|
||||||
submissionNumber?: number;
|
|
||||||
submitter: StudentDTO;
|
|
||||||
time?: Date;
|
|
||||||
group?: GroupDTO;
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface SubmissionDTOId {
|
|
||||||
learningObjectHruid: string;
|
|
||||||
learningObjectLanguage: Language;
|
|
||||||
learningObjectVersion: number;
|
|
||||||
|
|
||||||
submissionNumber?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToSubmissionDTO(submission: Submission): SubmissionDTO {
|
export function mapToSubmissionDTO(submission: Submission): SubmissionDTO {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,12 +1,7 @@
|
||||||
import { TeacherInvitation } from '../entities/classes/teacher-invitation.entity.js';
|
import { TeacherInvitation } from '../entities/classes/teacher-invitation.entity.js';
|
||||||
import { ClassDTO, mapToClassDTO } from './class.js';
|
import { mapToClassDTO } from './class.js';
|
||||||
import { mapToUserDTO, UserDTO } from './user.js';
|
import { mapToUserDTO } from './user.js';
|
||||||
|
import { TeacherInvitationDTO } from 'dwengo-1-common/src/interfaces/teacher-invitation';
|
||||||
export interface TeacherInvitationDTO {
|
|
||||||
sender: string | UserDTO;
|
|
||||||
receiver: string | UserDTO;
|
|
||||||
class: string | ClassDTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToTeacherInvitationDTO(invitation: TeacherInvitation): TeacherInvitationDTO {
|
export function mapToTeacherInvitationDTO(invitation: TeacherInvitation): TeacherInvitationDTO {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,18 +1,6 @@
|
||||||
import { Teacher } from '../entities/users/teacher.entity.js';
|
import { Teacher } from '../entities/users/teacher.entity.js';
|
||||||
import { getTeacherRepository } from '../data/repositories.js';
|
import { getTeacherRepository } from '../data/repositories.js';
|
||||||
|
import { TeacherDTO } from 'dwengo-1-common/src/interfaces/teacher';
|
||||||
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 {
|
export function mapToTeacherDTO(teacher: Teacher): TeacherDTO {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,17 +1,5 @@
|
||||||
import { User } from '../entities/users/user.entity.js';
|
import { User } from '../entities/users/user.entity.js';
|
||||||
|
import { UserDTO } from 'dwengo-1-common/src/interfaces/user';
|
||||||
export interface UserDTO {
|
|
||||||
id?: string;
|
|
||||||
username: string;
|
|
||||||
firstName: string;
|
|
||||||
lastName: string;
|
|
||||||
endpoints?: {
|
|
||||||
self: string;
|
|
||||||
classes: string;
|
|
||||||
questions: string;
|
|
||||||
invitations: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
export function mapToUserDTO(user: User): UserDTO {
|
export function mapToUserDTO(user: User): UserDTO {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { getAssignmentRepository, getClassRepository, getGroupRepository, getSubmissionRepository } from '../data/repositories.js';
|
import { getAssignmentRepository, getClassRepository, getGroupRepository, getSubmissionRepository } from '../data/repositories.js';
|
||||||
import { AssignmentDTO, mapToAssignment, mapToAssignmentDTO, mapToAssignmentDTOId } from '../interfaces/assignment.js';
|
import { mapToAssignment, mapToAssignmentDTO, mapToAssignmentDTOId } from '../interfaces/assignment.js';
|
||||||
import { mapToSubmissionDTO, mapToSubmissionDTOId, SubmissionDTO, SubmissionDTOId } from '../interfaces/submission.js';
|
import { mapToSubmissionDTO, mapToSubmissionDTOId } from '../interfaces/submission.js';
|
||||||
|
import { AssignmentDTO } from 'dwengo-1-common/src/interfaces/assignment';
|
||||||
|
import { SubmissionDTO, SubmissionDTOId } from 'dwengo-1-common/src/interfaces/submission';
|
||||||
import { getLogger } from '../logging/initalize.js';
|
import { getLogger } from '../logging/initalize.js';
|
||||||
|
|
||||||
export async function getAllAssignments(classid: string, full: boolean): Promise<AssignmentDTO[]> {
|
export async function getAllAssignments(classid: string, full: boolean): Promise<AssignmentDTO[]> {
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
import { getClassRepository, getStudentRepository, getTeacherInvitationRepository, getTeacherRepository } from '../data/repositories.js';
|
import { getClassRepository, getStudentRepository, getTeacherInvitationRepository, getTeacherRepository } from '../data/repositories.js';
|
||||||
import { ClassDTO, mapToClassDTO } from '../interfaces/class.js';
|
import { mapToClassDTO } from '../interfaces/class.js';
|
||||||
import { mapToStudentDTO, StudentDTO } from '../interfaces/student.js';
|
import { mapToStudentDTO } from '../interfaces/student.js';
|
||||||
import { mapToTeacherInvitationDTO, mapToTeacherInvitationDTOIds, TeacherInvitationDTO } from '../interfaces/teacher-invitation.js';
|
import { mapToTeacherInvitationDTO, mapToTeacherInvitationDTOIds } from '../interfaces/teacher-invitation.js';
|
||||||
import { getLogger } from '../logging/initalize.js';
|
import { getLogger } from '../logging/initalize.js';
|
||||||
import { NotFoundException } from '../exceptions/not-found-exception.js';
|
import { NotFoundException } from '../exceptions/not-found-exception.js';
|
||||||
import { Class } from '../entities/classes/class.entity.js';
|
import { Class } from '../entities/classes/class.entity.js';
|
||||||
|
import { ClassDTO } from 'dwengo-1-common/src/interfaces/class';
|
||||||
|
import { TeacherInvitationDTO } from 'dwengo-1-common/src/interfaces/teacher-invitation';
|
||||||
|
import { StudentDTO } from 'dwengo-1-common/src/interfaces/student';
|
||||||
|
|
||||||
const logger = getLogger();
|
const logger = getLogger();
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,10 @@ import {
|
||||||
getSubmissionRepository,
|
getSubmissionRepository,
|
||||||
} from '../data/repositories.js';
|
} from '../data/repositories.js';
|
||||||
import { Group } from '../entities/assignments/group.entity.js';
|
import { Group } from '../entities/assignments/group.entity.js';
|
||||||
import { GroupDTO, mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js';
|
import { mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js';
|
||||||
import { mapToSubmissionDTO, mapToSubmissionDTOId, SubmissionDTO, SubmissionDTOId } from '../interfaces/submission.js';
|
import { mapToSubmissionDTO, mapToSubmissionDTOId } from '../interfaces/submission.js';
|
||||||
|
import { GroupDTO } from 'dwengo-1-common/src/interfaces/group';
|
||||||
|
import { SubmissionDTO, SubmissionDTOId } from 'dwengo-1-common/src/interfaces/submission';
|
||||||
import { getLogger } from '../logging/initalize.js';
|
import { getLogger } from '../logging/initalize.js';
|
||||||
|
|
||||||
export async function getGroup(classId: string, assignmentNumber: number, groupNumber: number, full: boolean): Promise<GroupDTO | null> {
|
export async function getGroup(classId: string, assignmentNumber: number, groupNumber: number, full: boolean): Promise<GroupDTO | null> {
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
import { DWENGO_API_BASE } from '../config.js';
|
import { DWENGO_API_BASE } from '../config.js';
|
||||||
import { fetchWithLogging } from '../util/api-helper.js';
|
import { fetchWithLogging } from '../util/api-helper.js';
|
||||||
import { FilteredLearningObject, LearningObjectMetadata, LearningObjectNode, LearningPathResponse } from '../interfaces/learning-content.js';
|
|
||||||
|
import {
|
||||||
|
FilteredLearningObject,
|
||||||
|
LearningObjectMetadata,
|
||||||
|
LearningObjectNode,
|
||||||
|
LearningPathResponse,
|
||||||
|
} from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
import { getLogger } from '../logging/initalize.js';
|
import { getLogger } from '../logging/initalize.js';
|
||||||
|
|
||||||
function filterData(data: LearningObjectMetadata, htmlUrl: string): FilteredLearningObject {
|
function filterData(data: LearningObjectMetadata, htmlUrl: string): FilteredLearningObject {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { getAttachmentRepository } from '../../data/repositories.js';
|
import { getAttachmentRepository } from '../../data/repositories.js';
|
||||||
import { Attachment } from '../../entities/content/attachment.entity.js';
|
import { Attachment } from '../../entities/content/attachment.entity.js';
|
||||||
import { LearningObjectIdentifier } from '../../interfaces/learning-content.js';
|
|
||||||
|
import { LearningObjectIdentifier } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
const attachmentService = {
|
const attachmentService = {
|
||||||
async getAttachment(learningObjectId: LearningObjectIdentifier, attachmentName: string): Promise<Attachment | null> {
|
async getAttachment(learningObjectId: LearningObjectIdentifier, attachmentName: string): Promise<Attachment | null> {
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { LearningObjectProvider } from './learning-object-provider.js';
|
import { LearningObjectProvider } from './learning-object-provider.js';
|
||||||
import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../../interfaces/learning-content.js';
|
|
||||||
import { getLearningObjectRepository, getLearningPathRepository } from '../../data/repositories.js';
|
import { getLearningObjectRepository, getLearningPathRepository } from '../../data/repositories.js';
|
||||||
import { LearningObject } from '../../entities/content/learning-object.entity.js';
|
import { LearningObject } from '../../entities/content/learning-object.entity.js';
|
||||||
import { getUrlStringForLearningObject } from '../../util/links.js';
|
import { getUrlStringForLearningObject } from '../../util/links.js';
|
||||||
|
@ -7,6 +6,7 @@ import processingService from './processing/processing-service.js';
|
||||||
import { NotFoundError } from '@mikro-orm/core';
|
import { NotFoundError } from '@mikro-orm/core';
|
||||||
import learningObjectService from './learning-object-service.js';
|
import learningObjectService from './learning-object-service.js';
|
||||||
import { getLogger, Logger } from '../../logging/initalize.js';
|
import { getLogger, Logger } from '../../logging/initalize.js';
|
||||||
|
import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
const logger: Logger = getLogger();
|
const logger: Logger = getLogger();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
import { DWENGO_API_BASE } from '../../config.js';
|
import { DWENGO_API_BASE } from '../../config.js';
|
||||||
import { fetchWithLogging } from '../../util/api-helper.js';
|
import { fetchWithLogging } from '../../util/api-helper.js';
|
||||||
|
import dwengoApiLearningPathProvider from '../learning-paths/dwengo-api-learning-path-provider.js';
|
||||||
|
import { LearningObjectProvider } from './learning-object-provider.js';
|
||||||
|
import { getLogger, Logger } from '../../logging/initalize.js';
|
||||||
import {
|
import {
|
||||||
FilteredLearningObject,
|
FilteredLearningObject,
|
||||||
LearningObjectIdentifier,
|
LearningObjectIdentifier,
|
||||||
|
@ -7,10 +10,7 @@ import {
|
||||||
LearningObjectNode,
|
LearningObjectNode,
|
||||||
LearningPathIdentifier,
|
LearningPathIdentifier,
|
||||||
LearningPathResponse,
|
LearningPathResponse,
|
||||||
} from '../../interfaces/learning-content.js';
|
} from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
import dwengoApiLearningPathProvider from '../learning-paths/dwengo-api-learning-path-provider.js';
|
|
||||||
import { LearningObjectProvider } from './learning-object-provider.js';
|
|
||||||
import { getLogger, Logger } from '../../logging/initalize.js';
|
|
||||||
|
|
||||||
const logger: Logger = getLogger();
|
const logger: Logger = getLogger();
|
||||||
|
|
||||||
|
@ -90,7 +90,7 @@ const dwengoApiLearningObjectProvider: LearningObjectProvider = {
|
||||||
metadataUrl,
|
metadataUrl,
|
||||||
`Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`,
|
`Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`,
|
||||||
{
|
{
|
||||||
params: id,
|
params: { ...id },
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ const dwengoApiLearningObjectProvider: LearningObjectProvider = {
|
||||||
async getLearningObjectHTML(id: LearningObjectIdentifier): Promise<string | null> {
|
async getLearningObjectHTML(id: LearningObjectIdentifier): Promise<string | null> {
|
||||||
const htmlUrl = `${DWENGO_API_BASE}/learningObject/getRaw`;
|
const htmlUrl = `${DWENGO_API_BASE}/learningObject/getRaw`;
|
||||||
const html = await fetchWithLogging<string>(htmlUrl, `Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`, {
|
const html = await fetchWithLogging<string>(htmlUrl, `Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`, {
|
||||||
params: id,
|
params: { ...id },
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!html) {
|
if (!html) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../../interfaces/learning-content.js';
|
import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
export interface LearningObjectProvider {
|
export interface LearningObjectProvider {
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../../interfaces/learning-content.js';
|
|
||||||
import dwengoApiLearningObjectProvider from './dwengo-api-learning-object-provider.js';
|
import dwengoApiLearningObjectProvider from './dwengo-api-learning-object-provider.js';
|
||||||
import { LearningObjectProvider } from './learning-object-provider.js';
|
import { LearningObjectProvider } from './learning-object-provider.js';
|
||||||
import { envVars, getEnvVar } from '../../util/envVars.js';
|
import { envVars, getEnvVar } from '../../util/envVars.js';
|
||||||
import databaseLearningObjectProvider from './database-learning-object-provider.js';
|
import databaseLearningObjectProvider from './database-learning-object-provider.js';
|
||||||
|
import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
function getProvider(id: LearningObjectIdentifier): LearningObjectProvider {
|
function getProvider(id: LearningObjectIdentifier): LearningObjectProvider {
|
||||||
if (id.hruid.startsWith(getEnvVar(envVars.UserContentPrefix))) {
|
if (id.hruid.startsWith(getEnvVar(envVars.UserContentPrefix))) {
|
||||||
|
|
|
@ -8,13 +8,13 @@ import InlineImageProcessor from '../image/inline-image-processor.js';
|
||||||
import * as marked from 'marked';
|
import * as marked from 'marked';
|
||||||
import { getUrlStringForLearningObjectHTML, isValidHttpUrl } from '../../../../util/links.js';
|
import { getUrlStringForLearningObjectHTML, isValidHttpUrl } from '../../../../util/links.js';
|
||||||
import { ProcessingError } from '../processing-error.js';
|
import { ProcessingError } from '../processing-error.js';
|
||||||
import { LearningObjectIdentifier } from '../../../../interfaces/learning-content.js';
|
|
||||||
import { Language } from '../../../../entities/content/language.js';
|
import { Language } from '../../../../entities/content/language.js';
|
||||||
|
|
||||||
import Image = marked.Tokens.Image;
|
import Image = marked.Tokens.Image;
|
||||||
import Heading = marked.Tokens.Heading;
|
import Heading = marked.Tokens.Heading;
|
||||||
import Link = marked.Tokens.Link;
|
import Link = marked.Tokens.Link;
|
||||||
import RendererObject = marked.RendererObject;
|
import RendererObject = marked.RendererObject;
|
||||||
|
import { LearningObjectIdentifier } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
const prefixes = {
|
const prefixes = {
|
||||||
learningObject: '@learning-object',
|
learningObject: '@learning-object',
|
||||||
|
|
|
@ -13,9 +13,9 @@ import GiftProcessor from './gift/gift-processor.js';
|
||||||
import { LearningObject } from '../../../entities/content/learning-object.entity.js';
|
import { LearningObject } from '../../../entities/content/learning-object.entity.js';
|
||||||
import Processor from './processor.js';
|
import Processor from './processor.js';
|
||||||
import { DwengoContentType } from './content-type.js';
|
import { DwengoContentType } from './content-type.js';
|
||||||
import { LearningObjectIdentifier } from '../../../interfaces/learning-content.js';
|
|
||||||
import { Language } from '../../../entities/content/language.js';
|
import { Language } from '../../../entities/content/language.js';
|
||||||
import { replaceAsync } from '../../../util/async.js';
|
import { replaceAsync } from '../../../util/async.js';
|
||||||
|
import { LearningObjectIdentifier } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
const EMBEDDED_LEARNING_OBJECT_PLACEHOLDER = /<learning-object hruid="([^"]+)" language="([^"]+)" version="([^"]+)"\/>/g;
|
const EMBEDDED_LEARNING_OBJECT_PLACEHOLDER = /<learning-object hruid="([^"]+)" language="([^"]+)" version="([^"]+)"\/>/g;
|
||||||
const LEARNING_OBJECT_DOES_NOT_EXIST = "<div class='non-existing-learning-object' />";
|
const LEARNING_OBJECT_DOES_NOT_EXIST = "<div class='non-existing-learning-object' />";
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
import { LearningPathProvider } from './learning-path-provider.js';
|
import { LearningPathProvider } from './learning-path-provider.js';
|
||||||
import { FilteredLearningObject, LearningObjectNode, LearningPath, LearningPathResponse, Transition } from '../../interfaces/learning-content.js';
|
|
||||||
import { LearningPath as LearningPathEntity } from '../../entities/content/learning-path.entity.js';
|
import { LearningPath as LearningPathEntity } from '../../entities/content/learning-path.entity.js';
|
||||||
import { getLearningPathRepository } from '../../data/repositories.js';
|
import { getLearningPathRepository } from '../../data/repositories.js';
|
||||||
import { Language } from '../../entities/content/language.js';
|
import { Language } from '../../entities/content/language.js';
|
||||||
|
@ -7,6 +6,13 @@ import learningObjectService from '../learning-objects/learning-object-service.j
|
||||||
import { LearningPathNode } from '../../entities/content/learning-path-node.entity.js';
|
import { LearningPathNode } from '../../entities/content/learning-path-node.entity.js';
|
||||||
import { LearningPathTransition } from '../../entities/content/learning-path-transition.entity.js';
|
import { LearningPathTransition } from '../../entities/content/learning-path-transition.entity.js';
|
||||||
import { getLastSubmissionForCustomizationTarget, isTransitionPossible, PersonalizationTarget } from './learning-path-personalization-util.js';
|
import { getLastSubmissionForCustomizationTarget, isTransitionPossible, PersonalizationTarget } from './learning-path-personalization-util.js';
|
||||||
|
import {
|
||||||
|
FilteredLearningObject,
|
||||||
|
LearningObjectNode,
|
||||||
|
LearningPath,
|
||||||
|
LearningPathResponse,
|
||||||
|
Transition,
|
||||||
|
} from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches the corresponding learning object for each of the nodes and creates a map that maps each node to its
|
* Fetches the corresponding learning object for each of the nodes and creates a map that maps each node to its
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { fetchWithLogging } from '../../util/api-helper.js';
|
import { fetchWithLogging } from '../../util/api-helper.js';
|
||||||
import { DWENGO_API_BASE } from '../../config.js';
|
import { DWENGO_API_BASE } from '../../config.js';
|
||||||
import { LearningPath, LearningPathResponse } from '../../interfaces/learning-content.js';
|
|
||||||
import { LearningPathProvider } from './learning-path-provider.js';
|
import { LearningPathProvider } from './learning-path-provider.js';
|
||||||
import { getLogger, Logger } from '../../logging/initalize.js';
|
import { getLogger, Logger } from '../../logging/initalize.js';
|
||||||
|
import { LearningPath, LearningPathResponse } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
const logger: Logger = getLogger();
|
const logger: Logger = getLogger();
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { LearningPath, LearningPathResponse } from '../../interfaces/learning-content.js';
|
|
||||||
import { Language } from '../../entities/content/language.js';
|
import { Language } from '../../entities/content/language.js';
|
||||||
import { PersonalizationTarget } from './learning-path-personalization-util.js';
|
import { PersonalizationTarget } from './learning-path-personalization-util.js';
|
||||||
|
import { LearningPath, LearningPathResponse } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic interface for a service which provides access to learning paths from a data source.
|
* Generic interface for a service which provides access to learning paths from a data source.
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
import { LearningPath, LearningPathResponse } from '../../interfaces/learning-content.js';
|
|
||||||
import dwengoApiLearningPathProvider from './dwengo-api-learning-path-provider.js';
|
import dwengoApiLearningPathProvider from './dwengo-api-learning-path-provider.js';
|
||||||
import databaseLearningPathProvider from './database-learning-path-provider.js';
|
import databaseLearningPathProvider from './database-learning-path-provider.js';
|
||||||
import { envVars, getEnvVar } from '../../util/envVars.js';
|
import { envVars, getEnvVar } from '../../util/envVars.js';
|
||||||
import { Language } from '../../entities/content/language.js';
|
import { Language } from '../../entities/content/language.js';
|
||||||
import { PersonalizationTarget } from './learning-path-personalization-util.js';
|
import { PersonalizationTarget } from './learning-path-personalization-util.js';
|
||||||
|
import { LearningPath, LearningPathResponse } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
const userContentPrefix = getEnvVar(envVars.UserContentPrefix);
|
const userContentPrefix = getEnvVar(envVars.UserContentPrefix);
|
||||||
const allProviders = [dwengoApiLearningPathProvider, databaseLearningPathProvider];
|
const allProviders = [dwengoApiLearningPathProvider, databaseLearningPathProvider];
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
import { getSubmissionRepository } from '../data/repositories.js';
|
import { getSubmissionRepository } from '../data/repositories.js';
|
||||||
import { Language } from '../entities/content/language.js';
|
import { Language } from '../entities/content/language.js';
|
||||||
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
|
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
|
||||||
import { mapToSubmission, mapToSubmissionDTO, SubmissionDTO } from '../interfaces/submission.js';
|
import { mapToSubmission, mapToSubmissionDTO } from '../interfaces/submission.js';
|
||||||
|
import { SubmissionDTO } from 'dwengo-1-common/src/interfaces/submission';
|
||||||
|
|
||||||
export async function getSubmission(
|
export async function getSubmission(
|
||||||
learningObjectHruid: string,
|
learningObjectHruid: string,
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import axios, { AxiosRequestConfig } from 'axios';
|
import axios, { AxiosRequestConfig } from 'axios';
|
||||||
import { getLogger, Logger } from '../logging/initalize.js';
|
import { getLogger, Logger } from '../logging/initalize.js';
|
||||||
import { LearningObjectIdentifier } from '../interfaces/learning-content.js';
|
import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js';
|
||||||
|
|
||||||
const logger: Logger = getLogger();
|
const logger: Logger = getLogger();
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { LearningObjectIdentifier } from '../interfaces/learning-content';
|
import { LearningObjectIdentifier } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
export function isValidHttpUrl(url: string): boolean {
|
export function isValidHttpUrl(url: string): boolean {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -5,11 +5,11 @@ import example from '../../test-assets/learning-objects/pn-werkingnotebooks/pn-w
|
||||||
import { LearningObject } from '../../../src/entities/content/learning-object.entity';
|
import { LearningObject } from '../../../src/entities/content/learning-object.entity';
|
||||||
import databaseLearningObjectProvider from '../../../src/services/learning-objects/database-learning-object-provider';
|
import databaseLearningObjectProvider from '../../../src/services/learning-objects/database-learning-object-provider';
|
||||||
import { expectToBeCorrectFilteredLearningObject } from '../../test-utils/expectations';
|
import { expectToBeCorrectFilteredLearningObject } from '../../test-utils/expectations';
|
||||||
import { FilteredLearningObject } from '../../../src/interfaces/learning-content';
|
|
||||||
import { Language } from '../../../src/entities/content/language';
|
import { Language } from '../../../src/entities/content/language';
|
||||||
import learningObjectExample from '../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example';
|
import learningObjectExample from '../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example';
|
||||||
import learningPathExample from '../../test-assets/learning-paths/pn-werking-example';
|
import learningPathExample from '../../test-assets/learning-paths/pn-werking-example';
|
||||||
import { LearningPath } from '../../../src/entities/content/learning-path.entity';
|
import { LearningPath } from '../../../src/entities/content/learning-path.entity';
|
||||||
|
import { FilteredLearningObject } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
async function initExampleData(): Promise<{ learningObject: LearningObject; learningPath: LearningPath }> {
|
async function initExampleData(): Promise<{ learningObject: LearningObject; learningPath: LearningPath }> {
|
||||||
const learningObjectRepo = getLearningObjectRepository();
|
const learningObjectRepo = getLearningObjectRepository();
|
||||||
|
|
|
@ -4,11 +4,11 @@ import { LearningObject } from '../../../src/entities/content/learning-object.en
|
||||||
import { getLearningObjectRepository, getLearningPathRepository } from '../../../src/data/repositories';
|
import { getLearningObjectRepository, getLearningPathRepository } from '../../../src/data/repositories';
|
||||||
import learningObjectExample from '../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example';
|
import learningObjectExample from '../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example';
|
||||||
import learningObjectService from '../../../src/services/learning-objects/learning-object-service';
|
import learningObjectService from '../../../src/services/learning-objects/learning-object-service';
|
||||||
import { LearningObjectIdentifier, LearningPathIdentifier } from '../../../src/interfaces/learning-content';
|
|
||||||
import { Language } from '../../../src/entities/content/language';
|
import { Language } from '../../../src/entities/content/language';
|
||||||
import { envVars, getEnvVar } from '../../../src/util/envVars';
|
import { envVars, getEnvVar } from '../../../src/util/envVars';
|
||||||
import { LearningPath } from '../../../src/entities/content/learning-path.entity';
|
import { LearningPath } from '../../../src/entities/content/learning-path.entity';
|
||||||
import learningPathExample from '../../test-assets/learning-paths/pn-werking-example';
|
import learningPathExample from '../../test-assets/learning-paths/pn-werking-example';
|
||||||
|
import { LearningObjectIdentifier, LearningPathIdentifier } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
const EXPECTED_DWENGO_LEARNING_OBJECT_TITLE = 'Werken met notebooks';
|
const EXPECTED_DWENGO_LEARNING_OBJECT_TITLE = 'Werken met notebooks';
|
||||||
const DWENGO_TEST_LEARNING_OBJECT_ID: LearningObjectIdentifier = {
|
const DWENGO_TEST_LEARNING_OBJECT_ID: LearningObjectIdentifier = {
|
||||||
|
@ -105,7 +105,10 @@ describe('LearningObjectService', () => {
|
||||||
expect(new Set(result.map((it) => it.key))).toEqual(DWENGO_TEST_LEARNING_PATH_HRUIDS);
|
expect(new Set(result.map((it) => it.key))).toEqual(DWENGO_TEST_LEARNING_PATH_HRUIDS);
|
||||||
});
|
});
|
||||||
it('returns an empty list when queried with a non-existing learning path id', async () => {
|
it('returns an empty list when queried with a non-existing learning path id', async () => {
|
||||||
const result = await learningObjectService.getLearningObjectsFromPath({ hruid: 'non_existing', language: Language.Dutch });
|
const result = await learningObjectService.getLearningObjectsFromPath({
|
||||||
|
hruid: 'non_existing',
|
||||||
|
language: Language.Dutch,
|
||||||
|
});
|
||||||
expect(result).toEqual([]);
|
expect(result).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -120,7 +123,10 @@ describe('LearningObjectService', () => {
|
||||||
expect(new Set(result)).toEqual(DWENGO_TEST_LEARNING_PATH_HRUIDS);
|
expect(new Set(result)).toEqual(DWENGO_TEST_LEARNING_PATH_HRUIDS);
|
||||||
});
|
});
|
||||||
it('returns an empty list when queried with a non-existing learning path id', async () => {
|
it('returns an empty list when queried with a non-existing learning path id', async () => {
|
||||||
const result = await learningObjectService.getLearningObjectIdsFromPath({ hruid: 'non_existing', language: Language.Dutch });
|
const result = await learningObjectService.getLearningObjectIdsFromPath({
|
||||||
|
hruid: 'non_existing',
|
||||||
|
language: Language.Dutch,
|
||||||
|
});
|
||||||
expect(result).toEqual([]);
|
expect(result).toEqual([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -19,7 +19,8 @@ import {
|
||||||
createConditionTestLearningPathAndLearningObjects,
|
createConditionTestLearningPathAndLearningObjects,
|
||||||
} from '../../test-assets/learning-paths/test-conditions-example.js';
|
} from '../../test-assets/learning-paths/test-conditions-example.js';
|
||||||
import { Student } from '../../../src/entities/users/student.entity.js';
|
import { Student } from '../../../src/entities/users/student.entity.js';
|
||||||
import { LearningObjectNode, LearningPathResponse } from '../../../src/interfaces/learning-content.js';
|
|
||||||
|
import { LearningObjectNode, LearningPathResponse } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
async function initExampleData(): Promise<{ learningObject: LearningObject; learningPath: LearningPath }> {
|
async function initExampleData(): Promise<{ learningObject: LearningObject; learningPath: LearningPath }> {
|
||||||
const learningObjectRepo = getLearningObjectRepository();
|
const learningObjectRepo = getLearningObjectRepository();
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
import { AssertionError } from 'node:assert';
|
import { AssertionError } from 'node:assert';
|
||||||
import { LearningObject } from '../../src/entities/content/learning-object.entity';
|
import { LearningObject } from '../../src/entities/content/learning-object.entity';
|
||||||
import { FilteredLearningObject, LearningPath } from '../../src/interfaces/learning-content';
|
|
||||||
import { LearningPath as LearningPathEntity } from '../../src/entities/content/learning-path.entity';
|
import { LearningPath as LearningPathEntity } from '../../src/entities/content/learning-path.entity';
|
||||||
import { expect } from 'vitest';
|
import { expect } from 'vitest';
|
||||||
|
import { FilteredLearningObject, LearningPath } from 'dwengo-1-common/src/interfaces/learning-content';
|
||||||
|
|
||||||
// Ignored properties because they belang for example to the class, not to the entity itself.
|
// Ignored properties because they belang for example to the class, not to the entity itself.
|
||||||
const IGNORE_PROPERTIES = ['parent'];
|
const IGNORE_PROPERTIES = ['parent'];
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"rootDir": "./src",
|
"rootDir": "./src",
|
||||||
"outDir": "./dist",
|
"outDir": "./dist",
|
||||||
"resolveJsonModule": true
|
"resolveJsonModule": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"composite": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
common/package.json
Normal file
16
common/package.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"name": "dwengo-1-common",
|
||||||
|
"version": "0.1.1",
|
||||||
|
"description": "Common types and utilities for Dwengo-1",
|
||||||
|
"private": true,
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {
|
||||||
|
"build": "tsc --project tsconfig.json",
|
||||||
|
"format": "prettier --write src/",
|
||||||
|
"format-check": "prettier --check src/",
|
||||||
|
"lint": "eslint . --fix"
|
||||||
|
},
|
||||||
|
"exports": {
|
||||||
|
"./src/*": "./dist/*"
|
||||||
|
}
|
||||||
|
}
|
16
common/src/interfaces/answer.d.ts
vendored
Normal file
16
common/src/interfaces/answer.d.ts
vendored
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
import { UserDTO } from './user';
|
||||||
|
import { QuestionDTO } from './question';
|
||||||
|
|
||||||
|
export interface AnswerDTO {
|
||||||
|
author: UserDTO;
|
||||||
|
toQuestion: QuestionDTO;
|
||||||
|
sequenceNumber: number;
|
||||||
|
timestamp: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AnswerId {
|
||||||
|
author: string;
|
||||||
|
toQuestion: QuestionId;
|
||||||
|
sequenceNumber: number;
|
||||||
|
}
|
11
common/src/interfaces/assignment.d.ts
vendored
Normal file
11
common/src/interfaces/assignment.d.ts
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { GroupDTO } from './group';
|
||||||
|
|
||||||
|
export interface AssignmentDTO {
|
||||||
|
id: number;
|
||||||
|
class: string; // Id of class 'within'
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
learningPath: string;
|
||||||
|
language: string;
|
||||||
|
groups?: GroupDTO[] | string[]; // TODO
|
||||||
|
}
|
7
common/src/interfaces/class.d.ts
vendored
Normal file
7
common/src/interfaces/class.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export interface ClassDTO {
|
||||||
|
id: string;
|
||||||
|
displayName: string;
|
||||||
|
teachers: string[];
|
||||||
|
students: string[];
|
||||||
|
joinRequests: string[];
|
||||||
|
}
|
7
common/src/interfaces/group.d.ts
vendored
Normal file
7
common/src/interfaces/group.d.ts
vendored
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
import { AssignmentDTO } from './assignment';
|
||||||
|
|
||||||
|
export interface GroupDTO {
|
||||||
|
assignment: number | AssignmentDTO;
|
||||||
|
groupNumber: number;
|
||||||
|
members: string[] | StudentDTO[];
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
import { Language } from '../entities/content/language';
|
import { Language } from 'dwengo-1-backend/src/entities/content/language.js';
|
||||||
|
|
||||||
export interface Transition {
|
export interface Transition {
|
||||||
default: boolean;
|
default: boolean;
|
14
common/src/interfaces/question.d.ts
vendored
Normal file
14
common/src/interfaces/question.d.ts
vendored
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
import { StudentDTO } from './student';
|
||||||
|
|
||||||
|
export interface QuestionDTO {
|
||||||
|
learningObjectIdentifier: LearningObjectIdentifier;
|
||||||
|
sequenceNumber?: number;
|
||||||
|
author: StudentDTO;
|
||||||
|
timestamp?: string;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface QuestionId {
|
||||||
|
learningObjectIdentifier: LearningObjectIdentifier;
|
||||||
|
sequenceNumber: number;
|
||||||
|
}
|
12
common/src/interfaces/student.d.ts
vendored
Normal file
12
common/src/interfaces/student.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
export interface StudentDTO {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
endpoints?: {
|
||||||
|
classes: string;
|
||||||
|
questions: string;
|
||||||
|
invitations: string;
|
||||||
|
groups: string;
|
||||||
|
};
|
||||||
|
}
|
19
common/src/interfaces/submission.d.ts
vendored
Normal file
19
common/src/interfaces/submission.d.ts
vendored
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
import { GroupDTO } from './group';
|
||||||
|
|
||||||
|
export interface SubmissionDTO {
|
||||||
|
learningObjectIdentifier: LearningObjectIdentifier;
|
||||||
|
|
||||||
|
submissionNumber?: number;
|
||||||
|
submitter: StudentDTO;
|
||||||
|
time?: Date;
|
||||||
|
group?: GroupDTO;
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SubmissionDTOId {
|
||||||
|
learningObjectHruid: string;
|
||||||
|
learningObjectLanguage: Language;
|
||||||
|
learningObjectVersion: number;
|
||||||
|
|
||||||
|
submissionNumber?: number;
|
||||||
|
}
|
8
common/src/interfaces/teacher-invitation.d.ts
vendored
Normal file
8
common/src/interfaces/teacher-invitation.d.ts
vendored
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import { UserDTO } from './user';
|
||||||
|
import { ClassDTO } from './class';
|
||||||
|
|
||||||
|
export interface TeacherInvitationDTO {
|
||||||
|
sender: string | UserDTO;
|
||||||
|
receiver: string | UserDTO;
|
||||||
|
class: string | ClassDTO;
|
||||||
|
}
|
12
common/src/interfaces/teacher.d.ts
vendored
Normal file
12
common/src/interfaces/teacher.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
export interface TeacherDTO {
|
||||||
|
id: string;
|
||||||
|
username: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
endpoints?: {
|
||||||
|
classes: string;
|
||||||
|
questions: string;
|
||||||
|
invitations: string;
|
||||||
|
groups: string;
|
||||||
|
};
|
||||||
|
}
|
12
common/src/interfaces/user.d.ts
vendored
Normal file
12
common/src/interfaces/user.d.ts
vendored
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
export interface UserDTO {
|
||||||
|
id?: string;
|
||||||
|
username: string;
|
||||||
|
firstName: string;
|
||||||
|
lastName: string;
|
||||||
|
endpoints?: {
|
||||||
|
self: string;
|
||||||
|
classes: string;
|
||||||
|
questions: string;
|
||||||
|
invitations: string;
|
||||||
|
};
|
||||||
|
}
|
11
common/tsconfig.json
Normal file
11
common/tsconfig.json
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
{
|
||||||
|
"extends": "../tsconfig.json",
|
||||||
|
"include": ["src/**/*.ts"],
|
||||||
|
"compilerOptions": {
|
||||||
|
"rootDir": "./src",
|
||||||
|
"outDir": "./dist",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"sourceMap": true,
|
||||||
|
"composite": true
|
||||||
|
}
|
||||||
|
}
|
10
package-lock.json
generated
10
package-lock.json
generated
|
@ -10,6 +10,7 @@
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"backend",
|
"backend",
|
||||||
|
"common",
|
||||||
"frontend",
|
"frontend",
|
||||||
"docs"
|
"docs"
|
||||||
],
|
],
|
||||||
|
@ -40,6 +41,7 @@
|
||||||
"cross": "^1.0.0",
|
"cross": "^1.0.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"dotenv": "^16.4.7",
|
"dotenv": "^16.4.7",
|
||||||
|
"dwengo-1-common": "^0.1.1",
|
||||||
"express": "^5.0.1",
|
"express": "^5.0.1",
|
||||||
"express-jwt": "^8.5.1",
|
"express-jwt": "^8.5.1",
|
||||||
"gift-pegjs": "^1.0.2",
|
"gift-pegjs": "^1.0.2",
|
||||||
|
@ -83,6 +85,10 @@
|
||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"common": {
|
||||||
|
"name": "dwengo-1-common",
|
||||||
|
"version": "0.1.1"
|
||||||
|
},
|
||||||
"docs": {
|
"docs": {
|
||||||
"name": "dwengo-1-docs",
|
"name": "dwengo-1-docs",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
|
@ -4919,6 +4925,10 @@
|
||||||
"resolved": "backend",
|
"resolved": "backend",
|
||||||
"link": true
|
"link": true
|
||||||
},
|
},
|
||||||
|
"node_modules/dwengo-1-common": {
|
||||||
|
"resolved": "common",
|
||||||
|
"link": true
|
||||||
|
},
|
||||||
"node_modules/dwengo-1-docs": {
|
"node_modules/dwengo-1-docs": {
|
||||||
"resolved": "docs",
|
"resolved": "docs",
|
||||||
"link": true
|
"link": true
|
||||||
|
|
|
@ -5,14 +5,15 @@
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "npm run build --workspace=backend --workspace=frontend",
|
"build": "npm run build --workspaces --if-present",
|
||||||
"format": "npm run format --workspace=backend --workspace=frontend",
|
"format": "npm run format --workspace=backend --workspace=common --workspace=frontend",
|
||||||
"format-check": "npm run format-check --workspace=backend --workspace=frontend",
|
"format-check": "npm run format-check --workspace=backend --workspace=common --workspace=frontend",
|
||||||
"lint": "npm run lint --workspace=backend --workspace=frontend",
|
"lint": "npm run lint --workspace=backend --workspace=common --workspace=frontend",
|
||||||
"test:unit": "npm run test:unit --workspace=backend --workspace=frontend"
|
"test:unit": "npm run test:unit --workspace=backend --workspace=frontend"
|
||||||
},
|
},
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"backend",
|
"backend",
|
||||||
|
"common",
|
||||||
"frontend",
|
"frontend",
|
||||||
"docs"
|
"docs"
|
||||||
],
|
],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue