feat: change answer submission architecture
This commit is contained in:
@@ -38,17 +38,13 @@ export class CreateQuestionDTO {
|
||||
})
|
||||
content!: string;
|
||||
|
||||
@IsPositive({
|
||||
message: t('validation.wrongField', {
|
||||
field: '$t(questions.fields.order)',
|
||||
}),
|
||||
})
|
||||
@IsNotEmpty({
|
||||
message: t('validation.requiredField', {
|
||||
field: '$t(questions.fields.order)',
|
||||
}),
|
||||
})
|
||||
order!: number;
|
||||
// @IsPositive({
|
||||
// message: t('validation.wrongField', {
|
||||
// field: '$t(questions.fields.order)',
|
||||
// }),
|
||||
// })
|
||||
// @IsOptional()
|
||||
// order?: number;
|
||||
|
||||
@IsPositive({
|
||||
message: t('validation.wrongField', {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { ConflictException, HttpStatus, Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Question } from '../entities/question.entity';
|
||||
import { QueryFailedError, Repository } from 'typeorm';
|
||||
import { DataSource, QueryFailedError, Repository } from 'typeorm';
|
||||
import { TestsService } from '@/modules/tests/providers/tests.service';
|
||||
import { I18nService } from 'nestjs-i18n';
|
||||
import { CreateQuestionDTO } from '../dtos/create-question.dto';
|
||||
@@ -11,10 +11,16 @@ import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception';
|
||||
import { UpdateQuestionDTO } from '../dtos/update-question.dto';
|
||||
import { validateMetadata } from '../helpers/validate-metadata.helper';
|
||||
import { AppException } from '@/common/exceptions/app.exception';
|
||||
import { Test } from '@/modules/tests/entities/test.entity';
|
||||
|
||||
@Injectable()
|
||||
export class QuestionsCommandProvider {
|
||||
constructor(
|
||||
/**
|
||||
* Inject DataSource
|
||||
*/
|
||||
private readonly dataSource: DataSource,
|
||||
|
||||
/**
|
||||
* Inject Questions Repository
|
||||
*/
|
||||
@@ -35,13 +41,31 @@ export class QuestionsCommandProvider {
|
||||
public async createOne(createQuestionDto: CreateQuestionDTO) {
|
||||
const test = await this.testsService.adminGetOne(createQuestionDto.test);
|
||||
|
||||
let maxOrder: { max: string } | undefined;
|
||||
|
||||
try {
|
||||
maxOrder = await this.questionsRepository
|
||||
.createQueryBuilder('q')
|
||||
.select('MAX(q.order)', 'max')
|
||||
.where('q.testId = :testId', { testId: test.id })
|
||||
.getRawOne();
|
||||
} catch (err) {
|
||||
throw new AppTimeoutException(err);
|
||||
}
|
||||
|
||||
const newQuestion = this.questionsRepository.create({
|
||||
...createQuestionDto,
|
||||
test,
|
||||
order: (Number(maxOrder?.max) || 0) + 1,
|
||||
});
|
||||
|
||||
try {
|
||||
await this.questionsRepository.save(newQuestion);
|
||||
await this.dataSource.transaction(async (manager) => {
|
||||
await manager.save(newQuestion);
|
||||
|
||||
await manager.increment(Test, { id: test.id }, 'questionsCount', 1);
|
||||
});
|
||||
|
||||
return new AppResponse(
|
||||
newQuestion,
|
||||
this.i18nService.translate('common.messages.createSuccess', {
|
||||
@@ -117,7 +141,10 @@ export class QuestionsCommandProvider {
|
||||
let question: Question | null = null;
|
||||
|
||||
try {
|
||||
question = await this.questionsRepository.findOneBy({ id });
|
||||
question = await this.questionsRepository.findOne({
|
||||
where: { id },
|
||||
relations: { test: true },
|
||||
});
|
||||
} catch (err) {
|
||||
throw new AppTimeoutException(err);
|
||||
}
|
||||
@@ -130,7 +157,16 @@ export class QuestionsCommandProvider {
|
||||
);
|
||||
|
||||
try {
|
||||
await this.questionsRepository.delete(question.id);
|
||||
await this.dataSource.transaction(async (manager) => {
|
||||
await manager.delete(Question, question.id);
|
||||
|
||||
await manager.decrement(
|
||||
Test,
|
||||
{ id: question.test.id },
|
||||
'questionsCount',
|
||||
1,
|
||||
);
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
throw new AppTimeoutException(err);
|
||||
|
||||
@@ -7,7 +7,7 @@ import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception';
|
||||
import { PaginatedResponse } from '@/common/responses';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Question } from '../entities/question.entity';
|
||||
import { Repository } from 'typeorm';
|
||||
import { FindManyOptions, FindOneOptions, Repository } from 'typeorm';
|
||||
import { TestsService } from '@/modules/tests/providers/tests.service';
|
||||
import { AppException } from '@/common/exceptions/app.exception';
|
||||
|
||||
@@ -39,8 +39,6 @@ export class QuestionsQueryProvider {
|
||||
});
|
||||
}
|
||||
|
||||
console.log(selectedTest);
|
||||
|
||||
try {
|
||||
const [questions, total] = await this.questionsRepository.findAndCount({
|
||||
where: {
|
||||
@@ -69,7 +67,19 @@ export class QuestionsQueryProvider {
|
||||
}
|
||||
}
|
||||
|
||||
public async findOneForAdmin(id: number) {
|
||||
public async findByOptionsForAdmin(options: FindManyOptions<Question>) {
|
||||
let questions: Array<Question> = [];
|
||||
|
||||
try {
|
||||
questions = await this.questionsRepository.find(options);
|
||||
} catch (err) {
|
||||
throw new AppTimeoutException(err);
|
||||
}
|
||||
|
||||
return questions;
|
||||
}
|
||||
|
||||
public async findOneByIdForAdmin(id: number) {
|
||||
let question: Question | null = null;
|
||||
|
||||
try {
|
||||
@@ -91,4 +101,16 @@ export class QuestionsQueryProvider {
|
||||
|
||||
return question;
|
||||
}
|
||||
|
||||
public async findOneForAdmin(options: FindOneOptions<Question>) {
|
||||
let question: Question | null = null;
|
||||
|
||||
try {
|
||||
question = await this.questionsRepository.findOne(options);
|
||||
} catch (err) {
|
||||
throw new AppTimeoutException(err);
|
||||
}
|
||||
|
||||
return question;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@ import { FindQuestionsDTO } from '../dtos/find-questions.dto';
|
||||
import { UpdateQuestionDTO } from '../dtos/update-question.dto';
|
||||
import { QuestionsCommandProvider } from './questions-command.provider';
|
||||
import { QuestionsQueryProvider } from './questions-query.provider';
|
||||
import { FindManyOptions, FindOneOptions } from 'typeorm';
|
||||
import { Question } from '../entities/question.entity';
|
||||
|
||||
@Injectable()
|
||||
export class QuestionsService {
|
||||
@@ -27,8 +29,16 @@ export class QuestionsService {
|
||||
return await this.questionsQueryProvider.findAllForAdmin(query);
|
||||
}
|
||||
|
||||
public async findOneForAdmin(id: number) {
|
||||
return await this.questionsQueryProvider.findOneForAdmin(id);
|
||||
public async findByOptionsForAdmin(options: FindManyOptions<Question>) {
|
||||
return await this.questionsQueryProvider.findByOptionsForAdmin(options);
|
||||
}
|
||||
|
||||
public async findOneByIdForAdmin(id: number) {
|
||||
return await this.questionsQueryProvider.findOneByIdForAdmin(id);
|
||||
}
|
||||
|
||||
public async findOneForAdmin(options: FindOneOptions<Question>) {
|
||||
return await this.questionsQueryProvider.findOneForAdmin(options);
|
||||
}
|
||||
|
||||
public async updateOne(id: number, updateQuestionDto: UpdateQuestionDTO) {
|
||||
|
||||
Reference in New Issue
Block a user