fix: question controller
This commit is contained in:
		
							parent
							
								
									bd75ab8af9
								
							
						
					
					
						commit
						6a1adb0ee3
					
				
					 4 changed files with 49 additions and 88 deletions
				
			
		|  | @ -5,3 +5,4 @@ export const DWENGO_API_BASE = getEnvVar(envVars.LearningContentRepoApiBaseUrl); | ||||||
| export const FALLBACK_LANG = getEnvVar(envVars.FallbackLanguage); | export const FALLBACK_LANG = getEnvVar(envVars.FallbackLanguage); | ||||||
| 
 | 
 | ||||||
| export const FALLBACK_SEQ_NUM = 1; | export const FALLBACK_SEQ_NUM = 1; | ||||||
|  | export const FALLBACK_VERSION_NUM = 1; | ||||||
|  |  | ||||||
|  | @ -1,34 +1,20 @@ | ||||||
| import { Request, Response } from 'express'; | import { Request, Response } from 'express'; | ||||||
| import { createQuestion, deleteQuestion, getAllQuestions, getAnswersByQuestion, getQuestion } from '../services/questions.js'; | import { createQuestion, deleteQuestion, getAllQuestions, getAnswersByQuestion, getQuestion } from '../services/questions.js'; | ||||||
| import { 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 { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.js'; | ||||||
| import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; | import { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; | ||||||
| import { Language } from '@dwengo-1/common/util/language'; | import { Language } from '@dwengo-1/common/util/language'; | ||||||
|  | import {requireFields} from "./error-helper"; | ||||||
| 
 | 
 | ||||||
| function getObjectId(req: Request, res: Response): LearningObjectIdentifier | null { | function getLearningObjectId(hruid: string, version: string, lang: string): LearningObjectIdentifier { | ||||||
|     const { hruid, version } = req.params; |  | ||||||
|     const lang = req.query.lang; |  | ||||||
| 
 |  | ||||||
|     if (!hruid || !version) { |  | ||||||
|         res.status(400).json({ error: 'Missing required parameters.' }); |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return { |     return { | ||||||
|         hruid, |         hruid, | ||||||
|         language: (lang as Language) || FALLBACK_LANG, |         language: (lang || FALLBACK_LANG) as Language, | ||||||
|         version: Number(version), |         version: Number(version) || FALLBACK_VERSION_NUM, | ||||||
|     }; |     }; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| function getQuestionId(req: Request, res: Response): QuestionId | null { | function getQuestionId(learningObjectIdentifier: LearningObjectIdentifier, seq: string): QuestionId { | ||||||
|     const seq = req.params.seq; |  | ||||||
|     const learningObjectIdentifier = getObjectId(req, res); |  | ||||||
| 
 |  | ||||||
|     if (!learningObjectIdentifier) { |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return { |     return { | ||||||
|         learningObjectIdentifier, |         learningObjectIdentifier, | ||||||
|         sequenceNumber: seq ? Number(seq) : FALLBACK_SEQ_NUM, |         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<void> { | export async function getAllQuestionsHandler(req: Request, res: Response): Promise<void> { | ||||||
|     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'; |     const full = req.query.full === 'true'; | ||||||
|  |     requireFields({ hruid }) | ||||||
| 
 | 
 | ||||||
|     if (!objectId) { |     const learningObjectId = getLearningObjectId(hruid, version, language); | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     const questions = await getAllQuestions(objectId, full); |     const questions = await getAllQuestions(learningObjectId, full); | ||||||
| 
 | 
 | ||||||
|     if (!questions) { |     res.json({ questions }); | ||||||
|         res.status(404).json({ error: `Questions not found.` }); |  | ||||||
|     } else { |  | ||||||
|         res.json({ questions: questions }); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function getQuestionHandler(req: Request, res: Response): Promise<void> { | export async function getQuestionHandler(req: Request, res: Response): Promise<void> { | ||||||
|     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) { |     const learningObjectId = getLearningObjectId(hruid, version, language); | ||||||
|         return; |     const questionId = getQuestionId(learningObjectId, seq); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     const question = await getQuestion(questionId); |     const question = await getQuestion(questionId); | ||||||
| 
 | 
 | ||||||
|     if (!question) { |     res.json({ question }); | ||||||
|         res.status(404).json({ error: `Question not found.` }); | 
 | ||||||
|     } else { |  | ||||||
|         res.json(question); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function getQuestionAnswersHandler(req: Request, res: Response): Promise<void> { | export async function getQuestionAnswersHandler(req: Request, res: Response): Promise<void> { | ||||||
|     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'; |     const full = req.query.full === 'true'; | ||||||
|  |     requireFields({ hruid }) | ||||||
| 
 | 
 | ||||||
|     if (!questionId) { |     const learningObjectId = getLearningObjectId(hruid, version, language); | ||||||
|         return; |     const questionId = getQuestionId(learningObjectId, seq); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     const answers = await getAnswersByQuestion(questionId, full); |     const answers = await getAnswersByQuestion(questionId, full); | ||||||
| 
 | 
 | ||||||
|     if (!answers) { |     res.json({ answers }); | ||||||
|         res.status(404).json({ error: `Questions not found` }); |  | ||||||
|     } else { |  | ||||||
|         res.json({ answers: answers }); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function createQuestionHandler(req: Request, res: Response): Promise<void> { | export async function createQuestionHandler(req: Request, res: Response): Promise<void> { | ||||||
|     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) { |     const questionDTO = req.body as QuestionDTO; | ||||||
|         res.status(400).json({ error: 'Missing required fields: identifier and content' }); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     const question = await createQuestion(questionDTO); |     const question = await createQuestion(questionDTO); | ||||||
| 
 | 
 | ||||||
|     if (!question) { |     res.json({ question }); | ||||||
|         res.status(400).json({ error: 'Could not create question' }); | 
 | ||||||
|     } else { |  | ||||||
|         res.json(question); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export async function deleteQuestionHandler(req: Request, res: Response): Promise<void> { | export async function deleteQuestionHandler(req: Request, res: Response): Promise<void> { | ||||||
|     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) { |     const learningObjectId = getLearningObjectId(hruid, version, language); | ||||||
|         return; |     const questionId = getQuestionId(learningObjectId, seq); | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
|     const question = await deleteQuestion(questionId); |     const question = await deleteQuestion(questionId); | ||||||
| 
 | 
 | ||||||
|     if (!question) { |     res.json({ question }); | ||||||
|         res.status(400).json({ error: 'Could not find nor delete question' }); |  | ||||||
|     } else { |  | ||||||
|         res.json(question); |  | ||||||
|     } |  | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -5,12 +5,10 @@ import { Answer } from '../entities/questions/answer.entity.js'; | ||||||
| import { mapToAnswerDTO, mapToAnswerDTOId } from '../interfaces/answer.js'; | import { mapToAnswerDTO, mapToAnswerDTOId } from '../interfaces/answer.js'; | ||||||
| import { QuestionRepository } from '../data/questions/question-repository.js'; | import { QuestionRepository } from '../data/questions/question-repository.js'; | ||||||
| import { LearningObjectIdentifier } from '../entities/content/learning-object-identifier.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 { QuestionDTO, QuestionId } from '@dwengo-1/common/interfaces/question'; | ||||||
| import { AnswerDTO, AnswerId } from '@dwengo-1/common/interfaces/answer'; | import { AnswerDTO, AnswerId } from '@dwengo-1/common/interfaces/answer'; | ||||||
| import {NotFoundException} from "../exceptions/not-found-exception"; | import {NotFoundException} from "../exceptions/not-found-exception"; | ||||||
| import {fetchStudent} from "./students"; | import {fetchStudent} from "./students"; | ||||||
| import {Student} from "../entities/users/student.entity"; |  | ||||||
| 
 | 
 | ||||||
| export async function getAllQuestions(id: LearningObjectIdentifier, full: boolean): Promise<QuestionDTO[] | QuestionId[]> { | export async function getAllQuestions(id: LearningObjectIdentifier, full: boolean): Promise<QuestionDTO[] | QuestionId[]> { | ||||||
|     const questionRepository: QuestionRepository = getQuestionRepository(); |     const questionRepository: QuestionRepository = getQuestionRepository(); | ||||||
|  | @ -57,13 +55,7 @@ export async function getAnswersByQuestion(questionId: QuestionId, full: boolean | ||||||
| 
 | 
 | ||||||
| export async function createQuestion(questionDTO: QuestionDTO): Promise<QuestionDTO | null> { | export async function createQuestion(questionDTO: QuestionDTO): Promise<QuestionDTO | null> { | ||||||
|     const questionRepository = getQuestionRepository(); |     const questionRepository = getQuestionRepository(); | ||||||
|     let author: Student; |     const author = await fetchStudent(questionDTO.author); | ||||||
|     if (typeof questionDTO.author === "string" ){ |  | ||||||
|         author = await fetchStudent(questionDTO.author); |  | ||||||
|     } else { |  | ||||||
|         author = mapToStudent(questionDTO.author) |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
| 
 | 
 | ||||||
|     await questionRepository.createQuestion({ |     await questionRepository.createQuestion({ | ||||||
|         loId: mapToLearningObjectID(questionDTO.learningObjectIdentifier), |         loId: mapToLearningObjectID(questionDTO.learningObjectIdentifier), | ||||||
|  | @ -71,7 +63,6 @@ export async function createQuestion(questionDTO: QuestionDTO): Promise<Question | ||||||
|         content: questionDTO.content, |         content: questionDTO.content, | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
| 
 |  | ||||||
|     return questionDTO; |     return questionDTO; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -80,20 +71,11 @@ export async function deleteQuestion(questionId: QuestionId): Promise<QuestionDT | ||||||
| 
 | 
 | ||||||
|     const question = await fetchQuestion(questionId); |     const question = await fetchQuestion(questionId); | ||||||
| 
 | 
 | ||||||
|     if (!question) { |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     const loId: LearningObjectIdentifier = { |     const loId: LearningObjectIdentifier = { | ||||||
|         ...questionId.learningObjectIdentifier, |         ...questionId.learningObjectIdentifier, | ||||||
|         version: questionId.learningObjectIdentifier.version ?? 1, |         version: questionId.learningObjectIdentifier.version ?? 1, | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     try { |     await questionRepository.removeQuestionByLearningObjectAndSequenceNumber(loId, questionId.sequenceNumber); | ||||||
|         await questionRepository.removeQuestionByLearningObjectAndSequenceNumber(loId, questionId.sequenceNumber); |  | ||||||
|     } catch (_) { |  | ||||||
|         return null; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     return mapToQuestionDTO(question); |     return mapToQuestionDTO(question); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -4,7 +4,7 @@ import { StudentDTO } from './student'; | ||||||
| export interface QuestionDTO { | export interface QuestionDTO { | ||||||
|     learningObjectIdentifier: LearningObjectIdentifierDTO; |     learningObjectIdentifier: LearningObjectIdentifierDTO; | ||||||
|     sequenceNumber?: number; |     sequenceNumber?: number; | ||||||
|     author: StudentDTO | string; |     author: string; | ||||||
|     timestamp?: string; |     timestamp?: string; | ||||||
|     content: string; |     content: string; | ||||||
| } | } | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Gabriellvl
						Gabriellvl