feat: add user submission history preparations
This commit is contained in:
@@ -7,3 +7,24 @@ export const normalizePhone = (phone: string): string => {
|
|||||||
|
|
||||||
return phone;
|
return phone;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type GenerateCodeOptions = {
|
||||||
|
prefix?: string;
|
||||||
|
length?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const generateCode = (options?: GenerateCodeOptions) => {
|
||||||
|
const prefix = options?.prefix || '';
|
||||||
|
const length = options?.length || 5;
|
||||||
|
|
||||||
|
const characters =
|
||||||
|
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
|
||||||
|
|
||||||
|
let random = '';
|
||||||
|
|
||||||
|
for (let i = 0; i < length; i++) {
|
||||||
|
random += characters.charAt(Math.floor(Math.random() * characters.length));
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${prefix}${random}`;
|
||||||
|
};
|
||||||
|
|||||||
@@ -261,7 +261,6 @@ async function seedTest() {
|
|||||||
const q1Yes = choiceRepository.create({
|
const q1Yes = choiceRepository.create({
|
||||||
question: q1,
|
question: q1,
|
||||||
text: 'بله',
|
text: 'بله',
|
||||||
value: 1,
|
|
||||||
order: 1,
|
order: 1,
|
||||||
score: 1,
|
score: 1,
|
||||||
});
|
});
|
||||||
@@ -269,7 +268,6 @@ async function seedTest() {
|
|||||||
const q1No = choiceRepository.create({
|
const q1No = choiceRepository.create({
|
||||||
question: q1,
|
question: q1,
|
||||||
text: 'خیر',
|
text: 'خیر',
|
||||||
value: 0,
|
|
||||||
order: 2,
|
order: 2,
|
||||||
score: 0,
|
score: 0,
|
||||||
});
|
});
|
||||||
@@ -285,7 +283,6 @@ async function seedTest() {
|
|||||||
const q2Yes = choiceRepository.create({
|
const q2Yes = choiceRepository.create({
|
||||||
question: q2,
|
question: q2,
|
||||||
text: 'بله',
|
text: 'بله',
|
||||||
value: 1,
|
|
||||||
order: 1,
|
order: 1,
|
||||||
score: 1,
|
score: 1,
|
||||||
});
|
});
|
||||||
@@ -293,7 +290,6 @@ async function seedTest() {
|
|||||||
const q2No = choiceRepository.create({
|
const q2No = choiceRepository.create({
|
||||||
question: q2,
|
question: q2,
|
||||||
text: 'خیر',
|
text: 'خیر',
|
||||||
value: 0,
|
|
||||||
order: 2,
|
order: 2,
|
||||||
score: 0,
|
score: 0,
|
||||||
});
|
});
|
||||||
@@ -301,7 +297,6 @@ async function seedTest() {
|
|||||||
const q2NotSure = choiceRepository.create({
|
const q2NotSure = choiceRepository.create({
|
||||||
question: q2,
|
question: q2,
|
||||||
text: 'مطمئن نیستم',
|
text: 'مطمئن نیستم',
|
||||||
value: 2,
|
|
||||||
order: 3,
|
order: 3,
|
||||||
score: 1,
|
score: 1,
|
||||||
});
|
});
|
||||||
@@ -332,7 +327,6 @@ async function seedTest() {
|
|||||||
choiceRepository.create({
|
choiceRepository.create({
|
||||||
question: q3,
|
question: q3,
|
||||||
text,
|
text,
|
||||||
value: index + 1,
|
|
||||||
order: index + 1,
|
order: index + 1,
|
||||||
score: 2,
|
score: 2,
|
||||||
}),
|
}),
|
||||||
@@ -363,7 +357,6 @@ async function seedTest() {
|
|||||||
choiceRepository.create({
|
choiceRepository.create({
|
||||||
question: q4,
|
question: q4,
|
||||||
text,
|
text,
|
||||||
value: index + 1,
|
|
||||||
order: index + 1,
|
order: index + 1,
|
||||||
score: 1,
|
score: 1,
|
||||||
}),
|
}),
|
||||||
@@ -380,7 +373,6 @@ async function seedTest() {
|
|||||||
const q5Yes = choiceRepository.create({
|
const q5Yes = choiceRepository.create({
|
||||||
question: q5,
|
question: q5,
|
||||||
text: 'بله',
|
text: 'بله',
|
||||||
value: 1,
|
|
||||||
order: 1,
|
order: 1,
|
||||||
score: 1,
|
score: 1,
|
||||||
});
|
});
|
||||||
@@ -388,7 +380,6 @@ async function seedTest() {
|
|||||||
const q5No = choiceRepository.create({
|
const q5No = choiceRepository.create({
|
||||||
question: q5,
|
question: q5,
|
||||||
text: 'خیر',
|
text: 'خیر',
|
||||||
value: 0,
|
|
||||||
order: 2,
|
order: 2,
|
||||||
score: 0,
|
score: 0,
|
||||||
});
|
});
|
||||||
@@ -396,7 +387,6 @@ async function seedTest() {
|
|||||||
const q5NotSure = choiceRepository.create({
|
const q5NotSure = choiceRepository.create({
|
||||||
question: q5,
|
question: q5,
|
||||||
text: 'مطمئن نیستم',
|
text: 'مطمئن نیستم',
|
||||||
value: 2,
|
|
||||||
order: 3,
|
order: 3,
|
||||||
score: 1,
|
score: 1,
|
||||||
});
|
});
|
||||||
@@ -412,7 +402,6 @@ async function seedTest() {
|
|||||||
const q6Yes = choiceRepository.create({
|
const q6Yes = choiceRepository.create({
|
||||||
question: q6,
|
question: q6,
|
||||||
text: 'بله',
|
text: 'بله',
|
||||||
value: 1,
|
|
||||||
order: 1,
|
order: 1,
|
||||||
score: 1,
|
score: 1,
|
||||||
});
|
});
|
||||||
@@ -420,7 +409,6 @@ async function seedTest() {
|
|||||||
const q6No = choiceRepository.create({
|
const q6No = choiceRepository.create({
|
||||||
question: q6,
|
question: q6,
|
||||||
text: 'خیر',
|
text: 'خیر',
|
||||||
value: 0,
|
|
||||||
order: 2,
|
order: 2,
|
||||||
score: 0,
|
score: 0,
|
||||||
});
|
});
|
||||||
@@ -428,7 +416,6 @@ async function seedTest() {
|
|||||||
const q6NotSure = choiceRepository.create({
|
const q6NotSure = choiceRepository.create({
|
||||||
question: q6,
|
question: q6,
|
||||||
text: 'مطمئن نیستم',
|
text: 'مطمئن نیستم',
|
||||||
value: 2,
|
|
||||||
order: 3,
|
order: 3,
|
||||||
score: 1,
|
score: 1,
|
||||||
});
|
});
|
||||||
@@ -444,7 +431,6 @@ async function seedTest() {
|
|||||||
const q7Yes = choiceRepository.create({
|
const q7Yes = choiceRepository.create({
|
||||||
question: q7,
|
question: q7,
|
||||||
text: 'بله',
|
text: 'بله',
|
||||||
value: 1,
|
|
||||||
order: 1,
|
order: 1,
|
||||||
score: 2,
|
score: 2,
|
||||||
});
|
});
|
||||||
@@ -452,7 +438,6 @@ async function seedTest() {
|
|||||||
const q7No = choiceRepository.create({
|
const q7No = choiceRepository.create({
|
||||||
question: q7,
|
question: q7,
|
||||||
text: 'خیر',
|
text: 'خیر',
|
||||||
value: 0,
|
|
||||||
order: 2,
|
order: 2,
|
||||||
score: 0,
|
score: 0,
|
||||||
});
|
});
|
||||||
@@ -468,7 +453,6 @@ async function seedTest() {
|
|||||||
const q8Yes = choiceRepository.create({
|
const q8Yes = choiceRepository.create({
|
||||||
question: q8,
|
question: q8,
|
||||||
text: 'بله',
|
text: 'بله',
|
||||||
value: 1,
|
|
||||||
order: 1,
|
order: 1,
|
||||||
score: 2,
|
score: 2,
|
||||||
});
|
});
|
||||||
@@ -476,7 +460,6 @@ async function seedTest() {
|
|||||||
const q8No = choiceRepository.create({
|
const q8No = choiceRepository.create({
|
||||||
question: q8,
|
question: q8,
|
||||||
text: 'خیر',
|
text: 'خیر',
|
||||||
value: 0,
|
|
||||||
order: 2,
|
order: 2,
|
||||||
score: 0,
|
score: 0,
|
||||||
});
|
});
|
||||||
@@ -492,7 +475,6 @@ async function seedTest() {
|
|||||||
const q10Yes = choiceRepository.create({
|
const q10Yes = choiceRepository.create({
|
||||||
question: q10,
|
question: q10,
|
||||||
text: 'بله',
|
text: 'بله',
|
||||||
value: 1,
|
|
||||||
order: 1,
|
order: 1,
|
||||||
score: 1,
|
score: 1,
|
||||||
});
|
});
|
||||||
@@ -500,7 +482,6 @@ async function seedTest() {
|
|||||||
const q10No = choiceRepository.create({
|
const q10No = choiceRepository.create({
|
||||||
question: q10,
|
question: q10,
|
||||||
text: 'خیر',
|
text: 'خیر',
|
||||||
value: 0,
|
|
||||||
order: 2,
|
order: 2,
|
||||||
score: 0,
|
score: 0,
|
||||||
});
|
});
|
||||||
@@ -516,7 +497,6 @@ async function seedTest() {
|
|||||||
const q12Always = choiceRepository.create({
|
const q12Always = choiceRepository.create({
|
||||||
question: q12,
|
question: q12,
|
||||||
text: 'همیشه با همهٔ شرکای جنسیام از کاندوم استفاده کردهام.',
|
text: 'همیشه با همهٔ شرکای جنسیام از کاندوم استفاده کردهام.',
|
||||||
value: 1,
|
|
||||||
order: 1,
|
order: 1,
|
||||||
score: 0,
|
score: 0,
|
||||||
});
|
});
|
||||||
@@ -524,7 +504,6 @@ async function seedTest() {
|
|||||||
const q12Sometimes = choiceRepository.create({
|
const q12Sometimes = choiceRepository.create({
|
||||||
question: q12,
|
question: q12,
|
||||||
text: 'گاهی با شرکای جنسیام از کاندوم استفاده کردهام.',
|
text: 'گاهی با شرکای جنسیام از کاندوم استفاده کردهام.',
|
||||||
value: 2,
|
|
||||||
order: 2,
|
order: 2,
|
||||||
score: 2,
|
score: 2,
|
||||||
});
|
});
|
||||||
@@ -532,7 +511,6 @@ async function seedTest() {
|
|||||||
const q12Never = choiceRepository.create({
|
const q12Never = choiceRepository.create({
|
||||||
question: q12,
|
question: q12,
|
||||||
text: 'هیچوقت با هیچکدام از شرکای جنسیام از کاندوم استفاده نکردهام.',
|
text: 'هیچوقت با هیچکدام از شرکای جنسیام از کاندوم استفاده نکردهام.',
|
||||||
value: 3,
|
|
||||||
order: 3,
|
order: 3,
|
||||||
score: 5,
|
score: 5,
|
||||||
});
|
});
|
||||||
@@ -540,7 +518,6 @@ async function seedTest() {
|
|||||||
const q12NotApplicable = choiceRepository.create({
|
const q12NotApplicable = choiceRepository.create({
|
||||||
question: q12,
|
question: q12,
|
||||||
text: 'سؤال در مورد من صحت ندارد؛ چون که رابطهٔ واژنی یا مقعدی نداشتهام.',
|
text: 'سؤال در مورد من صحت ندارد؛ چون که رابطهٔ واژنی یا مقعدی نداشتهام.',
|
||||||
value: 4,
|
|
||||||
order: 4,
|
order: 4,
|
||||||
score: 1,
|
score: 1,
|
||||||
});
|
});
|
||||||
@@ -548,7 +525,6 @@ async function seedTest() {
|
|||||||
const q12NotSure = choiceRepository.create({
|
const q12NotSure = choiceRepository.create({
|
||||||
question: q12,
|
question: q12,
|
||||||
text: 'مطمئن نیستم.',
|
text: 'مطمئن نیستم.',
|
||||||
value: 5,
|
|
||||||
order: 5,
|
order: 5,
|
||||||
score: 2,
|
score: 2,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
"question": "Question",
|
"question": "Question",
|
||||||
"text": "Text",
|
"text": "Text",
|
||||||
"value": "Value",
|
"value": "Value",
|
||||||
"choice": "Choice",
|
|
||||||
"score": "Score",
|
"score": "Score",
|
||||||
"weight": "Weight",
|
"weight": "Weight",
|
||||||
"rangeRule": "Range Rule",
|
"rangeRule": "Range Rule",
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
"metadata": "تنظیمات",
|
"metadata": "تنظیمات",
|
||||||
"question": "سوال",
|
"question": "سوال",
|
||||||
"text": "متن",
|
"text": "متن",
|
||||||
"value": "مقدار",
|
|
||||||
"choice": "گزینه",
|
"choice": "گزینه",
|
||||||
"score": "نمره",
|
"score": "نمره",
|
||||||
"weight": "وزن",
|
"weight": "وزن",
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||||
|
|
||||||
|
export class PrepUserSubmissionHistory1788876455659 implements MigrationInterface {
|
||||||
|
name = 'PrepUserSubmissionHistory1788876455659';
|
||||||
|
|
||||||
|
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(`DROP INDEX "public"."unq_question_multi_choice"`);
|
||||||
|
await queryRunner.query(`ALTER TABLE "choice" DROP COLUMN "value"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "submission_answer" ADD "createdAt" TIMESTAMP NOT NULL DEFAULT now()`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "submission" ADD "code" character varying`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "submission" ADD "completedAt" TIMESTAMP WITH TIME ZONE`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "submission" DROP COLUMN "completedAt"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(`ALTER TABLE "submission" DROP COLUMN "code"`);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "submission_answer" DROP COLUMN "createdAt"`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`ALTER TABLE "choice" ADD "value" integer NOT NULL`,
|
||||||
|
);
|
||||||
|
await queryRunner.query(
|
||||||
|
`CREATE UNIQUE INDEX "unq_question_multi_choice" ON "question_transition" ("type", "fromQuestionId") WHERE (type = 'multi-choice'::question_transition_type_enum)`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,6 @@ Content-Type: application/json
|
|||||||
{
|
{
|
||||||
"question": 13,
|
"question": 13,
|
||||||
"text": "Option 4",
|
"text": "Option 4",
|
||||||
"value": 1,
|
|
||||||
"order": 4,
|
"order": 4,
|
||||||
"score": 10
|
"score": 10
|
||||||
}
|
}
|
||||||
@@ -27,14 +27,6 @@ export class CreateChoiceDTO {
|
|||||||
})
|
})
|
||||||
text!: string;
|
text!: string;
|
||||||
|
|
||||||
@IsNumber()
|
|
||||||
@IsNotEmpty({
|
|
||||||
message: t('validation.requiredField', {
|
|
||||||
field: '$t(questions.fields.value)',
|
|
||||||
}),
|
|
||||||
})
|
|
||||||
value!: number;
|
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsNotEmpty({
|
@IsNotEmpty({
|
||||||
message: t('validation.requiredField', {
|
message: t('validation.requiredField', {
|
||||||
|
|||||||
@@ -16,10 +16,6 @@ export class FindChoicesDTO extends PartialType(PaginationQueryDTO) {
|
|||||||
@IsOptional()
|
@IsOptional()
|
||||||
text?: string;
|
text?: string;
|
||||||
|
|
||||||
@IsNumber()
|
|
||||||
@IsOptional()
|
|
||||||
value?: number;
|
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
choiceOrder?: number;
|
choiceOrder?: number;
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ export class Choice {
|
|||||||
})
|
})
|
||||||
text!: string;
|
text!: string;
|
||||||
|
|
||||||
@Column({ type: 'int', nullable: false })
|
|
||||||
value!: number;
|
|
||||||
|
|
||||||
@Column({ type: 'int', nullable: false })
|
@Column({ type: 'int', nullable: false })
|
||||||
order!: number;
|
order!: number;
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,5 @@ export enum ChoiceSortField {
|
|||||||
QUESTION = 'question',
|
QUESTION = 'question',
|
||||||
TEXT = 'text',
|
TEXT = 'text',
|
||||||
ORDER = 'order',
|
ORDER = 'order',
|
||||||
VALUE = 'value',
|
|
||||||
SCORE = 'score',
|
SCORE = 'score',
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,10 +17,6 @@ export const filterChoices = (query: FindChoicesDTO) => {
|
|||||||
where.order = query.choiceOrder;
|
where.order = query.choiceOrder;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (query.value !== undefined) {
|
|
||||||
where.value = query.value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query.score !== undefined) {
|
if (query.score !== undefined) {
|
||||||
where.score = query.score;
|
where.score = query.score;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
Column,
|
Column,
|
||||||
|
CreateDateColumn,
|
||||||
Entity,
|
Entity,
|
||||||
Index,
|
Index,
|
||||||
JoinTable,
|
JoinTable,
|
||||||
@@ -44,4 +45,7 @@ export class SubmissionAnswer {
|
|||||||
nullable: true,
|
nullable: true,
|
||||||
})
|
})
|
||||||
textValue?: string;
|
textValue?: string;
|
||||||
|
|
||||||
|
@CreateDateColumn()
|
||||||
|
createdAt!: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,9 @@ export class Submission {
|
|||||||
@PrimaryGeneratedColumn()
|
@PrimaryGeneratedColumn()
|
||||||
id!: number;
|
id!: number;
|
||||||
|
|
||||||
|
@Column({ type: 'varchar', nullable: true })
|
||||||
|
code!: string;
|
||||||
|
|
||||||
@ManyToOne(() => User, { onDelete: 'CASCADE' })
|
@ManyToOne(() => User, { onDelete: 'CASCADE' })
|
||||||
user!: User;
|
user!: User;
|
||||||
|
|
||||||
@@ -43,4 +46,7 @@ export class Submission {
|
|||||||
|
|
||||||
@CreateDateColumn()
|
@CreateDateColumn()
|
||||||
createdAt!: Date;
|
createdAt!: Date;
|
||||||
|
|
||||||
|
@Column({ type: 'timestamptz', nullable: true })
|
||||||
|
completedAt?: Date;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -183,7 +183,11 @@ export class AnswerAuthenticatedProvider {
|
|||||||
await manager.update(
|
await manager.update(
|
||||||
Submission,
|
Submission,
|
||||||
{ id: submission.id },
|
{ id: submission.id },
|
||||||
{ currentQuestion: null, status: SubmissionStatus.COMPLETED },
|
{
|
||||||
|
currentQuestion: null,
|
||||||
|
status: SubmissionStatus.COMPLETED,
|
||||||
|
completedAt: new Date(),
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const result =
|
const result =
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import { AccessType } from '@/modules/tests/enums/access-types.enum';
|
|||||||
import { TestsService } from '@/modules/tests/providers/tests.service';
|
import { TestsService } from '@/modules/tests/providers/tests.service';
|
||||||
import { User } from '@/modules/users/entities/user.entity';
|
import { User } from '@/modules/users/entities/user.entity';
|
||||||
import {
|
import {
|
||||||
BadRequestException,
|
|
||||||
ForbiddenException,
|
ForbiddenException,
|
||||||
Injectable,
|
Injectable,
|
||||||
NotFoundException,
|
NotFoundException,
|
||||||
@@ -12,7 +11,6 @@ import { Submission } from '../../entities/submission.entity';
|
|||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception';
|
import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception';
|
||||||
import { AppResponse } from '@/common/responses';
|
import { AppResponse } from '@/common/responses';
|
||||||
import { SubmissionStatus } from '../../enums/submission-status.enum';
|
|
||||||
import { Test } from '@/modules/tests/entities/test.entity';
|
import { Test } from '@/modules/tests/entities/test.entity';
|
||||||
import { randomUUID } from 'crypto';
|
import { randomUUID } from 'crypto';
|
||||||
import { RedisService } from '@/common/modules/redis/providers/redis.service';
|
import { RedisService } from '@/common/modules/redis/providers/redis.service';
|
||||||
@@ -20,6 +18,7 @@ import { GuestSubmissionSession } from '../../interfaces/guest-submission-sessio
|
|||||||
import { TestStatus } from '@/modules/tests/enums/test-status.enum';
|
import { TestStatus } from '@/modules/tests/enums/test-status.enum';
|
||||||
import { QuestionTransition } from '@/modules/questions/entities/question-transition.entity';
|
import { QuestionTransition } from '@/modules/questions/entities/question-transition.entity';
|
||||||
import { QuestionTransitionType } from '@/modules/questions/enums/question-transition-type.enum';
|
import { QuestionTransitionType } from '@/modules/questions/enums/question-transition-type.enum';
|
||||||
|
import Utils from '@/common/utils';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class StartSubmissionProvider {
|
export class StartSubmissionProvider {
|
||||||
@@ -113,41 +112,19 @@ export class StartSubmissionProvider {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async startAuthenticated(test: Test, user: User) {
|
private async startAuthenticated(test: Test, user: User) {
|
||||||
let submission: Submission | null = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
submission = await this.submissionsRepository.findOne({
|
|
||||||
where: {
|
|
||||||
test: {
|
|
||||||
id: test.id,
|
|
||||||
},
|
|
||||||
user: {
|
|
||||||
id: user.id,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
} catch (err) {
|
|
||||||
throw new AppTimeoutException(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (submission && submission.status === SubmissionStatus.COMPLETED) {
|
|
||||||
throw new BadRequestException('submissions.errors.alreadyTookTest');
|
|
||||||
}
|
|
||||||
|
|
||||||
const firstQuestion = await this.getFirstQuestion(test.id);
|
const firstQuestion = await this.getFirstQuestion(test.id);
|
||||||
|
|
||||||
if (!submission) {
|
const submission = this.submissionsRepository.create({
|
||||||
submission = this.submissionsRepository.create({
|
test,
|
||||||
test,
|
user: user || undefined,
|
||||||
user: user || undefined,
|
currentQuestion: firstQuestion,
|
||||||
currentQuestion: firstQuestion,
|
code: Utils.StringUtils.generateCode({ prefix: 's-' }),
|
||||||
});
|
});
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.submissionsRepository.save(submission);
|
await this.submissionsRepository.save(submission);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
throw new AppTimeoutException(err);
|
throw new AppTimeoutException(err);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new AppResponse({
|
return new AppResponse({
|
||||||
|
|||||||
Reference in New Issue
Block a user