feat: complete auth and submission's swagger docs
This commit is contained in:
@@ -26,16 +26,13 @@ export class AuthController {
|
|||||||
@ApiAppResponse([
|
@ApiAppResponse([
|
||||||
{
|
{
|
||||||
status: HttpStatus.OK,
|
status: HttpStatus.OK,
|
||||||
description: 'Successfull responses',
|
|
||||||
variants: [
|
variants: [
|
||||||
{
|
{
|
||||||
model: TokensResponseDTO,
|
model: TokensResponseDTO,
|
||||||
example: {
|
example: {
|
||||||
data: {
|
data: {
|
||||||
access:
|
access: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
|
||||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJyb2xlIjoidXNlciIsImlhdCI6MTcyNDAwMDAwMCwiZXhwIjoxNzI0MDAzNjAwfQ.dGVzdC1zaWduYXR1cmU',
|
refresh: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
|
||||||
refresh:
|
|
||||||
'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjMiLCJyb2xlIjoidXNlciIsImlhdCI6MTcyNDAwMDAwMCwiZXhwIjoxNzI0MDAzNjAwfQ.dGVzdC1zaWduYXR1cmU',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -61,8 +58,7 @@ export class AuthController {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
status: HttpStatus.BAD_REQUEST,
|
status: HttpStatus.UNAUTHORIZED,
|
||||||
description: 'BadRequest responses',
|
|
||||||
variants: [
|
variants: [
|
||||||
{
|
{
|
||||||
messageExample: 'شماره موبایل یا رمز عبور اشتباه است.',
|
messageExample: 'شماره موبایل یا رمز عبور اشتباه است.',
|
||||||
@@ -71,7 +67,6 @@ export class AuthController {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
status: HttpStatus.TOO_MANY_REQUESTS,
|
status: HttpStatus.TOO_MANY_REQUESTS,
|
||||||
description: 'TooManyRequests responses',
|
|
||||||
variants: [
|
variants: [
|
||||||
{
|
{
|
||||||
messageExample:
|
messageExample:
|
||||||
@@ -88,6 +83,24 @@ export class AuthController {
|
|||||||
@Post('verify-otp')
|
@Post('verify-otp')
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@Throttle({ otp: {} })
|
@Throttle({ otp: {} })
|
||||||
|
@ApiAppResponse([
|
||||||
|
{
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
model: TokensResponseDTO,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: HttpStatus.UNAUTHORIZED,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
messageExample: 'کد تایید اشتباه است یا منقضی شده.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
public async verifyOTP(@Body() verifyOtpDto: VerifyOtpDTO) {
|
public async verifyOTP(@Body() verifyOtpDto: VerifyOtpDTO) {
|
||||||
return await this.authService.verifyOTP(verifyOtpDto);
|
return await this.authService.verifyOTP(verifyOtpDto);
|
||||||
}
|
}
|
||||||
@@ -96,6 +109,20 @@ export class AuthController {
|
|||||||
@Post('refresh')
|
@Post('refresh')
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@Throttle({ login: {} })
|
@Throttle({ login: {} })
|
||||||
|
@ApiAppResponse([
|
||||||
|
{
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
model: TokensResponseDTO,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: HttpStatus.UNAUTHORIZED,
|
||||||
|
variants: [{ messageExample: 'توکن قبلا استفاده شده.' }],
|
||||||
|
},
|
||||||
|
])
|
||||||
public async refreshToken(@Body() refreshTokenDto: RefreshTokenDTO) {
|
public async refreshToken(@Body() refreshTokenDto: RefreshTokenDTO) {
|
||||||
return await this.authService.refreshToken(refreshTokenDto);
|
return await this.authService.refreshToken(refreshTokenDto);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,11 +3,13 @@ import { ApiProperty } from '@nestjs/swagger';
|
|||||||
export class TokensResponseDTO {
|
export class TokensResponseDTO {
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
|
||||||
})
|
})
|
||||||
access!: string;
|
access!: string;
|
||||||
|
|
||||||
@ApiProperty({
|
@ApiProperty({
|
||||||
type: 'string',
|
type: 'string',
|
||||||
|
example: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
|
||||||
})
|
})
|
||||||
refresh!: string;
|
refresh!: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,22 @@
|
|||||||
import { IsArray, IsInt, IsNumber, IsOptional } from 'class-validator';
|
import { IsArray, IsInt, IsNumber, IsOptional } from 'class-validator';
|
||||||
import { SubmissionAnswer } from '../decorators/submission-answer.decorator';
|
import { SubmissionAnswer } from '../decorators/submission-answer.decorator';
|
||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
|
||||||
export class AnswerSubmissionDTO {
|
export class AnswerSubmissionDTO {
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiPropertyOptional()
|
||||||
choiceId?: number;
|
choiceId?: number;
|
||||||
|
|
||||||
@IsArray()
|
@IsArray()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@IsInt({ each: true })
|
@IsInt({ each: true })
|
||||||
|
@ApiPropertyOptional({ isArray: true, type: 'number' })
|
||||||
choiceIds?: number[];
|
choiceIds?: number[];
|
||||||
|
|
||||||
@IsNumber()
|
@IsNumber()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
|
@ApiPropertyOptional()
|
||||||
numericValue?: number;
|
numericValue?: number;
|
||||||
|
|
||||||
@SubmissionAnswer()
|
@SubmissionAnswer()
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { GetSubmissionQuestionDTO } from './get-submission-question.dto';
|
||||||
|
import { GetSubmissionResultDTO } from './get-submission-result.dto';
|
||||||
|
|
||||||
|
export class GetAnswerSubmissionDTO {
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'boolean',
|
||||||
|
example: false,
|
||||||
|
})
|
||||||
|
isCompleted!: boolean;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: GetSubmissionQuestionDTO,
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
currentQuestion!: GetSubmissionQuestionDTO;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: GetSubmissionResultDTO,
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
result!: GetSubmissionResultDTO;
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class GetChoiceDTO {
|
||||||
|
@ApiProperty()
|
||||||
|
id!: number;
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
order!: number;
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
text!: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { GetSubmissionQuestionDTO } from './get-submission-question.dto';
|
||||||
|
import { GetMessageAnswerDTO } from './get-message-answer.dto';
|
||||||
|
|
||||||
|
export class GetHistoryMessageDTO {
|
||||||
|
@ApiProperty({
|
||||||
|
type: GetSubmissionQuestionDTO,
|
||||||
|
})
|
||||||
|
question!: GetSubmissionQuestionDTO;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: [GetMessageAnswerDTO],
|
||||||
|
})
|
||||||
|
answers!: Array<GetMessageAnswerDTO>;
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
import { ApiPropertyOptional } from '@nestjs/swagger';
|
||||||
|
import { GetChoiceDTO } from './get-choice.dto';
|
||||||
|
|
||||||
|
export class GetMessageAnswerDTO {
|
||||||
|
@ApiPropertyOptional()
|
||||||
|
choiceId!: boolean;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ type: GetChoiceDTO })
|
||||||
|
choice?: GetChoiceDTO;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ isArray: true, type: 'number' })
|
||||||
|
choiceIds!: Array<number>;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ isArray: true, type: GetChoiceDTO })
|
||||||
|
choices?: Array<GetChoiceDTO>;
|
||||||
|
|
||||||
|
@ApiPropertyOptional({ type: 'number' })
|
||||||
|
numericValue?: number;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { GetSubmissionQuestionDTO } from './get-submission-question.dto';
|
||||||
|
import { GetHistoryMessageDTO } from './get-history-message.dto';
|
||||||
|
|
||||||
|
export class GetSubmissionHistoryDTO {
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'boolean',
|
||||||
|
example: false,
|
||||||
|
})
|
||||||
|
isCompleted!: boolean;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
isArray: true,
|
||||||
|
type: GetHistoryMessageDTO,
|
||||||
|
})
|
||||||
|
messages!: Array<GetHistoryMessageDTO>;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: GetSubmissionQuestionDTO,
|
||||||
|
nullable: true,
|
||||||
|
})
|
||||||
|
currentQuestion!: GetSubmissionQuestionDTO;
|
||||||
|
}
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
import { QuestionType } from '@/modules/questions/enums/question-type.enum';
|
||||||
|
import { type QuestionMetadata } from '@/modules/questions/types/question-metadata.type';
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { GetChoiceDTO } from './get-choice.dto';
|
||||||
|
|
||||||
|
export class GetSubmissionQuestionDTO {
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'number',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
|
id!: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
enum: QuestionType,
|
||||||
|
enumName: 'questionType',
|
||||||
|
})
|
||||||
|
type!: QuestionType;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'string',
|
||||||
|
})
|
||||||
|
content!: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'boolean',
|
||||||
|
})
|
||||||
|
required!: boolean;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: [GetChoiceDTO],
|
||||||
|
})
|
||||||
|
choices!: Array<GetChoiceDTO>;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
oneOf: [
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
min: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
max: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
step: {
|
||||||
|
type: 'number',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ['min', 'max'],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'object',
|
||||||
|
properties: {
|
||||||
|
allowOther: {
|
||||||
|
type: 'boolean',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
required: ['allowOther'],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
})
|
||||||
|
metadata!: QuestionMetadata;
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class GetSubmissionResultDTO {
|
||||||
|
@ApiProperty()
|
||||||
|
score!: number;
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
probability!: number;
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
title!: string;
|
||||||
|
|
||||||
|
@ApiProperty()
|
||||||
|
description!: string;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { GetSubmissionQuestionDTO } from './get-submission-question.dto';
|
||||||
|
|
||||||
|
export class StartAuthenticatedDTO {
|
||||||
|
@ApiProperty({ type: 'number', required: true })
|
||||||
|
submissionId!: number;
|
||||||
|
|
||||||
|
@ApiProperty({ type: GetSubmissionQuestionDTO })
|
||||||
|
question!: GetSubmissionQuestionDTO;
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { GetSubmissionQuestionDTO } from './get-submission-question.dto';
|
||||||
|
|
||||||
|
export class StartGuestDTO {
|
||||||
|
@ApiProperty({ type: 'string', required: true })
|
||||||
|
guestSubmissionId!: string;
|
||||||
|
|
||||||
|
@ApiProperty({ type: GetSubmissionQuestionDTO })
|
||||||
|
question!: GetSubmissionQuestionDTO;
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
import { IsNotEmpty, IsNumber } from 'class-validator';
|
import { IsNotEmpty, IsNumber } from 'class-validator';
|
||||||
import { i18nValidationMessage as t } from 'nestjs-i18n';
|
import { i18nValidationMessage as t } from 'nestjs-i18n';
|
||||||
|
|
||||||
@@ -8,5 +9,9 @@ export class StartSubmissionDTO {
|
|||||||
field: '$t(submissions.fields.testId)',
|
field: '$t(submissions.fields.testId)',
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'number',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
testId!: number;
|
testId!: number;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,6 +96,7 @@ export class HistoryAuthenticatedProvider {
|
|||||||
type: answer.question.type,
|
type: answer.question.type,
|
||||||
content: answer.question.content,
|
content: answer.question.content,
|
||||||
required: answer.question.required,
|
required: answer.question.required,
|
||||||
|
choices: answer.choices,
|
||||||
metadata: answer.question.metadata,
|
metadata: answer.question.metadata,
|
||||||
},
|
},
|
||||||
answer: {
|
answer: {
|
||||||
|
|||||||
@@ -15,6 +15,11 @@ import { ActiveUser } from '@/common/decorators/active-user.decorator';
|
|||||||
import { SubmissionsService } from './providers/submissions.service';
|
import { SubmissionsService } from './providers/submissions.service';
|
||||||
import { StartSubmissionDTO } from './dtos/start-submission.dto';
|
import { StartSubmissionDTO } from './dtos/start-submission.dto';
|
||||||
import { AnswerSubmissionDTO } from './dtos/answer-submission.dto';
|
import { AnswerSubmissionDTO } from './dtos/answer-submission.dto';
|
||||||
|
import { ApiAppResponse } from '@/common/decorators/api-app-response.decorator';
|
||||||
|
import { StartAuthenticatedDTO } from './dtos/responses/start-authenticated.dto';
|
||||||
|
import { StartGuestDTO } from './dtos/responses/start-guest.dto';
|
||||||
|
import { GetAnswerSubmissionDTO } from './dtos/responses/get-answer-submission.dto';
|
||||||
|
import { GetSubmissionHistoryDTO } from './dtos/responses/get-submission-history.dto';
|
||||||
|
|
||||||
@Controller('submissions')
|
@Controller('submissions')
|
||||||
export class SubmissionsController {
|
export class SubmissionsController {
|
||||||
@@ -29,6 +34,63 @@ export class SubmissionsController {
|
|||||||
@Post('start')
|
@Post('start')
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@UseGuards(OptionalJwtGuard)
|
@UseGuards(OptionalJwtGuard)
|
||||||
|
@ApiAppResponse([
|
||||||
|
{
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
model: StartAuthenticatedDTO,
|
||||||
|
example: {
|
||||||
|
data: {
|
||||||
|
submissionId: 1,
|
||||||
|
question: {
|
||||||
|
id: 1,
|
||||||
|
type: 'numeric',
|
||||||
|
content: 'string',
|
||||||
|
required: true,
|
||||||
|
choices: [],
|
||||||
|
metadata: {
|
||||||
|
min: 0,
|
||||||
|
max: 10,
|
||||||
|
step: 1,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
model: StartGuestDTO,
|
||||||
|
example: {
|
||||||
|
data: {
|
||||||
|
guestSubmissionId: 'sahfdih123ieg1231fds23ljhakshf',
|
||||||
|
question: {
|
||||||
|
id: 2,
|
||||||
|
type: 'single-choice',
|
||||||
|
content: 'string',
|
||||||
|
required: true,
|
||||||
|
choices: [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
order: 1,
|
||||||
|
text: 'string',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
metadata: null,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: HttpStatus.NOT_FOUND,
|
||||||
|
variants: [{ messageExample: 'تست مورد نظر یافت نشد.' }],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: HttpStatus.FORBIDDEN,
|
||||||
|
variants: [{ messageExample: 'تست مورد نظر فعال نیست.' }],
|
||||||
|
},
|
||||||
|
])
|
||||||
public async startTest(
|
public async startTest(
|
||||||
@Body() startSubmissionDto: StartSubmissionDTO,
|
@Body() startSubmissionDto: StartSubmissionDTO,
|
||||||
@ActiveUser() user?: User,
|
@ActiveUser() user?: User,
|
||||||
@@ -43,6 +105,16 @@ export class SubmissionsController {
|
|||||||
@Post(':id/answer')
|
@Post(':id/answer')
|
||||||
@HttpCode(HttpStatus.OK)
|
@HttpCode(HttpStatus.OK)
|
||||||
@UseGuards(OptionalJwtGuard)
|
@UseGuards(OptionalJwtGuard)
|
||||||
|
@ApiAppResponse([
|
||||||
|
{
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
model: GetAnswerSubmissionDTO,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
public async answerSubmission(
|
public async answerSubmission(
|
||||||
@Param('id') id: string,
|
@Param('id') id: string,
|
||||||
@Body() answerSubmissionDto: AnswerSubmissionDTO,
|
@Body() answerSubmissionDto: AnswerSubmissionDTO,
|
||||||
@@ -58,6 +130,16 @@ export class SubmissionsController {
|
|||||||
@Public()
|
@Public()
|
||||||
@Get(':id/history')
|
@Get(':id/history')
|
||||||
@UseGuards(OptionalJwtGuard)
|
@UseGuards(OptionalJwtGuard)
|
||||||
|
@ApiAppResponse([
|
||||||
|
{
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
model: GetSubmissionHistoryDTO,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
public async getHistory(@Param('id') id: string, @ActiveUser() user?: User) {
|
public async getHistory(@Param('id') id: string, @ActiveUser() user?: User) {
|
||||||
return await this.submissionsService.getSubmissionHistory(id, user);
|
return await this.submissionsService.getSubmissionHistory(id, user);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { AccessType } from '../../enums/access-types.enum';
|
||||||
|
|
||||||
|
export class GetTestByIdDTO {
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'number',
|
||||||
|
example: 1,
|
||||||
|
})
|
||||||
|
id!: number;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'string',
|
||||||
|
example: 'Test Title',
|
||||||
|
})
|
||||||
|
title!: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'string',
|
||||||
|
example: 'Test description',
|
||||||
|
})
|
||||||
|
description!: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
enum: AccessType,
|
||||||
|
enumName: 'accessType',
|
||||||
|
example: 'login',
|
||||||
|
})
|
||||||
|
accessType!: AccessType;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'string',
|
||||||
|
example: '1000000',
|
||||||
|
})
|
||||||
|
price!: string;
|
||||||
|
}
|
||||||
@@ -1,6 +1,14 @@
|
|||||||
import { Controller, Get, Param, ParseIntPipe } from '@nestjs/common';
|
import {
|
||||||
|
Controller,
|
||||||
|
Get,
|
||||||
|
HttpStatus,
|
||||||
|
Param,
|
||||||
|
ParseIntPipe,
|
||||||
|
} from '@nestjs/common';
|
||||||
import { TestsService } from './providers/tests.service';
|
import { TestsService } from './providers/tests.service';
|
||||||
import { Public } from '../auth/decorators/public.decorator';
|
import { Public } from '../auth/decorators/public.decorator';
|
||||||
|
import { ApiAppResponse } from '@/common/decorators/api-app-response.decorator';
|
||||||
|
import { GetTestByIdDTO } from './dtos/responses/get-test-by-id.dto';
|
||||||
|
|
||||||
@Controller('tests')
|
@Controller('tests')
|
||||||
export class TestsController {
|
export class TestsController {
|
||||||
@@ -13,12 +21,41 @@ export class TestsController {
|
|||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
@Get()
|
@Get()
|
||||||
|
@ApiAppResponse([
|
||||||
|
{
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
isArray: true,
|
||||||
|
model: GetTestByIdDTO,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
public async getAllTests() {
|
public async getAllTests() {
|
||||||
return await this.testsService.userGetAll();
|
return await this.testsService.userGetAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Public()
|
@Public()
|
||||||
@Get(':id')
|
@Get(':id')
|
||||||
|
@ApiAppResponse([
|
||||||
|
{
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
model: GetTestByIdDTO,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: HttpStatus.NOT_FOUND,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
messageExample: 'تست مورد نظر یافت نشد.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
public async getTestById(@Param('id', ParseIntPipe) id: number) {
|
public async getTestById(@Param('id', ParseIntPipe) id: number) {
|
||||||
return await this.testsService.userGetOne(id);
|
return await this.testsService.userGetOne(id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
|
||||||
|
export class GetProfileDTO {
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'string',
|
||||||
|
example: '09121111111',
|
||||||
|
})
|
||||||
|
phone!: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'string',
|
||||||
|
example: 'John',
|
||||||
|
})
|
||||||
|
firstName!: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'string',
|
||||||
|
example: 'Doe',
|
||||||
|
})
|
||||||
|
lastName!: string;
|
||||||
|
|
||||||
|
@ApiProperty({
|
||||||
|
type: 'string',
|
||||||
|
example: '2026-09-01T09:24:34.894Z',
|
||||||
|
})
|
||||||
|
dateJoined!: Date;
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ import { HashingProvider } from '@/common/modules/hashing/providers/hashing.prov
|
|||||||
import { Injectable } from '@nestjs/common';
|
import { Injectable } from '@nestjs/common';
|
||||||
import { I18nService } from 'nestjs-i18n';
|
import { I18nService } from 'nestjs-i18n';
|
||||||
import { User } from '../entities/user.entity';
|
import { User } from '../entities/user.entity';
|
||||||
import { UpdateProfileDTO } from '../dto/update-profile.dto';
|
import { UpdateProfileDTO } from '../dtos/update-profile.dto';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { AppResponse } from '@/common/responses';
|
import { AppResponse } from '@/common/responses';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { BadRequestException, Injectable } from '@nestjs/common';
|
|||||||
import { Repository } from 'typeorm';
|
import { Repository } from 'typeorm';
|
||||||
import { User } from '../entities/user.entity';
|
import { User } from '../entities/user.entity';
|
||||||
import { InjectRepository } from '@nestjs/typeorm';
|
import { InjectRepository } from '@nestjs/typeorm';
|
||||||
import { UpdateProfileDTO } from '../dto/update-profile.dto';
|
import { UpdateProfileDTO } from '../dtos/update-profile.dto';
|
||||||
import { UserProfileProvider } from './user-profile.provider';
|
import { UserProfileProvider } from './user-profile.provider';
|
||||||
import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception';
|
import { AppTimeoutException } from '@/common/exceptions/app-timeout.exception';
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
import { Body, Controller, Get, Patch } from '@nestjs/common';
|
import { Body, Controller, Get, HttpStatus, Patch } from '@nestjs/common';
|
||||||
import { UsersService } from './providers/users.service';
|
import { UsersService } from './providers/users.service';
|
||||||
import { ActiveUser } from '@/common/decorators/active-user.decorator';
|
import { ActiveUser } from '@/common/decorators/active-user.decorator';
|
||||||
import { User } from './entities/user.entity';
|
import { User } from './entities/user.entity';
|
||||||
import { UpdateProfileDTO } from './dto/update-profile.dto';
|
import { UpdateProfileDTO } from './dtos/update-profile.dto';
|
||||||
|
import { ApiAppResponse } from '@/common/decorators/api-app-response.decorator';
|
||||||
|
import { GetProfileDTO } from './dtos/responses/get-profile.dto';
|
||||||
|
|
||||||
@Controller('users')
|
@Controller('users')
|
||||||
export class UsersController {
|
export class UsersController {
|
||||||
@@ -14,11 +16,39 @@ export class UsersController {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
@Get('profile')
|
@Get('profile')
|
||||||
|
@ApiAppResponse([
|
||||||
|
{
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
model: GetProfileDTO,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
status: HttpStatus.UNAUTHORIZED,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
messageExample: 'دسترسی غیر مجاز',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
public getUserProfile(@ActiveUser() user: User) {
|
public getUserProfile(@ActiveUser() user: User) {
|
||||||
return this.usersService.getProfile(user);
|
return this.usersService.getProfile(user);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch('profile')
|
@Patch('profile')
|
||||||
|
@ApiAppResponse([
|
||||||
|
{
|
||||||
|
status: HttpStatus.OK,
|
||||||
|
variants: [
|
||||||
|
{
|
||||||
|
messageExample: 'تغییرات با موفقیت اعمال شد.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
])
|
||||||
public async updateUserProfile(
|
public async updateUserProfile(
|
||||||
@ActiveUser() user: User,
|
@ActiveUser() user: User,
|
||||||
@Body() updateProfileDto: UpdateProfileDTO,
|
@Body() updateProfileDto: UpdateProfileDTO,
|
||||||
|
|||||||
Reference in New Issue
Block a user