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" | ||||||
|     ], |     ], | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Gabriellvl
						Gabriellvl