diff --git a/.github/workflows/lint-action.yml b/.github/workflows/lint-action.yml index 32823417..7fd77d28 100644 --- a/.github/workflows/lint-action.yml +++ b/.github/workflows/lint-action.yml @@ -43,6 +43,6 @@ jobs: with: auto_fix: true eslint: true - eslint_args: '--config eslint.config.ts' + eslint_args: "--config eslint.config.ts --ignore-pattern '**/prettier.config.js'" prettier: true - commit_message: 'style: fix linting issues met ${linter}' \ No newline at end of file + commit_message: 'style: fix linting issues met ${linter}' diff --git a/.gitignore b/.gitignore index d28e7d73..d3905d1f 100644 --- a/.gitignore +++ b/.gitignore @@ -737,4 +737,4 @@ flycheck_*.el # network security /network-security.data - +docs/.venv diff --git a/backend/Dockerfile b/backend/Dockerfile index 7c63c4b8..f09a89eb 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -1,38 +1,51 @@ FROM node:22 AS build-stage -WORKDIR /app +WORKDIR /app/dwengo # Install dependencies COPY package*.json ./ COPY backend/package.json ./backend/ +# Backend depends on common +COPY common/package.json ./common/ RUN npm install --silent # Build the backend # Root tsconfig.json -COPY tsconfig.json ./ +COPY tsconfig.json tsconfig.build.json ./ -WORKDIR /app/backend - -COPY backend ./ -COPY docs /app/docs +COPY backend ./backend +COPY common ./common +COPY docs ./docs RUN npm run build FROM node:22 AS production-stage -WORKDIR /app +WORKDIR /app/dwengo -COPY package-lock.json backend/package.json ./ +# Copy static files + +COPY ./backend/i18n ./i18n + +# Copy built files + +COPY --from=build-stage /app/dwengo/common/dist ./common/dist +COPY --from=build-stage /app/dwengo/backend/dist ./backend/dist + +COPY package*.json ./ +COPY backend/package.json ./backend/ +# Backend depends on common +COPY common/package.json ./common/ RUN npm install --silent --only=production -COPY ./docs /docs -COPY ./backend/i18n /app/i18n -COPY --from=build-stage /app/backend/dist ./dist/ +COPY ./docs ./docs +COPY ./backend/i18n ./backend/i18n +COPY ./backend/.env ./backend/.env EXPOSE 3000 -CMD ["node", "--env-file=.env", "dist/app.js"] +CMD ["node", "--env-file=/app/dwengo/backend/.env", "/app/dwengo/backend/dist/app.js"] diff --git a/backend/config.js b/backend/config.js deleted file mode 100644 index be42027c..00000000 --- a/backend/config.js +++ /dev/null @@ -1,7 +0,0 @@ -// Can be placed in dotenv but found it redundant -// Import dotenv from "dotenv"; -// Load .env file -// Dotenv.config(); -export const DWENGO_API_BASE = 'https://dwengo.org/backend/api'; -export const FALLBACK_LANG = 'nl'; -export const FALLBACK_SEQ_NUM = 1; diff --git a/backend/package.json b/backend/package.json index c08fb1dc..83db321f 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,16 +1,18 @@ { - "name": "dwengo-1-backend", + "name": "@dwengo-1/backend", "version": "0.1.1", "description": "Backend for Dwengo-1", "private": true, "type": "module", + "main": "dist/app.js", "scripts": { - "build": "cross-env NODE_ENV=production tsc --project tsconfig.json", + "build": "cross-env NODE_ENV=production tsc --build", "dev": "cross-env NODE_ENV=development tsx watch --env-file=.env.development.local src/app.ts", "start": "cross-env NODE_ENV=production node --env-file=.env dist/app.js", "format": "prettier --write src/", "format-check": "prettier --check src/", "lint": "eslint . --fix", + "pretest:unit": "npm run build", "test:unit": "vitest --run" }, "dependencies": { @@ -24,6 +26,7 @@ "cross": "^1.0.0", "cross-env": "^7.0.3", "dotenv": "^16.4.7", + "dwengo-1-common": "^0.1.1", "express": "^5.0.1", "express-jwt": "^8.5.1", "gift-pegjs": "^1.0.2", diff --git a/backend/src/controllers/assignments.ts b/backend/src/controllers/assignments.ts index c8dd1ec8..1520fc10 100644 --- a/backend/src/controllers/assignments.ts +++ b/backend/src/controllers/assignments.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; import { createAssignment, getAllAssignments, getAssignment, getAssignmentsSubmissions } from '../services/assignments.js'; -import { AssignmentDTO } from '../interfaces/assignment.js'; +import { AssignmentDTO } from '@dwengo-1/common/interfaces/assignment'; // Typescript is annoying with parameter forwarding from class.ts interface AssignmentParams { diff --git a/backend/src/controllers/classes.ts b/backend/src/controllers/classes.ts index 7526f7c4..a041bf22 100644 --- a/backend/src/controllers/classes.ts +++ b/backend/src/controllers/classes.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; import { createClass, getAllClasses, getClass, getClassStudents, getClassStudentsIds, getClassTeacherInvitations } from '../services/classes.js'; -import { ClassDTO } from '../interfaces/class.js'; +import { ClassDTO } from '@dwengo-1/common/interfaces/class'; export async function getAllClassesHandler(req: Request, res: Response): Promise { const full = req.query.full === 'true'; diff --git a/backend/src/controllers/groups.ts b/backend/src/controllers/groups.ts index 7de3e114..989066a6 100644 --- a/backend/src/controllers/groups.ts +++ b/backend/src/controllers/groups.ts @@ -1,6 +1,6 @@ import { Request, Response } from 'express'; import { createGroup, getAllGroups, getGroup, getGroupSubmissions } from '../services/groups.js'; -import { GroupDTO } from '../interfaces/group.js'; +import { GroupDTO } from '@dwengo-1/common/interfaces/group'; // Typescript is annoywith with parameter forwarding from class.ts interface GroupParams { diff --git a/backend/src/controllers/learning-objects.ts b/backend/src/controllers/learning-objects.ts index b872ee74..a2510631 100644 --- a/backend/src/controllers/learning-objects.ts +++ b/backend/src/controllers/learning-objects.ts @@ -1,12 +1,12 @@ import { Request, Response } from 'express'; 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 { Language } from '../entities/content/language.js'; +import { Language } from '@dwengo-1/common/util/language'; import attachmentService from '../services/learning-objects/attachment-service.js'; import { BadRequestException } from '../exceptions/bad-request-exception.js'; import { NotFoundException } from '../exceptions/not-found-exception.js'; import { envVars, getEnvVar } from '../util/envVars.js'; +import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '@dwengo-1/common/interfaces/learning-content'; function getLearningObjectIdentifierFromRequest(req: Request): LearningObjectIdentifier { if (!req.params.hruid) { diff --git a/backend/src/controllers/learning-paths.ts b/backend/src/controllers/learning-paths.ts index 04e44b59..0097d568 100644 --- a/backend/src/controllers/learning-paths.ts +++ b/backend/src/controllers/learning-paths.ts @@ -2,7 +2,7 @@ import { Request, Response } from 'express'; import { themes } from '../data/themes.js'; import { FALLBACK_LANG } from '../config.js'; import learningPathService from '../services/learning-paths/learning-path-service.js'; -import { Language } from '../entities/content/language.js'; +import { Language } from '@dwengo-1/common/util/language'; import { PersonalizationTarget, personalizedForGroup, diff --git a/backend/src/controllers/questions.ts b/backend/src/controllers/questions.ts index 6735c305..b5b764ac 100644 --- a/backend/src/controllers/questions.ts +++ b/backend/src/controllers/questions.ts @@ -1,9 +1,9 @@ import { Request, Response } from 'express'; 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 { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js'; -import { Language } from '../entities/content/language.js'; +import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; +import { Language } from '@dwengo-1/common/util/language'; function getObjectId(req: Request, res: Response): LearningObjectIdentifier | null { const { hruid, version } = req.params; diff --git a/backend/src/controllers/students.ts b/backend/src/controllers/students.ts index 7e0b5565..54aae143 100644 --- a/backend/src/controllers/students.ts +++ b/backend/src/controllers/students.ts @@ -9,7 +9,8 @@ import { getStudentGroups, getStudentSubmissions, } from '../services/students.js'; -import { StudentDTO } from '../interfaces/student.js'; + +import { StudentDTO } from '@dwengo-1/common/interfaces/student'; // TODO: accept arguments (full, ...) // TODO: endpoints diff --git a/backend/src/controllers/submissions.ts b/backend/src/controllers/submissions.ts index 67c1d3a9..239eb6d7 100644 --- a/backend/src/controllers/submissions.ts +++ b/backend/src/controllers/submissions.ts @@ -1,7 +1,7 @@ import { Request, Response } from 'express'; import { createSubmission, deleteSubmission, getSubmission } from '../services/submissions.js'; -import { Language, languageMap } from '../entities/content/language.js'; -import { SubmissionDTO } from '../interfaces/submission'; +import { SubmissionDTO } from '@dwengo-1/common/interfaces/submission'; +import { Language, languageMap } from '@dwengo-1/common/util/language'; interface SubmissionParams { hruid: string; diff --git a/backend/src/controllers/teachers.ts b/backend/src/controllers/teachers.ts index 06316681..c3894bd6 100644 --- a/backend/src/controllers/teachers.ts +++ b/backend/src/controllers/teachers.ts @@ -8,7 +8,7 @@ import { getStudentsByTeacher, getTeacher, } from '../services/teachers.js'; -import { TeacherDTO } from '../interfaces/teacher.js'; +import { TeacherDTO } from '@dwengo-1/common/interfaces/teacher'; export async function getAllTeachersHandler(req: Request, res: Response): Promise { const full = req.query.full === 'true'; diff --git a/backend/src/data/content/attachment-repository.ts b/backend/src/data/content/attachment-repository.ts index 73baa943..69178b1c 100644 --- a/backend/src/data/content/attachment-repository.ts +++ b/backend/src/data/content/attachment-repository.ts @@ -1,6 +1,6 @@ import { DwengoEntityRepository } from '../dwengo-entity-repository.js'; import { Attachment } from '../../entities/content/attachment.entity.js'; -import { Language } from '../../entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier'; export class AttachmentRepository extends DwengoEntityRepository { diff --git a/backend/src/data/content/learning-object-repository.ts b/backend/src/data/content/learning-object-repository.ts index 4684c6cc..889a1594 100644 --- a/backend/src/data/content/learning-object-repository.ts +++ b/backend/src/data/content/learning-object-repository.ts @@ -1,7 +1,7 @@ import { DwengoEntityRepository } from '../dwengo-entity-repository.js'; import { LearningObject } from '../../entities/content/learning-object.entity.js'; import { LearningObjectIdentifier } from '../../entities/content/learning-object-identifier.js'; -import { Language } from '../../entities/content/language.js'; +import { Language } from '@dwengo-1/common/util/language'; import { Teacher } from '../../entities/users/teacher.entity.js'; export class LearningObjectRepository extends DwengoEntityRepository { diff --git a/backend/src/data/content/learning-path-repository.ts b/backend/src/data/content/learning-path-repository.ts index e34508ec..87035f21 100644 --- a/backend/src/data/content/learning-path-repository.ts +++ b/backend/src/data/content/learning-path-repository.ts @@ -1,6 +1,6 @@ import { DwengoEntityRepository } from '../dwengo-entity-repository.js'; import { LearningPath } from '../../entities/content/learning-path.entity.js'; -import { Language } from '../../entities/content/language.js'; +import { Language } from '@dwengo-1/common/util/language'; export class LearningPathRepository extends DwengoEntityRepository { public async findByHruidAndLanguage(hruid: string, language: Language): Promise { diff --git a/backend/src/entities/assignments/assignment.entity.ts b/backend/src/entities/assignments/assignment.entity.ts index daa71ed6..36b24344 100644 --- a/backend/src/entities/assignments/assignment.entity.ts +++ b/backend/src/entities/assignments/assignment.entity.ts @@ -1,7 +1,7 @@ import { Entity, Enum, ManyToOne, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; import { Class } from '../classes/class.entity.js'; import { Group } from './group.entity.js'; -import { Language } from '../content/language.js'; +import { Language } from '@dwengo-1/common/util/language'; import { AssignmentRepository } from '../../data/assignments/assignment-repository.js'; @Entity({ diff --git a/backend/src/entities/assignments/submission.entity.ts b/backend/src/entities/assignments/submission.entity.ts index e4330e0d..80b9a8fb 100644 --- a/backend/src/entities/assignments/submission.entity.ts +++ b/backend/src/entities/assignments/submission.entity.ts @@ -1,8 +1,8 @@ import { Student } from '../users/student.entity.js'; import { Group } from './group.entity.js'; import { Entity, Enum, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'; -import { Language } from '../content/language.js'; import { SubmissionRepository } from '../../data/assignments/submission-repository.js'; +import { Language } from '@dwengo-1/common/util/language'; @Entity({ repository: () => SubmissionRepository }) export class Submission { diff --git a/backend/src/entities/classes/class-join-request.entity.ts b/backend/src/entities/classes/class-join-request.entity.ts index fdf13aa9..907c0199 100644 --- a/backend/src/entities/classes/class-join-request.entity.ts +++ b/backend/src/entities/classes/class-join-request.entity.ts @@ -2,12 +2,7 @@ import { Entity, Enum, ManyToOne } from '@mikro-orm/core'; import { Student } from '../users/student.entity.js'; import { Class } from './class.entity.js'; import { ClassJoinRequestRepository } from '../../data/classes/class-join-request-repository.js'; - -export enum ClassJoinRequestStatus { - Open = 'open', - Accepted = 'accepted', - Declined = 'declined', -} +import { ClassJoinRequestStatus } from '@dwengo-1/common/util/class-join-request'; @Entity({ repository: () => ClassJoinRequestRepository, diff --git a/backend/src/entities/content/learning-object-identifier.ts b/backend/src/entities/content/learning-object-identifier.ts index 9234afa7..09a9c057 100644 --- a/backend/src/entities/content/learning-object-identifier.ts +++ b/backend/src/entities/content/learning-object-identifier.ts @@ -1,4 +1,4 @@ -import { Language } from './language.js'; +import { Language } from '@dwengo-1/common/util/language'; export class LearningObjectIdentifier { constructor( diff --git a/backend/src/entities/content/learning-object.entity.ts b/backend/src/entities/content/learning-object.entity.ts index e352a10a..ff858fe6 100644 --- a/backend/src/entities/content/learning-object.entity.ts +++ b/backend/src/entities/content/learning-object.entity.ts @@ -1,5 +1,4 @@ import { Embedded, Entity, Enum, ManyToMany, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; -import { Language } from './language.js'; import { Attachment } from './attachment.entity.js'; import { Teacher } from '../users/teacher.entity.js'; import { DwengoContentType } from '../../services/learning-objects/processing/content-type.js'; @@ -7,6 +6,7 @@ import { v4 } from 'uuid'; import { LearningObjectRepository } from '../../data/content/learning-object-repository.js'; import { EducationalGoal } from './educational-goal.entity.js'; import { ReturnValue } from './return-value.entity.js'; +import { Language } from '@dwengo-1/common/util/language'; @Entity({ repository: () => LearningObjectRepository }) export class LearningObject { diff --git a/backend/src/entities/content/learning-path-node.entity.ts b/backend/src/entities/content/learning-path-node.entity.ts index 03499270..3016c367 100644 --- a/backend/src/entities/content/learning-path-node.entity.ts +++ b/backend/src/entities/content/learning-path-node.entity.ts @@ -1,7 +1,7 @@ import { Entity, Enum, ManyToOne, OneToMany, PrimaryKey, Property, Rel } from '@mikro-orm/core'; -import { Language } from './language.js'; import { LearningPath } from './learning-path.entity.js'; import { LearningPathTransition } from './learning-path-transition.entity.js'; +import { Language } from '@dwengo-1/common/util/language'; @Entity() export class LearningPathNode { diff --git a/backend/src/entities/content/learning-path.entity.ts b/backend/src/entities/content/learning-path.entity.ts index 888cc0cf..203af86d 100644 --- a/backend/src/entities/content/learning-path.entity.ts +++ b/backend/src/entities/content/learning-path.entity.ts @@ -1,8 +1,8 @@ import { Entity, Enum, ManyToMany, OneToMany, PrimaryKey, Property } from '@mikro-orm/core'; -import { Language } from './language.js'; import { Teacher } from '../users/teacher.entity.js'; import { LearningPathRepository } from '../../data/content/learning-path-repository.js'; import { LearningPathNode } from './learning-path-node.entity.js'; +import { Language } from '@dwengo-1/common/util/language'; @Entity({ repository: () => LearningPathRepository }) export class LearningPath { diff --git a/backend/src/entities/questions/question.entity.ts b/backend/src/entities/questions/question.entity.ts index 09e3cd46..5e691f70 100644 --- a/backend/src/entities/questions/question.entity.ts +++ b/backend/src/entities/questions/question.entity.ts @@ -1,7 +1,7 @@ import { Entity, Enum, ManyToOne, PrimaryKey, Property } from '@mikro-orm/core'; -import { Language } from '../content/language.js'; import { Student } from '../users/student.entity.js'; import { QuestionRepository } from '../../data/questions/question-repository.js'; +import { Language } from '@dwengo-1/common/util/language'; @Entity({ repository: () => QuestionRepository }) export class Question { diff --git a/backend/src/interfaces/answer.ts b/backend/src/interfaces/answer.ts index 493fd3c0..5599839f 100644 --- a/backend/src/interfaces/answer.ts +++ b/backend/src/interfaces/answer.ts @@ -1,14 +1,7 @@ -import { mapToUserDTO, UserDTO } from './user.js'; -import { mapToQuestionDTO, mapToQuestionId, QuestionDTO, QuestionId } from './question.js'; +import { mapToUserDTO } from './user.js'; +import { mapToQuestionDTO, mapToQuestionId } from './question.js'; import { Answer } from '../entities/questions/answer.entity.js'; - -export interface AnswerDTO { - author: UserDTO; - toQuestion: QuestionDTO; - sequenceNumber: number; - timestamp: string; - content: string; -} +import { AnswerDTO, AnswerId } from '@dwengo-1/common/interfaces/answer'; /** * Convert a Question entity to a DTO format. @@ -23,12 +16,6 @@ export function mapToAnswerDTO(answer: Answer): AnswerDTO { }; } -export interface AnswerId { - author: string; - toQuestion: QuestionId; - sequenceNumber: number; -} - export function mapToAnswerId(answer: AnswerDTO): AnswerId { return { author: answer.author.username, diff --git a/backend/src/interfaces/assignment.ts b/backend/src/interfaces/assignment.ts index 698b5b40..d48a9083 100644 --- a/backend/src/interfaces/assignment.ts +++ b/backend/src/interfaces/assignment.ts @@ -1,19 +1,9 @@ +import { languageMap } from '@dwengo-1/common/util/language'; import { FALLBACK_LANG } from '../config.js'; import { Assignment } from '../entities/assignments/assignment.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'; - -export interface AssignmentDTO { - id: number; - class: string; // Id of class 'within' - title: string; - description: string; - learningPath: string; - language: string; - groups?: GroupDTO[] | string[]; // TODO -} +import { AssignmentDTO } from '@dwengo-1/common/interfaces/assignment'; export function mapToAssignmentDTOId(assignment: Assignment): AssignmentDTO { return { diff --git a/backend/src/interfaces/class.ts b/backend/src/interfaces/class.ts index ea1d4901..7b07fcf2 100644 --- a/backend/src/interfaces/class.ts +++ b/backend/src/interfaces/class.ts @@ -2,14 +2,7 @@ import { Collection } from '@mikro-orm/core'; import { Class } from '../entities/classes/class.entity.js'; import { Student } from '../entities/users/student.entity.js'; import { Teacher } from '../entities/users/teacher.entity.js'; - -export interface ClassDTO { - id: string; - displayName: string; - teachers: string[]; - students: string[]; - joinRequests: string[]; -} +import { ClassDTO } from '@dwengo-1/common/interfaces/class'; export function mapToClassDTO(cls: Class): ClassDTO { return { diff --git a/backend/src/interfaces/group.ts b/backend/src/interfaces/group.ts index a25c5b8e..1a169b2b 100644 --- a/backend/src/interfaces/group.ts +++ b/backend/src/interfaces/group.ts @@ -1,12 +1,7 @@ import { Group } from '../entities/assignments/group.entity.js'; -import { AssignmentDTO, mapToAssignmentDTO } from './assignment.js'; -import { mapToStudentDTO, StudentDTO } from './student.js'; - -export interface GroupDTO { - assignment: number | AssignmentDTO; - groupNumber: number; - members: string[] | StudentDTO[]; -} +import { mapToAssignmentDTO } from './assignment.js'; +import { mapToStudentDTO } from './student.js'; +import { GroupDTO } from '@dwengo-1/common/interfaces/group'; export function mapToGroupDTO(group: Group): GroupDTO { return { diff --git a/backend/src/interfaces/question.ts b/backend/src/interfaces/question.ts index 0da87eb7..57778bac 100644 --- a/backend/src/interfaces/question.ts +++ b/backend/src/interfaces/question.ts @@ -1,14 +1,6 @@ import { Question } from '../entities/questions/question.entity.js'; -import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js'; -import { mapToStudentDTO, StudentDTO } from './student.js'; - -export interface QuestionDTO { - learningObjectIdentifier: LearningObjectIdentifier; - sequenceNumber?: number; - author: StudentDTO; - timestamp?: string; - content: string; -} +import { mapToStudentDTO } from './student.js'; +import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; /** * Convert a Question entity to a DTO format. @@ -29,11 +21,6 @@ export function mapToQuestionDTO(question: Question): QuestionDTO { }; } -export interface QuestionId { - learningObjectIdentifier: LearningObjectIdentifier; - sequenceNumber: number; -} - export function mapToQuestionId(question: QuestionDTO): QuestionId { return { learningObjectIdentifier: question.learningObjectIdentifier, diff --git a/backend/src/interfaces/student.ts b/backend/src/interfaces/student.ts index ecce8f89..06e173a1 100644 --- a/backend/src/interfaces/student.ts +++ b/backend/src/interfaces/student.ts @@ -1,18 +1,6 @@ import { Student } from '../entities/users/student.entity.js'; import { getStudentRepository } from '../data/repositories.js'; - -export interface StudentDTO { - id: string; - username: string; - firstName: string; - lastName: string; - endpoints?: { - classes: string; - questions: string; - invitations: string; - groups: string; - }; -} +import { StudentDTO } from '@dwengo-1/common/interfaces/student'; export function mapToStudentDTO(student: Student): StudentDTO { return { diff --git a/backend/src/interfaces/submission.ts b/backend/src/interfaces/submission.ts index 98cc4f22..b4ed4a2b 100644 --- a/backend/src/interfaces/submission.ts +++ b/backend/src/interfaces/submission.ts @@ -1,26 +1,7 @@ import { Submission } from '../entities/assignments/submission.entity.js'; -import { Language } from '../entities/content/language.js'; -import { GroupDTO, mapToGroupDTO } from './group.js'; -import { mapToStudent, mapToStudentDTO, StudentDTO } from './student.js'; -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; -} +import { mapToGroupDTO } from './group.js'; +import { mapToStudent, mapToStudentDTO } from './student.js'; +import { SubmissionDTO, SubmissionDTOId } from '@dwengo-1/common/interfaces/submission'; export function mapToSubmissionDTO(submission: Submission): SubmissionDTO { return { diff --git a/backend/src/interfaces/teacher-invitation.ts b/backend/src/interfaces/teacher-invitation.ts index cddef566..d9cb9915 100644 --- a/backend/src/interfaces/teacher-invitation.ts +++ b/backend/src/interfaces/teacher-invitation.ts @@ -1,12 +1,7 @@ import { TeacherInvitation } from '../entities/classes/teacher-invitation.entity.js'; -import { ClassDTO, mapToClassDTO } from './class.js'; -import { mapToUserDTO, UserDTO } from './user.js'; - -export interface TeacherInvitationDTO { - sender: string | UserDTO; - receiver: string | UserDTO; - class: string | ClassDTO; -} +import { mapToClassDTO } from './class.js'; +import { mapToUserDTO } from './user.js'; +import { TeacherInvitationDTO } from '@dwengo-1/common/interfaces/teacher-invitation'; export function mapToTeacherInvitationDTO(invitation: TeacherInvitation): TeacherInvitationDTO { return { diff --git a/backend/src/interfaces/teacher.ts b/backend/src/interfaces/teacher.ts index 31b4723f..f7e1745f 100644 --- a/backend/src/interfaces/teacher.ts +++ b/backend/src/interfaces/teacher.ts @@ -1,18 +1,6 @@ import { Teacher } from '../entities/users/teacher.entity.js'; import { getTeacherRepository } from '../data/repositories.js'; - -export interface TeacherDTO { - id: string; - username: string; - firstName: string; - lastName: string; - endpoints?: { - classes: string; - questions: string; - invitations: string; - groups: string; - }; -} +import { TeacherDTO } from '@dwengo-1/common/interfaces/teacher'; export function mapToTeacherDTO(teacher: Teacher): TeacherDTO { return { diff --git a/backend/src/interfaces/user.ts b/backend/src/interfaces/user.ts index 58f0dd5a..f4413b5e 100644 --- a/backend/src/interfaces/user.ts +++ b/backend/src/interfaces/user.ts @@ -1,17 +1,5 @@ import { User } from '../entities/users/user.entity.js'; - -export interface UserDTO { - id?: string; - username: string; - firstName: string; - lastName: string; - endpoints?: { - self: string; - classes: string; - questions: string; - invitations: string; - }; -} +import { UserDTO } from '@dwengo-1/common/interfaces/user'; export function mapToUserDTO(user: User): UserDTO { return { diff --git a/backend/src/services/assignments.ts b/backend/src/services/assignments.ts index 22c5ce9e..e86b69b2 100644 --- a/backend/src/services/assignments.ts +++ b/backend/src/services/assignments.ts @@ -1,6 +1,8 @@ import { getAssignmentRepository, getClassRepository, getGroupRepository, getSubmissionRepository } from '../data/repositories.js'; -import { AssignmentDTO, mapToAssignment, mapToAssignmentDTO, mapToAssignmentDTOId } from '../interfaces/assignment.js'; -import { mapToSubmissionDTO, mapToSubmissionDTOId, SubmissionDTO, SubmissionDTOId } from '../interfaces/submission.js'; +import { mapToAssignment, mapToAssignmentDTO, mapToAssignmentDTOId } from '../interfaces/assignment.js'; +import { mapToSubmissionDTO, mapToSubmissionDTOId } from '../interfaces/submission.js'; +import { AssignmentDTO } from '@dwengo-1/common/interfaces/assignment'; +import { SubmissionDTO, SubmissionDTOId } from '@dwengo-1/common/interfaces/submission'; import { getLogger } from '../logging/initalize.js'; export async function getAllAssignments(classid: string, full: boolean): Promise { diff --git a/backend/src/services/classes.ts b/backend/src/services/classes.ts index dc3ac8a0..fccbbee0 100644 --- a/backend/src/services/classes.ts +++ b/backend/src/services/classes.ts @@ -1,8 +1,11 @@ import { getClassRepository, getStudentRepository, getTeacherInvitationRepository, getTeacherRepository } from '../data/repositories.js'; -import { ClassDTO, mapToClassDTO } from '../interfaces/class.js'; -import { mapToStudentDTO, StudentDTO } from '../interfaces/student.js'; -import { mapToTeacherInvitationDTO, mapToTeacherInvitationDTOIds, TeacherInvitationDTO } from '../interfaces/teacher-invitation.js'; +import { mapToClassDTO } from '../interfaces/class.js'; +import { mapToStudentDTO } from '../interfaces/student.js'; +import { mapToTeacherInvitationDTO, mapToTeacherInvitationDTOIds } from '../interfaces/teacher-invitation.js'; import { getLogger } from '../logging/initalize.js'; +import { ClassDTO } from '@dwengo-1/common/interfaces/class'; +import { TeacherInvitationDTO } from '@dwengo-1/common/interfaces/teacher-invitation'; +import { StudentDTO } from '@dwengo-1/common/interfaces/student'; const logger = getLogger(); diff --git a/backend/src/services/groups.ts b/backend/src/services/groups.ts index 16895e0a..346c1ee1 100644 --- a/backend/src/services/groups.ts +++ b/backend/src/services/groups.ts @@ -6,8 +6,10 @@ import { getSubmissionRepository, } from '../data/repositories.js'; import { Group } from '../entities/assignments/group.entity.js'; -import { GroupDTO, mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js'; -import { mapToSubmissionDTO, mapToSubmissionDTOId, SubmissionDTO, SubmissionDTOId } from '../interfaces/submission.js'; +import { mapToGroupDTO, mapToGroupDTOId } from '../interfaces/group.js'; +import { mapToSubmissionDTO, mapToSubmissionDTOId } from '../interfaces/submission.js'; +import { GroupDTO } from '@dwengo-1/common/interfaces/group'; +import { SubmissionDTO, SubmissionDTOId } from '@dwengo-1/common/interfaces/submission'; import { getLogger } from '../logging/initalize.js'; export async function getGroup(classId: string, assignmentNumber: number, groupNumber: number, full: boolean): Promise { diff --git a/backend/src/services/learning-objects.ts b/backend/src/services/learning-objects.ts index 43af1aca..436c4a08 100644 --- a/backend/src/services/learning-objects.ts +++ b/backend/src/services/learning-objects.ts @@ -1,6 +1,12 @@ import { DWENGO_API_BASE } from '../config.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/interfaces/learning-content'; import { getLogger } from '../logging/initalize.js'; function filterData(data: LearningObjectMetadata, htmlUrl: string): FilteredLearningObject { diff --git a/backend/src/services/learning-objects/attachment-service.ts b/backend/src/services/learning-objects/attachment-service.ts index 4ff4ec47..46fc5e03 100644 --- a/backend/src/services/learning-objects/attachment-service.ts +++ b/backend/src/services/learning-objects/attachment-service.ts @@ -1,6 +1,7 @@ import { getAttachmentRepository } from '../../data/repositories.js'; import { Attachment } from '../../entities/content/attachment.entity.js'; -import { LearningObjectIdentifier } from '../../interfaces/learning-content.js'; + +import { LearningObjectIdentifier } from '@dwengo-1/common/interfaces/learning-content'; const attachmentService = { async getAttachment(learningObjectId: LearningObjectIdentifier, attachmentName: string): Promise { diff --git a/backend/src/services/learning-objects/database-learning-object-provider.ts b/backend/src/services/learning-objects/database-learning-object-provider.ts index a8055f2c..361153f5 100644 --- a/backend/src/services/learning-objects/database-learning-object-provider.ts +++ b/backend/src/services/learning-objects/database-learning-object-provider.ts @@ -1,5 +1,4 @@ import { LearningObjectProvider } from './learning-object-provider.js'; -import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../../interfaces/learning-content.js'; import { getLearningObjectRepository, getLearningPathRepository } from '../../data/repositories.js'; import { LearningObject } from '../../entities/content/learning-object.entity.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 learningObjectService from './learning-object-service.js'; import { getLogger, Logger } from '../../logging/initalize.js'; +import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '@dwengo-1/common/interfaces/learning-content'; const logger: Logger = getLogger(); diff --git a/backend/src/services/learning-objects/dwengo-api-learning-object-provider.ts b/backend/src/services/learning-objects/dwengo-api-learning-object-provider.ts index dfee329d..d67b69ae 100644 --- a/backend/src/services/learning-objects/dwengo-api-learning-object-provider.ts +++ b/backend/src/services/learning-objects/dwengo-api-learning-object-provider.ts @@ -1,5 +1,8 @@ import { DWENGO_API_BASE } from '../../config.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 { FilteredLearningObject, LearningObjectIdentifier, @@ -7,10 +10,7 @@ import { LearningObjectNode, LearningPathIdentifier, LearningPathResponse, -} from '../../interfaces/learning-content.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'; +} from '@dwengo-1/common/interfaces/learning-content'; const logger: Logger = getLogger(); @@ -66,12 +66,13 @@ async function fetchLearningObjects(learningPathId: LearningPathIdentifier, full } const objects = await Promise.all( - nodes.map(async (node) => - dwengoApiLearningObjectProvider.getLearningObjectById({ + nodes.map(async (node) => { + const learningObjectId: LearningObjectIdentifier = { hruid: node.learningobject_hruid, language: learningPathId.language, - }) - ) + }; + return dwengoApiLearningObjectProvider.getLearningObjectById(learningObjectId); + }) ); return objects.filter((obj): obj is FilteredLearningObject => obj !== null); } catch (error) { @@ -90,7 +91,7 @@ const dwengoApiLearningObjectProvider: LearningObjectProvider = { metadataUrl, `Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`, { - params: id, + params: { ...id }, } ); @@ -123,7 +124,7 @@ const dwengoApiLearningObjectProvider: LearningObjectProvider = { async getLearningObjectHTML(id: LearningObjectIdentifier): Promise { const htmlUrl = `${DWENGO_API_BASE}/learningObject/getRaw`; const html = await fetchWithLogging(htmlUrl, `Metadata for Learning Object HRUID "${id.hruid}" (language ${id.language})`, { - params: id, + params: { ...id }, }); if (!html) { diff --git a/backend/src/services/learning-objects/learning-object-provider.ts b/backend/src/services/learning-objects/learning-object-provider.ts index 81b4d228..a0fcb552 100644 --- a/backend/src/services/learning-objects/learning-object-provider.ts +++ b/backend/src/services/learning-objects/learning-object-provider.ts @@ -1,4 +1,4 @@ -import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../../interfaces/learning-content.js'; +import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '@dwengo-1/common/interfaces/learning-content'; export interface LearningObjectProvider { /** diff --git a/backend/src/services/learning-objects/learning-object-service.ts b/backend/src/services/learning-objects/learning-object-service.ts index 59ffb643..5a06f0f2 100644 --- a/backend/src/services/learning-objects/learning-object-service.ts +++ b/backend/src/services/learning-objects/learning-object-service.ts @@ -1,8 +1,8 @@ -import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '../../interfaces/learning-content.js'; import dwengoApiLearningObjectProvider from './dwengo-api-learning-object-provider.js'; import { LearningObjectProvider } from './learning-object-provider.js'; import { envVars, getEnvVar } from '../../util/envVars.js'; import databaseLearningObjectProvider from './database-learning-object-provider.js'; +import { FilteredLearningObject, LearningObjectIdentifier, LearningPathIdentifier } from '@dwengo-1/common/interfaces/learning-content'; function getProvider(id: LearningObjectIdentifier): LearningObjectProvider { if (id.hruid.startsWith(getEnvVar(envVars.UserContentPrefix))) { diff --git a/backend/src/services/learning-objects/processing/markdown/dwengo-marked-renderer.ts b/backend/src/services/learning-objects/processing/markdown/dwengo-marked-renderer.ts index d1c797be..87ba13b7 100644 --- a/backend/src/services/learning-objects/processing/markdown/dwengo-marked-renderer.ts +++ b/backend/src/services/learning-objects/processing/markdown/dwengo-marked-renderer.ts @@ -8,13 +8,12 @@ import InlineImageProcessor from '../image/inline-image-processor.js'; import * as marked from 'marked'; import { getUrlStringForLearningObjectHTML, isValidHttpUrl } from '../../../../util/links.js'; import { ProcessingError } from '../processing-error.js'; -import { LearningObjectIdentifier } from '../../../../interfaces/learning-content.js'; -import { Language } from '../../../../entities/content/language.js'; - import Image = marked.Tokens.Image; import Heading = marked.Tokens.Heading; import Link = marked.Tokens.Link; import RendererObject = marked.RendererObject; +import { LearningObjectIdentifier } from '@dwengo-1/common/interfaces/learning-content'; +import { Language } from '@dwengo-1/common/util/language'; const prefixes = { learningObject: '@learning-object', diff --git a/backend/src/services/learning-objects/processing/processing-service.ts b/backend/src/services/learning-objects/processing/processing-service.ts index f731eb5d..e9147e31 100644 --- a/backend/src/services/learning-objects/processing/processing-service.ts +++ b/backend/src/services/learning-objects/processing/processing-service.ts @@ -13,9 +13,9 @@ import GiftProcessor from './gift/gift-processor.js'; import { LearningObject } from '../../../entities/content/learning-object.entity.js'; import Processor from './processor.js'; import { DwengoContentType } from './content-type.js'; -import { LearningObjectIdentifier } from '../../../interfaces/learning-content.js'; -import { Language } from '../../../entities/content/language.js'; import { replaceAsync } from '../../../util/async.js'; +import { LearningObjectIdentifier } from '@dwengo-1/common/interfaces/learning-content'; +import { Language } from '@dwengo-1/common/util/language'; const EMBEDDED_LEARNING_OBJECT_PLACEHOLDER = //g; const LEARNING_OBJECT_DOES_NOT_EXIST = "
"; diff --git a/backend/src/services/learning-paths/database-learning-path-provider.ts b/backend/src/services/learning-paths/database-learning-path-provider.ts index 3d883ef2..ba312b08 100644 --- a/backend/src/services/learning-paths/database-learning-path-provider.ts +++ b/backend/src/services/learning-paths/database-learning-path-provider.ts @@ -1,12 +1,18 @@ 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 { getLearningPathRepository } from '../../data/repositories.js'; -import { Language } from '../../entities/content/language.js'; import learningObjectService from '../learning-objects/learning-object-service.js'; import { LearningPathNode } from '../../entities/content/learning-path-node.entity.js'; import { LearningPathTransition } from '../../entities/content/learning-path-transition.entity.js'; import { getLastSubmissionForCustomizationTarget, isTransitionPossible, PersonalizationTarget } from './learning-path-personalization-util.js'; +import { + FilteredLearningObject, + LearningObjectNode, + LearningPath, + LearningPathResponse, + Transition, +} from '@dwengo-1/common/interfaces/learning-content'; +import { Language } from '@dwengo-1/common/util/language'; /** * Fetches the corresponding learning object for each of the nodes and creates a map that maps each node to its diff --git a/backend/src/services/learning-paths/dwengo-api-learning-path-provider.ts b/backend/src/services/learning-paths/dwengo-api-learning-path-provider.ts index a6093bb4..110cd570 100644 --- a/backend/src/services/learning-paths/dwengo-api-learning-path-provider.ts +++ b/backend/src/services/learning-paths/dwengo-api-learning-path-provider.ts @@ -1,8 +1,8 @@ import { fetchWithLogging } from '../../util/api-helper.js'; import { DWENGO_API_BASE } from '../../config.js'; -import { LearningPath, LearningPathResponse } from '../../interfaces/learning-content.js'; import { LearningPathProvider } from './learning-path-provider.js'; import { getLogger, Logger } from '../../logging/initalize.js'; +import { LearningPath, LearningPathResponse } from '@dwengo-1/common/interfaces/learning-content'; const logger: Logger = getLogger(); diff --git a/backend/src/services/learning-paths/learning-path-provider.ts b/backend/src/services/learning-paths/learning-path-provider.ts index 5e2a09df..3bf734e7 100644 --- a/backend/src/services/learning-paths/learning-path-provider.ts +++ b/backend/src/services/learning-paths/learning-path-provider.ts @@ -1,6 +1,6 @@ -import { LearningPath, LearningPathResponse } from '../../interfaces/learning-content.js'; -import { Language } from '../../entities/content/language.js'; +import { LearningPath, LearningPathResponse } from '@dwengo-1/common/interfaces/learning-content'; import { PersonalizationTarget } from './learning-path-personalization-util.js'; +import { Language } from '@dwengo-1/common/util/language'; /** * Generic interface for a service which provides access to learning paths from a data source. diff --git a/backend/src/services/learning-paths/learning-path-service.ts b/backend/src/services/learning-paths/learning-path-service.ts index f8e328b2..0e4d2c5e 100644 --- a/backend/src/services/learning-paths/learning-path-service.ts +++ b/backend/src/services/learning-paths/learning-path-service.ts @@ -1,9 +1,9 @@ -import { LearningPath, LearningPathResponse } from '../../interfaces/learning-content.js'; import dwengoApiLearningPathProvider from './dwengo-api-learning-path-provider.js'; import databaseLearningPathProvider from './database-learning-path-provider.js'; import { envVars, getEnvVar } from '../../util/envVars.js'; -import { Language } from '../../entities/content/language.js'; import { PersonalizationTarget } from './learning-path-personalization-util.js'; +import { LearningPath, LearningPathResponse } from '@dwengo-1/common/interfaces/learning-content'; +import { Language } from '@dwengo-1/common/util/language'; const userContentPrefix = getEnvVar(envVars.UserContentPrefix); const allProviders = [dwengoApiLearningPathProvider, databaseLearningPathProvider]; diff --git a/backend/src/services/questions.ts b/backend/src/services/questions.ts index ac1095bf..f92efae0 100644 --- a/backend/src/services/questions.ts +++ b/backend/src/services/questions.ts @@ -1,11 +1,13 @@ import { getAnswerRepository, getQuestionRepository } from '../data/repositories.js'; -import { mapToQuestionDTO, mapToQuestionId, QuestionDTO, QuestionId } from '../interfaces/question.js'; +import { mapToQuestionDTO, mapToQuestionId } from '../interfaces/question.js'; import { Question } from '../entities/questions/question.entity.js'; import { Answer } from '../entities/questions/answer.entity.js'; -import { AnswerDTO, AnswerId, mapToAnswerDTO, mapToAnswerId } from '../interfaces/answer.js'; +import { mapToAnswerDTO, mapToAnswerId } from '../interfaces/answer.js'; import { QuestionRepository } from '../data/questions/question-repository.js'; import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js'; import { mapToStudent } from '../interfaces/student.js'; +import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; +import { AnswerDTO, AnswerId } from '@dwengo-1/common/interfaces/answer'; export async function getAllQuestions(id: LearningObjectIdentifier, full: boolean): Promise { const questionRepository: QuestionRepository = getQuestionRepository(); @@ -73,9 +75,14 @@ export async function createQuestion(questionDTO: QuestionDTO): Promise { diff --git a/backend/src/services/submissions.ts b/backend/src/services/submissions.ts index a456d9d1..1d8a7874 100644 --- a/backend/src/services/submissions.ts +++ b/backend/src/services/submissions.ts @@ -1,7 +1,8 @@ import { getSubmissionRepository } from '../data/repositories.js'; -import { Language } from '../entities/content/language.js'; import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js'; -import { mapToSubmission, mapToSubmissionDTO, SubmissionDTO } from '../interfaces/submission.js'; +import { mapToSubmission, mapToSubmissionDTO } from '../interfaces/submission.js'; +import { SubmissionDTO } from '@dwengo-1/common/interfaces/submission'; +import { Language } from '@dwengo-1/common/util/language'; export async function getSubmission( learningObjectHruid: string, diff --git a/backend/src/services/teachers.ts b/backend/src/services/teachers.ts index b2aefe63..3986462b 100644 --- a/backend/src/services/teachers.ts +++ b/backend/src/services/teachers.ts @@ -1,9 +1,12 @@ import { getClassRepository, getLearningObjectRepository, getQuestionRepository, getTeacherRepository } from '../data/repositories.js'; -import { ClassDTO, mapToClassDTO } from '../interfaces/class.js'; +import { mapToClassDTO } from '../interfaces/class.js'; import { getClassStudents } from './classes.js'; -import { StudentDTO } from '../interfaces/student.js'; -import { mapToQuestionDTO, mapToQuestionId, QuestionDTO, QuestionId } from '../interfaces/question.js'; -import { mapToTeacher, mapToTeacherDTO, TeacherDTO } from '../interfaces/teacher.js'; +import { mapToQuestionDTO, mapToQuestionId } from '../interfaces/question.js'; +import { mapToTeacher, mapToTeacherDTO } from '../interfaces/teacher.js'; +import { ClassDTO } from '@dwengo-1/common/interfaces/class'; +import { TeacherDTO } from '@dwengo-1/common/interfaces/teacher'; +import { StudentDTO } from '@dwengo-1/common/interfaces/student'; +import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; import { getLogger } from '../logging/initalize.js'; export async function getAllTeachers(full: boolean): Promise { diff --git a/backend/src/util/api-helper.ts b/backend/src/util/api-helper.ts index 9aac5bd1..af36532d 100644 --- a/backend/src/util/api-helper.ts +++ b/backend/src/util/api-helper.ts @@ -1,6 +1,6 @@ import axios, { AxiosRequestConfig } from 'axios'; 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(); diff --git a/backend/src/util/links.ts b/backend/src/util/links.ts index ff334eb5..9ede7d12 100644 --- a/backend/src/util/links.ts +++ b/backend/src/util/links.ts @@ -1,4 +1,4 @@ -import { LearningObjectIdentifier } from '../interfaces/learning-content'; +import { LearningObjectIdentifier } from '@dwengo-1/common/interfaces/learning-content'; export function isValidHttpUrl(url: string): boolean { try { diff --git a/backend/tests/data/assignments/submissions.test.ts b/backend/tests/data/assignments/submissions.test.ts index cd212b77..85e1bc11 100644 --- a/backend/tests/data/assignments/submissions.test.ts +++ b/backend/tests/data/assignments/submissions.test.ts @@ -9,7 +9,7 @@ import { getSubmissionRepository, } from '../../../src/data/repositories'; import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { StudentRepository } from '../../../src/data/users/student-repository'; import { GroupRepository } from '../../../src/data/assignments/group-repository'; import { AssignmentRepository } from '../../../src/data/assignments/assignment-repository'; diff --git a/backend/tests/data/content/attachments.test.ts b/backend/tests/data/content/attachments.test.ts index 94e132a9..4e65954e 100644 --- a/backend/tests/data/content/attachments.test.ts +++ b/backend/tests/data/content/attachments.test.ts @@ -4,7 +4,7 @@ import { getAttachmentRepository, getLearningObjectRepository } from '../../../s import { AttachmentRepository } from '../../../src/data/content/attachment-repository.js'; import { LearningObjectRepository } from '../../../src/data/content/learning-object-repository.js'; import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier.js'; -import { Language } from '../../../src/entities/content/language.js'; +import { Language } from '@dwengo-1/common/util/language'; describe('AttachmentRepository', () => { let attachmentRepository: AttachmentRepository; diff --git a/backend/tests/data/content/learning-objects.test.ts b/backend/tests/data/content/learning-objects.test.ts index 712f75c9..3c9d5dde 100644 --- a/backend/tests/data/content/learning-objects.test.ts +++ b/backend/tests/data/content/learning-objects.test.ts @@ -3,7 +3,7 @@ import { LearningObjectRepository } from '../../../src/data/content/learning-obj import { getLearningObjectRepository } from '../../../src/data/repositories'; import { setupTestApp } from '../../setup-tests'; import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; describe('LearningObjectRepository', () => { let learningObjectRepository: LearningObjectRepository; diff --git a/backend/tests/data/content/learning-path-repository.test.ts b/backend/tests/data/content/learning-path-repository.test.ts index 4424fced..bdf5377e 100644 --- a/backend/tests/data/content/learning-path-repository.test.ts +++ b/backend/tests/data/content/learning-path-repository.test.ts @@ -5,7 +5,7 @@ import { LearningPathRepository } from '../../../src/data/content/learning-path- import example from '../../test-assets/learning-paths/pn-werking-example.js'; import { LearningPath } from '../../../src/entities/content/learning-path.entity.js'; import { expectToBeCorrectEntity } from '../../test-utils/expectations.js'; -import { Language } from '../../../src/entities/content/language.js'; +import { Language } from '@dwengo-1/common/util/language'; function expectToHaveFoundPrecisely(expected: LearningPath, result: LearningPath[]): void { expect(result).toHaveProperty('length'); diff --git a/backend/tests/data/content/learning-paths.test.ts b/backend/tests/data/content/learning-paths.test.ts index 01fd20e5..683e1d40 100644 --- a/backend/tests/data/content/learning-paths.test.ts +++ b/backend/tests/data/content/learning-paths.test.ts @@ -2,7 +2,7 @@ import { beforeAll, describe, expect, it } from 'vitest'; import { getLearningPathRepository } from '../../../src/data/repositories'; import { LearningPathRepository } from '../../../src/data/content/learning-path-repository'; import { setupTestApp } from '../../setup-tests'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; describe('LearningPathRepository', () => { let learningPathRepository: LearningPathRepository; diff --git a/backend/tests/data/questions/answers.test.ts b/backend/tests/data/questions/answers.test.ts index 59917c3f..80cd3034 100644 --- a/backend/tests/data/questions/answers.test.ts +++ b/backend/tests/data/questions/answers.test.ts @@ -4,7 +4,7 @@ import { AnswerRepository } from '../../../src/data/questions/answer-repository' import { getAnswerRepository, getQuestionRepository, getTeacherRepository } from '../../../src/data/repositories'; import { QuestionRepository } from '../../../src/data/questions/question-repository'; import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { TeacherRepository } from '../../../src/data/users/teacher-repository'; describe('AnswerRepository', () => { diff --git a/backend/tests/data/questions/questions.test.ts b/backend/tests/data/questions/questions.test.ts index c1d2b483..055a9d79 100644 --- a/backend/tests/data/questions/questions.test.ts +++ b/backend/tests/data/questions/questions.test.ts @@ -4,7 +4,7 @@ import { QuestionRepository } from '../../../src/data/questions/question-reposit import { getQuestionRepository, getStudentRepository } from '../../../src/data/repositories'; import { StudentRepository } from '../../../src/data/users/student-repository'; import { LearningObjectIdentifier } from '../../../src/entities/content/learning-object-identifier'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; describe('QuestionRepository', () => { let questionRepository: QuestionRepository; diff --git a/backend/tests/services/learning-objects/database-learning-object-provider.test.ts b/backend/tests/services/learning-objects/database-learning-object-provider.test.ts index 2c3b7dfc..31899ded 100644 --- a/backend/tests/services/learning-objects/database-learning-object-provider.test.ts +++ b/backend/tests/services/learning-objects/database-learning-object-provider.test.ts @@ -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 databaseLearningObjectProvider from '../../../src/services/learning-objects/database-learning-object-provider'; import { expectToBeCorrectFilteredLearningObject } from '../../test-utils/expectations'; -import { FilteredLearningObject } from '../../../src/interfaces/learning-content'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import learningObjectExample from '../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example'; import learningPathExample from '../../test-assets/learning-paths/pn-werking-example'; import { LearningPath } from '../../../src/entities/content/learning-path.entity'; +import { FilteredLearningObject } from '@dwengo-1/common/interfaces/learning-content'; async function initExampleData(): Promise<{ learningObject: LearningObject; learningPath: LearningPath }> { const learningObjectRepo = getLearningObjectRepository(); @@ -37,7 +37,7 @@ describe('DatabaseLearningObjectProvider', () => { it('should return the learning object when it is queried by its id', async () => { const result: FilteredLearningObject | null = await databaseLearningObjectProvider.getLearningObjectById(exampleLearningObject); expect(result).toBeTruthy(); - expectToBeCorrectFilteredLearningObject(result!, exampleLearningObject); + expectToBeCorrectFilteredLearningObject(result, exampleLearningObject); }); it('should return the learning object when it is queried by only hruid and language (but not version)', async () => { @@ -46,7 +46,7 @@ describe('DatabaseLearningObjectProvider', () => { language: exampleLearningObject.language, }); expect(result).toBeTruthy(); - expectToBeCorrectFilteredLearningObject(result!, exampleLearningObject); + expectToBeCorrectFilteredLearningObject(result, exampleLearningObject); }); it('should return null when queried with an id that does not exist', async () => { diff --git a/backend/tests/services/learning-objects/learning-object-service.test.ts b/backend/tests/services/learning-objects/learning-object-service.test.ts index f284b939..a0fea849 100644 --- a/backend/tests/services/learning-objects/learning-object-service.test.ts +++ b/backend/tests/services/learning-objects/learning-object-service.test.ts @@ -4,11 +4,11 @@ import { LearningObject } from '../../../src/entities/content/learning-object.en import { getLearningObjectRepository, getLearningPathRepository } from '../../../src/data/repositories'; import learningObjectExample from '../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example'; 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 { envVars, getEnvVar } from '../../../src/util/envVars'; import { LearningPath } from '../../../src/entities/content/learning-path.entity'; import learningPathExample from '../../test-assets/learning-paths/pn-werking-example'; +import { LearningObjectIdentifier, LearningPathIdentifier } from '@dwengo-1/common/interfaces/learning-content'; +import { Language } from '@dwengo-1/common/util/language'; const EXPECTED_DWENGO_LEARNING_OBJECT_TITLE = 'Werken met notebooks'; const DWENGO_TEST_LEARNING_OBJECT_ID: LearningObjectIdentifier = { @@ -105,8 +105,11 @@ describe('LearningObjectService', () => { 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 () => { - const result = await learningObjectService.getLearningObjectsFromPath({ hruid: 'non_existing', language: Language.Dutch }); - expect(result).toEqual([]); + const result = await learningObjectService.getLearningObjectsFromPath({ + hruid: 'non_existing', + language: Language.Dutch, + }); + expect(result).toStrictEqual([]); }); }); @@ -120,8 +123,11 @@ describe('LearningObjectService', () => { 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 () => { - const result = await learningObjectService.getLearningObjectIdsFromPath({ hruid: 'non_existing', language: Language.Dutch }); - expect(result).toEqual([]); + const result = await learningObjectService.getLearningObjectIdsFromPath({ + hruid: 'non_existing', + language: Language.Dutch, + }); + expect(result).toStrictEqual([]); }); }); }); diff --git a/backend/tests/services/learning-path/database-learning-path-provider.test.ts b/backend/tests/services/learning-path/database-learning-path-provider.test.ts index a5943f5f..b8a733e7 100644 --- a/backend/tests/services/learning-path/database-learning-path-provider.test.ts +++ b/backend/tests/services/learning-path/database-learning-path-provider.test.ts @@ -13,13 +13,14 @@ import learningPathExample from '../../test-assets/learning-paths/pn-werking-exa import databaseLearningPathProvider from '../../../src/services/learning-paths/database-learning-path-provider.js'; import { expectToBeCorrectLearningPath } from '../../test-utils/expectations.js'; import learningObjectService from '../../../src/services/learning-objects/learning-object-service.js'; -import { Language } from '../../../src/entities/content/language.js'; +import { Language } from '@dwengo-1/common/util/language'; import { ConditionTestLearningPathAndLearningObjects, createConditionTestLearningPathAndLearningObjects, } from '../../test-assets/learning-paths/test-conditions-example.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/interfaces/learning-content'; async function initExampleData(): Promise<{ learningObject: LearningObject; learningPath: LearningPath }> { const learningObjectRepo = getLearningObjectRepository(); diff --git a/backend/tests/services/learning-path/learning-path-service.test.ts b/backend/tests/services/learning-path/learning-path-service.test.ts index 7a45dc43..972a7fa1 100644 --- a/backend/tests/services/learning-path/learning-path-service.test.ts +++ b/backend/tests/services/learning-path/learning-path-service.test.ts @@ -5,8 +5,8 @@ import { LearningPath } from '../../../src/entities/content/learning-path.entity import { getLearningObjectRepository, getLearningPathRepository } from '../../../src/data/repositories'; import learningObjectExample from '../../test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example'; import learningPathExample from '../../test-assets/learning-paths/pn-werking-example'; -import { Language } from '../../../src/entities/content/language'; import learningPathService from '../../../src/services/learning-paths/learning-path-service'; +import { Language } from '@dwengo-1/common/util/language'; async function initExampleData(): Promise<{ learningObject: LearningObject; learningPath: LearningPath }> { const learningObjectRepo = getLearningObjectRepository(); @@ -48,8 +48,8 @@ describe('LearningPathService', () => { expect(result.data?.length).toBe(1); // Should include all the nodes, even those pointing to foreign learning objects. - expect([...result.data![0].nodes.map((it) => it.learningobject_hruid)].sort()).toEqual( - example.learningPath.nodes.map((it) => it.learningObjectHruid).sort() + expect([...result.data![0].nodes.map((it) => it.learningobject_hruid)].sort((a, b) => a.localeCompare(b))).toEqual( + example.learningPath.nodes.map((it) => it.learningObjectHruid).sort((a, b) => a.localeCompare(b)) ); }); }); diff --git a/backend/tests/test-assets/learning-objects/dummy/dummy-learning-object-example.ts b/backend/tests/test-assets/learning-objects/dummy/dummy-learning-object-example.ts index f810d57a..6889c93b 100644 --- a/backend/tests/test-assets/learning-objects/dummy/dummy-learning-object-example.ts +++ b/backend/tests/test-assets/learning-objects/dummy/dummy-learning-object-example.ts @@ -1,6 +1,6 @@ import { LearningObjectExample } from '../learning-object-example'; import { LearningObject } from '../../../../src/entities/content/learning-object.entity'; -import { Language } from '../../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { loadTestAsset } from '../../../test-utils/load-test-asset'; import { DwengoContentType } from '../../../../src/services/learning-objects/processing/content-type'; import { envVars, getEnvVar } from '../../../../src/util/envVars'; diff --git a/backend/tests/test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example.ts b/backend/tests/test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example.ts index 835a0ed0..ab0c8640 100644 --- a/backend/tests/test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example.ts +++ b/backend/tests/test-assets/learning-objects/pn-werkingnotebooks/pn-werkingnotebooks-example.ts @@ -1,5 +1,5 @@ import { LearningObjectExample } from '../learning-object-example'; -import { Language } from '../../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { DwengoContentType } from '../../../../src/services/learning-objects/processing/content-type'; import { loadTestAsset } from '../../../test-utils/load-test-asset'; import { LearningObject } from '../../../../src/entities/content/learning-object.entity'; diff --git a/backend/tests/test-assets/learning-objects/test-essay/test-essay-example.ts b/backend/tests/test-assets/learning-objects/test-essay/test-essay-example.ts index 943a10c7..5a444fc0 100644 --- a/backend/tests/test-assets/learning-objects/test-essay/test-essay-example.ts +++ b/backend/tests/test-assets/learning-objects/test-essay/test-essay-example.ts @@ -2,7 +2,7 @@ import { LearningObjectExample } from '../learning-object-example'; import { LearningObject } from '../../../../src/entities/content/learning-object.entity'; import { loadTestAsset } from '../../../test-utils/load-test-asset'; import { envVars, getEnvVar } from '../../../../src/util/envVars'; -import { Language } from '../../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { DwengoContentType } from '../../../../src/services/learning-objects/processing/content-type'; const example: LearningObjectExample = { diff --git a/backend/tests/test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example.ts b/backend/tests/test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example.ts index 276a41bb..129665ae 100644 --- a/backend/tests/test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example.ts +++ b/backend/tests/test-assets/learning-objects/test-multiple-choice/test-multiple-choice-example.ts @@ -2,8 +2,8 @@ import { LearningObjectExample } from '../learning-object-example'; import { LearningObject } from '../../../../src/entities/content/learning-object.entity'; import { loadTestAsset } from '../../../test-utils/load-test-asset'; import { envVars, getEnvVar } from '../../../../src/util/envVars'; -import { Language } from '../../../../src/entities/content/language'; import { DwengoContentType } from '../../../../src/services/learning-objects/processing/content-type'; +import { Language } from '@dwengo-1/common/util/language'; const example: LearningObjectExample = { createLearningObject: () => { diff --git a/backend/tests/test-assets/learning-paths/learning-path-utils.ts b/backend/tests/test-assets/learning-paths/learning-path-utils.ts index eb786fe1..177d905f 100644 --- a/backend/tests/test-assets/learning-paths/learning-path-utils.ts +++ b/backend/tests/test-assets/learning-paths/learning-path-utils.ts @@ -1,4 +1,4 @@ -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { LearningPathTransition } from '../../../src/entities/content/learning-path-transition.entity'; import { LearningPathNode } from '../../../src/entities/content/learning-path-node.entity'; import { LearningPath } from '../../../src/entities/content/learning-path.entity'; diff --git a/backend/tests/test-assets/learning-paths/pn-werking-example.ts b/backend/tests/test-assets/learning-paths/pn-werking-example.ts index 06a29007..1ac1c40d 100644 --- a/backend/tests/test-assets/learning-paths/pn-werking-example.ts +++ b/backend/tests/test-assets/learning-paths/pn-werking-example.ts @@ -1,5 +1,5 @@ import { LearningPath } from '../../../src/entities/content/learning-path.entity'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { envVars, getEnvVar } from '../../../src/util/envVars'; import { createLearningPathNode, createLearningPathTransition } from './learning-path-utils'; import { LearningPathNode } from '../../../src/entities/content/learning-path-node.entity'; diff --git a/backend/tests/test-assets/learning-paths/test-conditions-example.ts b/backend/tests/test-assets/learning-paths/test-conditions-example.ts index b5e38c24..0fb7ead5 100644 --- a/backend/tests/test-assets/learning-paths/test-conditions-example.ts +++ b/backend/tests/test-assets/learning-paths/test-conditions-example.ts @@ -1,5 +1,5 @@ import { LearningPath } from '../../../src/entities/content/learning-path.entity'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import testMultipleChoiceExample from '../learning-objects/test-multiple-choice/test-multiple-choice-example'; import { dummyLearningObject } from '../learning-objects/dummy/dummy-learning-object-example'; import { createLearningPathNode, createLearningPathTransition } from './learning-path-utils'; diff --git a/backend/tests/test-utils/expectations.ts b/backend/tests/test-utils/expectations.ts index c3fa5a43..b6462702 100644 --- a/backend/tests/test-utils/expectations.ts +++ b/backend/tests/test-utils/expectations.ts @@ -1,8 +1,8 @@ import { AssertionError } from 'node:assert'; 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 { expect } from 'vitest'; +import { FilteredLearningObject, LearningPath } from '@dwengo-1/common/interfaces/learning-content'; // Ignored properties because they belang for example to the class, not to the entity itself. const IGNORE_PROPERTIES = ['parent']; diff --git a/backend/tests/test_assets/assignments/assignments.testdata.ts b/backend/tests/test_assets/assignments/assignments.testdata.ts index 8753b0ce..b0da638f 100644 --- a/backend/tests/test_assets/assignments/assignments.testdata.ts +++ b/backend/tests/test_assets/assignments/assignments.testdata.ts @@ -1,7 +1,7 @@ import { EntityManager } from '@mikro-orm/core'; import { Assignment } from '../../../src/entities/assignments/assignment.entity'; import { Class } from '../../../src/entities/classes/class.entity'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; export function makeTestAssignemnts(em: EntityManager, classes: Class[]): Assignment[] { const assignment01 = em.create(Assignment, { diff --git a/backend/tests/test_assets/assignments/submission.testdata.ts b/backend/tests/test_assets/assignments/submission.testdata.ts index 4fca5f9b..f454b133 100644 --- a/backend/tests/test_assets/assignments/submission.testdata.ts +++ b/backend/tests/test_assets/assignments/submission.testdata.ts @@ -1,6 +1,6 @@ import { EntityManager } from '@mikro-orm/core'; import { Submission } from '../../../src/entities/assignments/submission.entity'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { Student } from '../../../src/entities/users/student.entity'; import { Group } from '../../../src/entities/assignments/group.entity'; diff --git a/backend/tests/test_assets/classes/class-join-requests.testdata.ts b/backend/tests/test_assets/classes/class-join-requests.testdata.ts index 632fd392..32337b19 100644 --- a/backend/tests/test_assets/classes/class-join-requests.testdata.ts +++ b/backend/tests/test_assets/classes/class-join-requests.testdata.ts @@ -1,7 +1,8 @@ import { EntityManager } from '@mikro-orm/core'; -import { ClassJoinRequest, ClassJoinRequestStatus } from '../../../src/entities/classes/class-join-request.entity'; +import { ClassJoinRequest } from '../../../src/entities/classes/class-join-request.entity'; import { Student } from '../../../src/entities/users/student.entity'; import { Class } from '../../../src/entities/classes/class.entity'; +import { ClassJoinRequestStatus } from '@dwengo-1/common/util/class-join-request'; export function makeTestClassJoinRequests(em: EntityManager, students: Student[], classes: Class[]): ClassJoinRequest[] { const classJoinRequest01 = em.create(ClassJoinRequest, { diff --git a/backend/tests/test_assets/content/learning-objects.testdata.ts b/backend/tests/test_assets/content/learning-objects.testdata.ts index bbca8830..6e28dc16 100644 --- a/backend/tests/test_assets/content/learning-objects.testdata.ts +++ b/backend/tests/test_assets/content/learning-objects.testdata.ts @@ -1,6 +1,6 @@ import { EntityManager } from '@mikro-orm/core'; import { LearningObject } from '../../../src/entities/content/learning-object.entity'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { DwengoContentType } from '../../../src/services/learning-objects/processing/content-type'; import { ReturnValue } from '../../../src/entities/content/return-value.entity'; diff --git a/backend/tests/test_assets/content/learning-paths.testdata.ts b/backend/tests/test_assets/content/learning-paths.testdata.ts index e41773cc..72581f42 100644 --- a/backend/tests/test_assets/content/learning-paths.testdata.ts +++ b/backend/tests/test_assets/content/learning-paths.testdata.ts @@ -1,6 +1,6 @@ import { EntityManager } from '@mikro-orm/core'; import { LearningPath } from '../../../src/entities/content/learning-path.entity'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { LearningPathTransition } from '../../../src/entities/content/learning-path-transition.entity'; import { LearningPathNode } from '../../../src/entities/content/learning-path-node.entity'; diff --git a/backend/tests/test_assets/questions/questions.testdata.ts b/backend/tests/test_assets/questions/questions.testdata.ts index 8604cf07..dff742bb 100644 --- a/backend/tests/test_assets/questions/questions.testdata.ts +++ b/backend/tests/test_assets/questions/questions.testdata.ts @@ -1,6 +1,6 @@ import { EntityManager } from '@mikro-orm/core'; import { Question } from '../../../src/entities/questions/question.entity'; -import { Language } from '../../../src/entities/content/language'; +import { Language } from '@dwengo-1/common/util/language'; import { Student } from '../../../src/entities/users/student.entity'; export function makeTestQuestions(em: EntityManager, students: Student[]): Question[] { diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 2dd3998d..1ddfe1e0 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -3,7 +3,11 @@ "include": ["src/**/*.ts"], "compilerOptions": { "rootDir": "./src", - "outDir": "./dist", - "resolveJsonModule": true - } + "outDir": "./dist" + }, + "references": [ + { + "path": "../common" + } + ] } diff --git a/common/package.json b/common/package.json new file mode 100644 index 00000000..7eef4ded --- /dev/null +++ b/common/package.json @@ -0,0 +1,21 @@ +{ + "name": "@dwengo-1/common", + "version": "0.1.1", + "description": "Common types and utilities for Dwengo-1", + "private": true, + "type": "module", + "files": [ + "./dist" + ], + "scripts": { + "build": "tsc --build", + "clean": "tsc --build --clean", + "watch": "tsc --build --watch", + "format": "prettier --write src/", + "format-check": "prettier --check src/", + "lint": "eslint . --fix" + }, + "exports": { + "./*": "./dist/*.js" + } +} diff --git a/common/src/interfaces/answer.ts b/common/src/interfaces/answer.ts new file mode 100644 index 00000000..e9280f8a --- /dev/null +++ b/common/src/interfaces/answer.ts @@ -0,0 +1,16 @@ +import { UserDTO } from './user'; +import { QuestionDTO, QuestionId } from './question'; + +export interface AnswerDTO { + author: UserDTO; + toQuestion: QuestionDTO; + sequenceNumber: number; + timestamp: string; + content: string; +} + +export interface AnswerId { + author: string; + toQuestion: QuestionId; + sequenceNumber: number; +} diff --git a/common/src/interfaces/assignment.ts b/common/src/interfaces/assignment.ts new file mode 100644 index 00000000..8ad1649b --- /dev/null +++ b/common/src/interfaces/assignment.ts @@ -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 +} diff --git a/common/src/interfaces/class.ts b/common/src/interfaces/class.ts new file mode 100644 index 00000000..c35c2dfc --- /dev/null +++ b/common/src/interfaces/class.ts @@ -0,0 +1,7 @@ +export interface ClassDTO { + id: string; + displayName: string; + teachers: string[]; + students: string[]; + joinRequests: string[]; +} diff --git a/common/src/interfaces/group.ts b/common/src/interfaces/group.ts new file mode 100644 index 00000000..ca95770a --- /dev/null +++ b/common/src/interfaces/group.ts @@ -0,0 +1,8 @@ +import { AssignmentDTO } from './assignment'; +import { StudentDTO } from './student'; + +export interface GroupDTO { + assignment: number | AssignmentDTO; + groupNumber: number; + members: string[] | StudentDTO[]; +} diff --git a/backend/src/interfaces/learning-content.ts b/common/src/interfaces/learning-content.ts similarity index 97% rename from backend/src/interfaces/learning-content.ts rename to common/src/interfaces/learning-content.ts index 693aec37..02e49648 100644 --- a/backend/src/interfaces/learning-content.ts +++ b/common/src/interfaces/learning-content.ts @@ -1,4 +1,4 @@ -import { Language } from '../entities/content/language'; +import { Language } from '../util/language'; export interface Transition { default: boolean; diff --git a/common/src/interfaces/question.ts b/common/src/interfaces/question.ts new file mode 100644 index 00000000..b80ff0af --- /dev/null +++ b/common/src/interfaces/question.ts @@ -0,0 +1,15 @@ +import { LearningObjectIdentifier } from './learning-content'; +import { StudentDTO } from './student'; + +export interface QuestionDTO { + learningObjectIdentifier: LearningObjectIdentifier; + sequenceNumber?: number; + author: StudentDTO; + timestamp?: string; + content: string; +} + +export interface QuestionId { + learningObjectIdentifier: LearningObjectIdentifier; + sequenceNumber: number; +} diff --git a/common/src/interfaces/student.ts b/common/src/interfaces/student.ts new file mode 100644 index 00000000..7ec628b4 --- /dev/null +++ b/common/src/interfaces/student.ts @@ -0,0 +1,6 @@ +export interface StudentDTO { + id: string; + username: string; + firstName: string; + lastName: string; +} diff --git a/common/src/interfaces/submission.ts b/common/src/interfaces/submission.ts new file mode 100644 index 00000000..6b250616 --- /dev/null +++ b/common/src/interfaces/submission.ts @@ -0,0 +1,22 @@ +import { GroupDTO } from './group'; +import { LearningObjectIdentifier } from './learning-content'; +import { StudentDTO } from './student'; +import { Language } from '../util/language'; + +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; +} diff --git a/common/src/interfaces/teacher-invitation.ts b/common/src/interfaces/teacher-invitation.ts new file mode 100644 index 00000000..13709322 --- /dev/null +++ b/common/src/interfaces/teacher-invitation.ts @@ -0,0 +1,8 @@ +import { UserDTO } from './user'; +import { ClassDTO } from './class'; + +export interface TeacherInvitationDTO { + sender: string | UserDTO; + receiver: string | UserDTO; + class: string | ClassDTO; +} diff --git a/common/src/interfaces/teacher.ts b/common/src/interfaces/teacher.ts new file mode 100644 index 00000000..53195c33 --- /dev/null +++ b/common/src/interfaces/teacher.ts @@ -0,0 +1,6 @@ +export interface TeacherDTO { + id: string; + username: string; + firstName: string; + lastName: string; +} diff --git a/common/src/interfaces/user.ts b/common/src/interfaces/user.ts new file mode 100644 index 00000000..66bca296 --- /dev/null +++ b/common/src/interfaces/user.ts @@ -0,0 +1,6 @@ +export interface UserDTO { + id?: string; + username: string; + firstName: string; + lastName: string; +} diff --git a/common/src/util/class-join-request.ts b/common/src/util/class-join-request.ts new file mode 100644 index 00000000..5f9410f0 --- /dev/null +++ b/common/src/util/class-join-request.ts @@ -0,0 +1,5 @@ +export enum ClassJoinRequestStatus { + Open = 'open', + Accepted = 'accepted', + Declined = 'declined', +} diff --git a/backend/src/entities/content/language.ts b/common/src/util/language.ts similarity index 100% rename from backend/src/entities/content/language.ts rename to common/src/util/language.ts diff --git a/common/tsconfig.json b/common/tsconfig.json new file mode 100644 index 00000000..86267d25 --- /dev/null +++ b/common/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "../tsconfig.json", + "include": ["src/**/*.ts"], + "compilerOptions": { + "rootDir": "./src", + "outDir": "./dist" + } +} diff --git a/eslint.config.ts b/eslint.config.ts index 61a99fda..fb19e5c4 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -16,8 +16,17 @@ export default [ prettierConfig, includeIgnoreFile(gitignorePath), { - ignores: ['**/dist/**', '**/.node_modules/**', '**/coverage/**', '**/.github/**'], - files: ['**/*.ts', '**/*.cts', '**.*.mts', '**/*.ts'], + ignores: [ + '**/dist/**', + '**/.node_modules/**', + '**/coverage/**', + '**/.github/**', + '**/prettier.config.js', + 'docs/.venv/**', + 'prettier.config.js', + 'frontend/prettier.config.js', + ], + files: ['**/*.ts', '**/*.cts', '**.*.mts'], }, { languageOptions: { diff --git a/frontend/eslint.config.ts b/frontend/eslint.config.ts index e9359af7..9ca1a08b 100644 --- a/frontend/eslint.config.ts +++ b/frontend/eslint.config.ts @@ -21,7 +21,7 @@ const vueConfig = defineConfigWithVueTs( { name: "app/files-to-ignore", - ignores: ["**/dist/**", "**/dist-ssr/**", "**/coverage/**"], + ignores: ["**/dist/**", "**/dist-ssr/**", "**/coverage/**", "prettier.config.js"], }, pluginVue.configs["flat/essential"], diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index e0d34b13..baf5577b 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -12,6 +12,7 @@ } ], "compilerOptions": { + "composite": true, "resolveJsonModule": true } } diff --git a/package-lock.json b/package-lock.json index a38ca88a..27d261cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,15 +1,16 @@ { - "name": "dwengo-1-monorepo", + "name": "dwengo-1", "version": "0.1.1", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "dwengo-1-monorepo", + "name": "dwengo-1", "version": "0.1.1", "license": "MIT", "workspaces": [ "backend", + "common", "frontend", "docs" ], @@ -27,7 +28,7 @@ } }, "backend": { - "name": "dwengo-1-backend", + "name": "@dwengo-1/backend", "version": "0.1.1", "dependencies": { "@mikro-orm/core": "6.4.9", @@ -40,6 +41,7 @@ "cross": "^1.0.0", "cross-env": "^7.0.3", "dotenv": "^16.4.7", + "dwengo-1-common": "^0.1.1", "express": "^5.0.1", "express-jwt": "^8.5.1", "gift-pegjs": "^1.0.2", @@ -83,6 +85,10 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "common": { + "name": "@dwengo-1/common", + "version": "0.1.1" + }, "docs": { "name": "dwengo-1-docs", "version": "0.0.1", @@ -843,6 +849,14 @@ "kuler": "^2.0.0" } }, + "node_modules/@dwengo-1/backend": { + "resolved": "backend", + "link": true + }, + "node_modules/@dwengo-1/common": { + "resolved": "common", + "link": true + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.25.2", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.2.tgz", @@ -4915,8 +4929,8 @@ "node": ">= 0.4" } }, - "node_modules/dwengo-1-backend": { - "resolved": "backend", + "node_modules/dwengo-1-common": { + "resolved": "common", "link": true }, "node_modules/dwengo-1-docs": { diff --git a/package.json b/package.json index e23a49f6..64cfd665 100644 --- a/package.json +++ b/package.json @@ -1,18 +1,23 @@ { - "name": "dwengo-1-monorepo", + "name": "dwengo-1", "version": "0.1.1", "description": "Monorepo for Dwengo-1", "private": true, "type": "module", "scripts": { - "build": "npm run build --workspace=backend --workspace=frontend", - "format": "npm run format --workspace=backend --workspace=frontend", - "format-check": "npm run format-check --workspace=backend --workspace=frontend", - "lint": "npm run lint --workspace=backend --workspace=frontend", + "prebuild": "npm run clean", + "build": "tsc --build tsconfig.build.json", + "clean": "tsc --build tsconfig.build.json --clean", + "watch": "tsc --build tsconfig.build.json --watch", + "format": "npm run format --workspace=backend --workspace=common --workspace=frontend", + "format-check": "npm run format-check --workspace=backend --workspace=common --workspace=frontend", + "lint": "npm run lint --workspace=backend --workspace=common --workspace=frontend", + "pretest:unit": "npm run build", "test:unit": "npm run test:unit --workspace=backend --workspace=frontend" }, "workspaces": [ "backend", + "common", "frontend", "docs" ], diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 00000000..e283237e --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,11 @@ +{ + "files": [], + "references": [ + { + "path": "./common" + }, + { + "path": "./backend" + } + ] +} diff --git a/tsconfig.json b/tsconfig.json index b41449cf..1da18198 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ /* Projects */ // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + "composite": true /* Enable constraints that allow a TypeScript project to be used with project references. */, // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ @@ -25,7 +25,7 @@ // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ - "moduleDetection": "force", + // "moduleDetection": "force", /* Control what method is used to detect module-format JS files. */ /* Modules */ @@ -33,7 +33,7 @@ /* Specify what module code is generated. */ // "rootDir": "./src", /* Specify the root folder within your source files. */ - "moduleResolution": "node", + "moduleResolution": "bundler", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ @@ -53,16 +53,16 @@ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ - "allowJs": true, + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + "declaration": true /* Generate .d.ts files from TypeScript and JavaScript files in your project. */, + "declarationMap": true /* Create sourcemaps for d.ts files. */, // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + "sourceMap": true /* Create source map files for emitted JavaScript files. */, // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "noEmit": true, /* Disable emitting files from a compilation. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */