diff --git a/backend/src/config.ts b/backend/src/config.ts index 9b4702b5..9b209ada 100644 --- a/backend/src/config.ts +++ b/backend/src/config.ts @@ -5,3 +5,4 @@ export const DWENGO_API_BASE = getEnvVar(envVars.LearningContentRepoApiBaseUrl); export const FALLBACK_LANG = getEnvVar(envVars.FallbackLanguage); export const FALLBACK_SEQ_NUM = 1; +export const FALLBACK_VERSION_NUM = 1; diff --git a/backend/src/controllers/questions.ts b/backend/src/controllers/questions.ts index b5b764ac..a4a6a76d 100644 --- a/backend/src/controllers/questions.ts +++ b/backend/src/controllers/questions.ts @@ -1,34 +1,20 @@ import { Request, Response } from 'express'; import { createQuestion, deleteQuestion, getAllQuestions, getAnswersByQuestion, getQuestion } from '../services/questions.js'; -import { FALLBACK_LANG, FALLBACK_SEQ_NUM } from '../config.js'; +import {FALLBACK_LANG, FALLBACK_SEQ_NUM, FALLBACK_VERSION_NUM} from '../config.js'; import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js'; import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; import { Language } from '@dwengo-1/common/util/language'; +import {requireFields} from "./error-helper"; -function getObjectId(req: Request, res: Response): LearningObjectIdentifier | null { - const { hruid, version } = req.params; - const lang = req.query.lang; - - if (!hruid || !version) { - res.status(400).json({ error: 'Missing required parameters.' }); - return null; - } - +function getLearningObjectId(hruid: string, version: string, lang: string): LearningObjectIdentifier { return { hruid, - language: (lang as Language) || FALLBACK_LANG, - version: Number(version), + language: (lang || FALLBACK_LANG) as Language, + version: Number(version) || FALLBACK_VERSION_NUM, }; } -function getQuestionId(req: Request, res: Response): QuestionId | null { - const seq = req.params.seq; - const learningObjectIdentifier = getObjectId(req, res); - - if (!learningObjectIdentifier) { - return null; - } - +function getQuestionId(learningObjectIdentifier: LearningObjectIdentifier, seq: string): QuestionId { return { learningObjectIdentifier, sequenceNumber: seq ? Number(seq) : FALLBACK_SEQ_NUM, @@ -36,84 +22,76 @@ function getQuestionId(req: Request, res: Response): QuestionId | null { } export async function getAllQuestionsHandler(req: Request, res: Response): Promise { - const objectId = getObjectId(req, res); + const hruid = req.params.hruid; + const version = req.params.version; + const language = req.query.lang as string; const full = req.query.full === 'true'; + requireFields({ hruid }) - if (!objectId) { - return; - } + const learningObjectId = getLearningObjectId(hruid, version, language); - const questions = await getAllQuestions(objectId, full); + const questions = await getAllQuestions(learningObjectId, full); - if (!questions) { - res.status(404).json({ error: `Questions not found.` }); - } else { - res.json({ questions: questions }); - } + res.json({ questions }); } export async function getQuestionHandler(req: Request, res: Response): Promise { - const questionId = getQuestionId(req, res); + const hruid = req.params.hruid; + const version = req.params.version; + const language = req.query.lang as string; + const seq = req.params.seq; + requireFields({ hruid }) - if (!questionId) { - return; - } + const learningObjectId = getLearningObjectId(hruid, version, language); + const questionId = getQuestionId(learningObjectId, seq); const question = await getQuestion(questionId); - if (!question) { - res.status(404).json({ error: `Question not found.` }); - } else { - res.json(question); - } + res.json({ question }); + } export async function getQuestionAnswersHandler(req: Request, res: Response): Promise { - const questionId = getQuestionId(req, res); + const hruid = req.params.hruid; + const version = req.params.version; + const language = req.query.lang as string; + const seq = req.params.seq; const full = req.query.full === 'true'; + requireFields({ hruid }) - if (!questionId) { - return; - } + const learningObjectId = getLearningObjectId(hruid, version, language); + const questionId = getQuestionId(learningObjectId, seq); const answers = await getAnswersByQuestion(questionId, full); - if (!answers) { - res.status(404).json({ error: `Questions not found` }); - } else { - res.json({ answers: answers }); - } + res.json({ answers }); } export async function createQuestionHandler(req: Request, res: Response): Promise { - const questionDTO = req.body as QuestionDTO; + const learningObjectIdentifier = req.body.learningObjectIdentifier; + const author = req.body.author; + const content = req.body.content; + requireFields({ learningObjectIdentifier, author, content }); - if (!questionDTO.learningObjectIdentifier || !questionDTO.author || !questionDTO.content) { - res.status(400).json({ error: 'Missing required fields: identifier and content' }); - return; - } + const questionDTO = req.body as QuestionDTO; const question = await createQuestion(questionDTO); - if (!question) { - res.status(400).json({ error: 'Could not create question' }); - } else { - res.json(question); - } + res.json({ question }); + } export async function deleteQuestionHandler(req: Request, res: Response): Promise { - const questionId = getQuestionId(req, res); + const hruid = req.params.hruid; + const version = req.params.version; + const language = req.query.lang as string; + const seq = req.params.seq; + requireFields({ hruid }) - if (!questionId) { - return; - } + const learningObjectId = getLearningObjectId(hruid, version, language); + const questionId = getQuestionId(learningObjectId, seq); const question = await deleteQuestion(questionId); - if (!question) { - res.status(400).json({ error: 'Could not find nor delete question' }); - } else { - res.json(question); - } + res.json({ question }); } diff --git a/backend/src/services/questions.ts b/backend/src/services/questions.ts index d983c3be..be361085 100644 --- a/backend/src/services/questions.ts +++ b/backend/src/services/questions.ts @@ -5,12 +5,10 @@ import { Answer } from '../entities/questions/answer.entity.js'; import { mapToAnswerDTO, mapToAnswerDTOId } from '../interfaces/answer.js'; import { QuestionRepository } from '../data/questions/question-repository.js'; import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js'; -import {mapToStudent, mapToStudentDTO} from '../interfaces/student.js'; import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; import { AnswerDTO, AnswerId } from '@dwengo-1/common/interfaces/answer'; import {NotFoundException} from "../exceptions/not-found-exception"; import {fetchStudent} from "./students"; -import {Student} from "../entities/users/student.entity"; export async function getAllQuestions(id: LearningObjectIdentifier, full: boolean): Promise { const questionRepository: QuestionRepository = getQuestionRepository(); @@ -57,13 +55,7 @@ export async function getAnswersByQuestion(questionId: QuestionId, full: boolean export async function createQuestion(questionDTO: QuestionDTO): Promise { const questionRepository = getQuestionRepository(); - let author: Student; - if (typeof questionDTO.author === "string" ){ - author = await fetchStudent(questionDTO.author); - } else { - author = mapToStudent(questionDTO.author) - } - + const author = await fetchStudent(questionDTO.author); await questionRepository.createQuestion({ loId: mapToLearningObjectID(questionDTO.learningObjectIdentifier), @@ -71,7 +63,6 @@ export async function createQuestion(questionDTO: QuestionDTO): Promise