swagger updates

This commit is contained in:
harshithnrao 2025-03-05 10:00:18 +05:30
parent aa8ae8c5af
commit ef02c555f5
15 changed files with 2638 additions and 5161 deletions

6715
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -23,12 +23,12 @@
"test:e2e": "jest --config ./test/jest-e2e.json" "test:e2e": "jest --config ./test/jest-e2e.json"
}, },
"dependencies": { "dependencies": {
"@nestjs-modules/mailer": "^1.10.3",
"@nestjs/axios": "^4.0.0", "@nestjs/axios": "^4.0.0",
"@nestjs/common": "^10.0.0", "@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.1.1", "@nestjs/config": "^3.1.1",
"@nestjs/core": "^10.0.0", "@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0", "@nestjs/platform-express": "^10.0.0",
"@nestjs/swagger": "^8.1.1",
"@nestjs/typeorm": "^10.0.1", "@nestjs/typeorm": "^10.0.1",
"dotenv": "^16.3.1", "dotenv": "^16.3.1",
"handlebars": "^4.7.8", "handlebars": "^4.7.8",

View File

@ -45,4 +45,8 @@ export class AppConfigService {
getUrlConfig(){ getUrlConfig(){
return configMaster[this.defaultEnv].urlConfig; return configMaster[this.defaultEnv].urlConfig;
} }
getSWaggerConfig() {
return configMaster[this.defaultEnv].swaggerConfig;
}
} }

View File

@ -32,6 +32,14 @@
}, },
"urlConfig": { "urlConfig": {
"textbookBaseUrl": "http://localhost/content/textbooks/" "textbookBaseUrl": "http://localhost/content/textbooks/"
},
"swaggerConfig": {
"swagger": {
"title": "Remedify Content API",
"description": "Remedify Content API",
"version": "1.0.0",
"tag": "Remedify Content API"
}
} }
} }
} }

View File

@ -32,6 +32,14 @@
}, },
"urlConfig": { "urlConfig": {
"textbookBaseUrl": "http://localhost/content/textbooks/" "textbookBaseUrl": "http://localhost/content/textbooks/"
},
"swaggerConfig": {
"swagger": {
"title": "Remedify Content API",
"description": "Remedify Content API",
"version": "1.0.0",
"tag": "Remedify Content API"
}
} }
} }
} }

View File

@ -4,6 +4,7 @@ export class Utility {
static sequelize: Sequelize; static sequelize: Sequelize;
static appPort: number = 3000; static appPort: number = 3000;
static models: any; static models: any;
static swaggerConfig: any;
static fileConfig: any = {"storagePath": "./uploads"}; static fileConfig: any = {"storagePath": "./uploads"};
static mailConfig: any = { static mailConfig: any = {
"transport": { "transport": {

View File

@ -1,29 +1,36 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript'; import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({tableName: 'crud_config_info', paranoid : true}) @Table({ tableName: 'crud_config_info', paranoid: true })
export default class DataModel extends Model { export default class DataModel extends Model {
@Column({type: DataType.NUMBER}) @ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER })
endPtNm: number; endPtNm: number;
@Column({type: DataType.TEXT}) @ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
sqlQueryText: string; sqlQueryText: string;
@Column({type: DataType.TEXT}) @ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
opsTypeName: string; opsTypeName: string;
@ApiProperty({ type: Date, default: new Date() })
@Default(new Date()) @Default(new Date())
@Column({type: DataType.DATEONLY}) @Column({ type: DataType.DATEONLY })
validFrom: Date; validFrom: Date;
@ApiProperty({ type: Date, default: new Date("2070-12-31") })
@Default(new Date("2070-12-31")) @Default(new Date("2070-12-31"))
@Column({type: DataType.DATEONLY}) @Column({ type: DataType.DATEONLY })
validTill: Date; validTill: Date;
@Column({type: DataType.TEXT}) @ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
createBy: string; createBy: string;
@Column({type: DataType.TEXT}) @ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
modifiedBy: string; modifiedBy: string;
} }

View File

@ -1,5 +1,5 @@
import { MailerModule } from '@nestjs-modules/mailer'; // import { MailerModule } from '@nestjs-modules/mailer';
import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter'; // import { HandlebarsAdapter } from '@nestjs-modules/mailer/dist/adapters/handlebars.adapter';
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { MailService } from './mail.service'; import { MailService } from './mail.service';
import { join } from 'path'; import { join } from 'path';
@ -7,19 +7,19 @@ import { Utility } from 'src/common/Utility';
@Module({ @Module({
imports: [ imports: [
MailerModule.forRoot({ // MailerModule.forRoot({
// transport: 'smtps://user@example.com:topsecret@smtp.example.com', // // transport: 'smtps://user@example.com:topsecret@smtp.example.com',
// or // // or
transport: Utility.mailConfig.transport, // transport: Utility.mailConfig.transport,
defaults: Utility.mailConfig.defaults, // defaults: Utility.mailConfig.defaults,
template: { // template: {
dir: join(__dirname, 'templates'), // dir: join(__dirname, 'templates'),
adapter: new HandlebarsAdapter(), // or new PugAdapter() or new EjsAdapter() // adapter: new HandlebarsAdapter(), // or new PugAdapter() or new EjsAdapter()
options: { // options: {
strict: true, // strict: true,
}, // },
}, // },
}), // }),
], ],
providers: [MailService], providers: [MailService],
exports: [MailService], // 👈 export for DI exports: [MailService], // 👈 export for DI

View File

@ -1,19 +1,19 @@
import { MailerService } from '@nestjs-modules/mailer'; // import { MailerService } from '@nestjs-modules/mailer';
import { Injectable } from '@nestjs/common'; import { Injectable } from '@nestjs/common';
@Injectable() @Injectable()
export class MailService { export class MailService {
constructor(private mailerService: MailerService) { } // constructor(private mailerS/ervice: MailerService) { }
async sendEmail(templateName: string, subject: string, context: any, toEmail: string, ccEmails?: string[], bccEmails?: string[]) { async sendEmail(templateName: string, subject: string, context: any, toEmail: string, ccEmails?: string[], bccEmails?: string[]) {
await this.mailerService.sendMail({ // await this.mailerService.sendMail({
to: toEmail, // to: toEmail,
cc: ccEmails, // cc: ccEmails,
bcc: bccEmails, // bcc: bccEmails,
subject: subject, // subject: subject,
template: templateName, // `.hbs` extension is appended automatically // template: templateName, // `.hbs` extension is appended automatically
context, // context,
}) // })
} }
} }

View File

@ -3,14 +3,27 @@ import { AppModule } from './app.module';
import * as bodyParser from 'body-parser'; import * as bodyParser from 'body-parser';
import * as configMaster from './app-config/config.json'; import * as configMaster from './app-config/config.json';
import { Utility } from './common/Utility'; import { Utility } from './common/Utility';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
async function bootstrap() { async function bootstrap() {
Utility.appPort = configMaster.local.appConfig.port; Utility.appPort = configMaster.local.appConfig.port;
Utility.mailConfig = configMaster.local.mailConfig; Utility.mailConfig = configMaster.local.mailConfig;
Utility.fileConfig = configMaster.local.fileConfig; Utility.fileConfig = configMaster.local.fileConfig;
Utility.swaggerConfig = configMaster.local.swaggerConfig;
const app = await NestFactory.create(AppModule, { cors: true }); const app = await NestFactory.create(AppModule, { cors: true });
app.use(bodyParser.json({limit: '50mb'}));
app.use(bodyParser.urlencoded({limit: '50mb', extended: true})); const config = new DocumentBuilder()
.setTitle(Utility.swaggerConfig.swagger.title)
.setVersion(Utility.swaggerConfig.swagger.version)
.addTag(Utility.swaggerConfig.swagger.tag)
.setDescription(Utility.swaggerConfig.swagger.description)
.build();
const document = SwaggerModule.createDocument(app, config);
SwaggerModule.setup('api', app, document);
app.use(bodyParser.json({ limit: '50mb' }));
app.use(bodyParser.urlencoded({ limit: '50mb', extended: true }));
await app.listen(Utility.appPort); await app.listen(Utility.appPort);
} }
bootstrap(); bootstrap();

View File

@ -2,105 +2,309 @@ import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/co
import { TestQuestionRelService } from './test-question-rel.service'; import { TestQuestionRelService } from './test-question-rel.service';
import { Response } from 'express'; import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model'; import { GenericResponse } from '../common/GenericResponse.model';
import TestQuestionRel from './test-question-rel.entity'; import TestQuestionRel from './test-question-rel.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('test-question-rel')
@Controller('testQuestionRel') @Controller('testQuestionRel')
export class TestQuestionRelController { export class TestQuestionRelController {
constructor(private testQuestionRelService: TestQuestionRelService) {} constructor(private testQuestionRelService: TestQuestionRelService) {}
@Get("/all") @Get("/all")
@ApiOperation({ summary: 'Get all test question relationships' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all test question relationships',
})
@ApiResponse({
status: 404,
description: 'No test question relationships found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No test question relationships found"
},
"data": null
}
})
async getAllTestQuestionRels(@Res() res: Response) { async getAllTestQuestionRels(@Res() res: Response) {
const response = await this.testQuestionRelService.findAll() || []; const response = await this.testQuestionRelService.findAll() || [];
const httpResponse = new GenericResponse(null, response) if (!response) {
res.send(httpResponse); const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No test question relationships found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
} }
@Get(':id') @Get(':id')
@ApiOperation({ summary: 'Get test question relationship by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Test Question Relationship ID' })
@ApiResponse({
status: 400,
description: 'ID is required',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Test question relationship not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Test question relationship not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved test question relationship by ID',
})
async findById(@Param('id') id: number, @Res() res: Response) { async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) { if (!id) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
const response = await this.testQuestionRelService.findByPk(id) || {}; const response = await this.testQuestionRelService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response) if (!response) {
res.send(httpResponse); const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Test question relationship with ID ${id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
} }
@Post('/filter') @Post('/filter')
@ApiOperation({ summary: 'Filter test question relationships based on criteria' })
@ApiBody({ type: TestQuestionRel, description: 'Filter criteria for test question relationships' })
@ApiResponse({
status: 400,
description: 'Invalid filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_CRITERIA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'No test question relationships found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No test question relationships found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered test question relationships',
})
async filter(@Body() testQuestionRel: TestQuestionRel, @Res() res: Response) { async filter(@Body() testQuestionRel: TestQuestionRel, @Res() res: Response) {
if(!testQuestionRel) { if (!testQuestionRel) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.INVALID_CRITERIA',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
const response = await this.testQuestionRelService.filter(testQuestionRel) || []; const response = await this.testQuestionRelService.filter(testQuestionRel) || [];
const httpResponse = new GenericResponse(null, response) if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No test question relationships found based on the filter criteria'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse); res.status(200).send(httpResponse);
} }
@Post() @Post()
@ApiOperation({ summary: 'Insert a new test question relationship' })
@ApiBody({ type: TestQuestionRel, description: 'Test question relationship data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid test question relationship data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Test question relationship successfully created',
})
async insert(@Body() testQuestionRel: TestQuestionRel, @Res() res: Response) { async insert(@Body() testQuestionRel: TestQuestionRel, @Res() res: Response) {
if(!testQuestionRel) { if (!testQuestionRel) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
delete testQuestionRel.id; delete testQuestionRel.id;
const response = await this.testQuestionRelService.upsert(testQuestionRel, true); const response = await this.testQuestionRelService.upsert(testQuestionRel, true);
const httpResponse = new GenericResponse(null, response) const httpResponse = new GenericResponse(null, response);
res.send(httpResponse); res.status(201).send(httpResponse);
} }
@Put() @Put()
@ApiOperation({ summary: 'Update an existing test question relationship' })
@ApiBody({ type: TestQuestionRel, description: 'Test question relationship data to update' })
@ApiResponse({
status: 400,
description: 'Invalid test question relationship data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Test question relationship not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Test question relationship not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Test question relationship successfully updated',
})
async update(@Body() testQuestionRel: TestQuestionRel, @Res() res: Response) { async update(@Body() testQuestionRel: TestQuestionRel, @Res() res: Response) {
if(!testQuestionRel || !testQuestionRel.id) { if (!testQuestionRel || !testQuestionRel.id) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
const response = await this.testQuestionRelService.upsert(testQuestionRel, false); const response = await this.testQuestionRelService.upsert(testQuestionRel, false);
const httpResponse = new GenericResponse(null, response) if (!response) {
res.send(httpResponse); const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Test question relationship with ID ${testQuestionRel.id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
} }
@Delete(':id') @Delete(':id')
@ApiOperation({ summary: 'Delete a test question relationship by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Test Question Relationship ID to delete' })
@ApiResponse({
status: 400,
description: 'ID parameter is required',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Test question relationship not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Test question relationship not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Test question relationship successfully deleted',
})
async deleteById(@Param('id') id: number, @Res() res: Response) { async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) { if (!id) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
const response = await this.testQuestionRelService.remove(id) || {}; const response = await this.testQuestionRelService.remove(id) || {};
const httpResponse = new GenericResponse(null, response) if (!response) {
res.send(httpResponse); const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Test question relationship with ID ${id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
} }
} }

View File

@ -1,44 +1,56 @@
import { Table, Column, Model, Default, DataType, ForeignKey } from 'sequelize-typescript'; import { Table, Column, Model, Default, DataType, ForeignKey } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
import Question from 'src/question/question.entity'; import Question from 'src/question/question.entity';
import Test from 'src/test/test.entity'; import Test from 'src/test/test.entity';
@Table({ tableName: 'test_question_rel', paranoid: true }) @Table({ tableName: 'test_question_rel', paranoid: true })
export default class TestQuestionRel extends Model { export default class TestQuestionRel extends Model {
@ApiProperty({ type: Number })
@ForeignKey(() => Test) @ForeignKey(() => Test)
@Column(DataType.BIGINT) @Column(DataType.BIGINT)
testId: number; testId: number;
@ApiProperty({ type: Number })
@ForeignKey(() => Question) @ForeignKey(() => Question)
@Column(DataType.BIGINT) @Column(DataType.BIGINT)
questionId: number; questionId: number;
@ApiProperty({ type: Date, default: new Date() })
@Default(new Date()) @Default(new Date())
@Column(DataType.DATEONLY) @Column(DataType.DATEONLY)
validFrom: Date; validFrom: Date;
@ApiProperty({ type: Date, default: new Date("2070-12-31") })
@Default(new Date("2070-12-31")) @Default(new Date("2070-12-31"))
@Column(DataType.DATEONLY) @Column(DataType.DATEONLY)
validTill: Date; validTill: Date;
@Column(DataType.DATEONLY) @ApiProperty({ type: String, format: 'date-time' })
@Column(DataType.DATE)
createdAt: Date; createdAt: Date;
@Column(DataType.DATEONLY) @ApiProperty({ type: String, format: 'date-time' })
@Column(DataType.DATE)
updatedAt: Date; updatedAt: Date;
@ApiProperty({ type: String, required: false })
@Column(DataType.TEXT) @Column(DataType.TEXT)
createdBy: string; createdBy: string;
@ApiProperty({ type: String, required: false })
@Column(DataType.TEXT) @Column(DataType.TEXT)
modifiedBy: string; modifiedBy: string;
@ApiProperty({ type: Date, required: false })
@Column(DataType.DATEONLY) @Column(DataType.DATEONLY)
deletedAt: Date; deletedAt: Date;
@Column(DataType.NUMBER) @ApiProperty({ type: Number })
@Column(DataType.INTEGER)
version: number; version: number;
@ApiProperty({ type: String })
@Column(DataType.TEXT) @Column(DataType.TEXT)
status: string; status: string;
} }

View File

@ -2,105 +2,309 @@ import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/co
import { TestTagService } from './test-tag.service'; import { TestTagService } from './test-tag.service';
import { Response } from 'express'; import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model'; import { GenericResponse } from '../common/GenericResponse.model';
import TestTag from './test-tag.entity'; import TestTag from './test-tag.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('test-tag')
@Controller('test-tag') @Controller('test-tag')
export class TestTagController { export class TestTagController {
constructor(private testTagService: TestTagService) {} constructor(private testTagService: TestTagService) {}
@Get("/all") @Get("/all")
@ApiOperation({ summary: 'Get all test tags' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all test tags',
})
@ApiResponse({
status: 404,
description: 'No test tags found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No test tags found"
},
"data": null
}
})
async getAllTestTags(@Res() res: Response) { async getAllTestTags(@Res() res: Response) {
const response = await this.testTagService.findAll() || []; const response = await this.testTagService.findAll() || [];
const httpResponse = new GenericResponse(null, response) if (!response) {
res.send(httpResponse); const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No test tags found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
} }
@Get(':id') @Get(':id')
@ApiOperation({ summary: 'Get test tag by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Test Tag ID' })
@ApiResponse({
status: 400,
description: 'ID is required',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Test tag not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Test tag not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved test tag by ID',
})
async findById(@Param('id') id: number, @Res() res: Response) { async findById(@Param('id') id: number, @Res() res: Response) {
if(!id) { if (!id) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
const response = await this.testTagService.findByPk(id) || {}; const response = await this.testTagService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response) if (!response) {
res.send(httpResponse); const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Test tag with ID ${id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
} }
@Post('/filter') @Post('/filter')
@ApiOperation({ summary: 'Filter test tags based on criteria' })
@ApiBody({ type: TestTag, description: 'Filter criteria for test tags' })
@ApiResponse({
status: 400,
description: 'Invalid filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_CRITERIA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'No test tags found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No test tags found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered test tags',
})
async filter(@Body() testTag: TestTag, @Res() res: Response) { async filter(@Body() testTag: TestTag, @Res() res: Response) {
if(!testTag) { if (!testTag) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.INVALID_CRITERIA',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
const response = await this.testTagService.filter(testTag) || []; const response = await this.testTagService.filter(testTag) || [];
const httpResponse = new GenericResponse(null, response) if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No test tags found based on the filter criteria'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse); res.status(200).send(httpResponse);
} }
@Post() @Post()
@ApiOperation({ summary: 'Insert a new test tag' })
@ApiBody({ type: TestTag, description: 'Test tag data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid test tag data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Test tag successfully created',
})
async insert(@Body() testTag: TestTag, @Res() res: Response) { async insert(@Body() testTag: TestTag, @Res() res: Response) {
if(!testTag) { if (!testTag) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
delete testTag.id; delete testTag.id;
const response = await this.testTagService.upsert(testTag, true); const response = await this.testTagService.upsert(testTag, true);
const httpResponse = new GenericResponse(null, response) const httpResponse = new GenericResponse(null, response);
res.send(httpResponse); res.status(201).send(httpResponse);
} }
@Put() @Put()
@ApiOperation({ summary: 'Update an existing test tag' })
@ApiBody({ type: TestTag, description: 'Test tag data to update' })
@ApiResponse({
status: 400,
description: 'Invalid test tag data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Test tag not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Test tag not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Test tag successfully updated',
})
async update(@Body() testTag: TestTag, @Res() res: Response) { async update(@Body() testTag: TestTag, @Res() res: Response) {
if(!testTag || !testTag.id) { if (!testTag || !testTag.id) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
const response = await this.testTagService.upsert(testTag, false); const response = await this.testTagService.upsert(testTag, false);
const httpResponse = new GenericResponse(null, response) if (!response) {
res.send(httpResponse); const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Test tag with ID ${testTag.id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
} }
@Delete(':id') @Delete(':id')
@ApiOperation({ summary: 'Delete a test tag by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Test Tag ID to delete' })
@ApiResponse({
status: 400,
description: 'ID parameter is required',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Test tag not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Test tag not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Test tag successfully deleted',
})
async deleteById(@Param('id') id: number, @Res() res: Response) { async deleteById(@Param('id') id: number, @Res() res: Response) {
if(!id) { if (!id) {
const response = new GenericResponse({ const response = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request' stackTrace: 'Request'
}, null); }, null);
res.send(response); return res.status(400).send(response);
return;
} }
const response = await this.testTagService.remove(id) || {}; const response = await this.testTagService.remove(id) || {};
const httpResponse = new GenericResponse(null, response) if (!response) {
res.send(httpResponse); const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Test tag with ID ${id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
} }
} }

View File

@ -2,105 +2,318 @@ import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/co
import { UserAnswersService } from './user-answers.service'; import { UserAnswersService } from './user-answers.service';
import { Response } from 'express'; import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model'; import { GenericResponse } from '../common/GenericResponse.model';
import UserAnswers from './user-answers.entity'; import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
import UserAnswers from './user-answers.entity';
@ApiTags('user-answers')
@Controller('user-answers') @Controller('user-answers')
export class UserAnswersController { export class UserAnswersController {
constructor(private userAnswersService: UserAnswersService) {} constructor(private userAnswersService: UserAnswersService) {}
@Get("/all") @Get("/all")
async getAllUserAnswerss(@Res() res: Response) { @ApiOperation({ summary: 'Get all user answers' })
const response = await this.userAnswersService.findAll() || []; @ApiResponse({
const httpResponse = new GenericResponse(null, response) status: 200,
res.send(httpResponse); description: 'Successfully retrieved all user answers',
})
@ApiResponse({
status: 404,
description: 'No user answers found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No user answers found"
},
"data": null
} }
})
@Get(':id') async getAllUserAnswers(@Res() res: Response) {
async findById(@Param('id') id: number, @Res() res: Response) { const response = await this.userAnswersService.findAll() || [];
if(!id) { if (!response) {
const response = new GenericResponse({ const errorResponse = new GenericResponse({
exception: true, exception: true,
exceptionSeverity: 'HIGH', exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ', exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'Request' stackTrace: 'No user answers found'
}, null); }, null);
res.send(response); return res.status(404).send(errorResponse);
return;
}
const response = await this.userAnswersService.findByPk(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
} }
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Post('/filter') @Get(':id')
async filter(@Body() userAnswers: UserAnswers, @Res() res: Response) { @ApiOperation({ summary: 'Get user answer by ID' })
if(!userAnswers) { @ApiParam({ name: 'id', type: Number, description: 'User answer ID' })
const response = new GenericResponse({ @ApiResponse({
exception: true, status: 400,
exceptionSeverity: 'HIGH', description: 'ID is required',
exceptionMessage: 'ERR.NO_ID_REQ', example: {
stackTrace: 'Request' "notification": {
}, null); "exception": true,
res.send(response); "exceptionSeverity": "HIGH",
return; "exceptionMessage": "ERR.NO_ID_REQ",
} "stackTrace": "Request"
const response = await this.userAnswersService.filter(userAnswers) || []; },
const httpResponse = new GenericResponse(null, response) "data": null
res.status(200).send(httpResponse);
} }
})
@Post() @ApiResponse({
async insert(@Body() userAnswers: UserAnswers, @Res() res: Response) { status: 404,
if(!userAnswers) { description: 'User answer not found',
const response = new GenericResponse({ example: {
exception: true, "notification": {
exceptionSeverity: 'HIGH', "exception": true,
exceptionMessage: 'ERR.NO_ID_REQ', "exceptionSeverity": "HIGH",
stackTrace: 'Request' "exceptionMessage": "ERR.NOT_FOUND",
}, null); "stackTrace": "User answer not found"
res.send(response); },
return; "data": null
}
delete userAnswers.id;
const response = await this.userAnswersService.upsert(userAnswers, true);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
} }
})
@Put() @ApiResponse({
async update(@Body() userAnswers: UserAnswers, @Res() res: Response) { status: 200,
if(!userAnswers || !userAnswers.id) { description: 'Successfully retrieved user answer by ID',
const response = new GenericResponse({ })
exception: true, async findById(@Param('id') id: number, @Res() res: Response) {
exceptionSeverity: 'HIGH', if (!id) {
exceptionMessage: 'ERR.NO_ID_REQ', const response = new GenericResponse({
stackTrace: 'Request' exception: true,
}, null); exceptionSeverity: 'HIGH',
res.send(response); exceptionMessage: 'ERR.NO_ID_REQ',
return; stackTrace: 'Request'
} }, null);
return res.status(400).send(response);
const response = await this.userAnswersService.upsert(userAnswers, false);
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
} }
const response = await this.userAnswersService.findByPk(id) || {};
@Delete(':id') if (!response) {
async deleteById(@Param('id') id: number, @Res() res: Response) { const errorResponse = new GenericResponse({
if(!id) { exception: true,
const response = new GenericResponse({ exceptionSeverity: 'HIGH',
exception: true, exceptionMessage: 'ERR.NOT_FOUND',
exceptionSeverity: 'HIGH', stackTrace: `User answer with ID ${id} not found`
exceptionMessage: 'ERR.NO_ID_REQ', }, null);
stackTrace: 'Request' return res.status(404).send(errorResponse);
}, null);
res.send(response);
return;
}
const response = await this.userAnswersService.remove(id) || {};
const httpResponse = new GenericResponse(null, response)
res.send(httpResponse);
} }
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Post('/filter')
@ApiOperation({ summary: 'Filter user answers based on criteria' })
@ApiBody({ type: UserAnswers, description: 'Filter criteria for user answers' })
@ApiResponse({
status: 400,
description: 'Invalid filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_CRITERIA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'No user answers found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No user answers found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered user answers',
})
async filter(@Body() userAnswers: UserAnswers, @Res() res: Response) {
if (!userAnswers) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_CRITERIA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
const response = await this.userAnswersService.filter(userAnswers) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No user answers found based on the filter criteria'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Post()
@ApiOperation({ summary: 'Insert a new user answer' })
@ApiBody({ type: UserAnswers, description: 'User answer data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid user answer data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'User answer successfully created',
})
async insert(@Body() userAnswers: UserAnswers, @Res() res: Response) {
if (!userAnswers) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete userAnswers.id;
const response = await this.userAnswersService.upsert(userAnswers, true);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Error inserting user answer'
}, null);
return res.status(400).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing user answer' })
@ApiBody({ type: UserAnswers, description: 'User answer data to update' })
@ApiResponse({
status: 400,
description: 'Invalid user answer data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User answer not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User answer not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'User answer successfully updated',
})
async update(@Body() userAnswers: UserAnswers, @Res() res: Response) {
if (!userAnswers || !userAnswers.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
const response = await this.userAnswersService.upsert(userAnswers, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `User answer with ID ${userAnswers.id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Delete(':id')
@ApiOperation({ summary: 'Delete a user answer by ID' })
@ApiParam({ name: 'id', type: Number, description: 'User answer ID to delete' })
@ApiResponse({
status: 400,
description: 'ID parameter is required',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User answer not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User answer not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'User answer successfully deleted',
})
async deleteById(@Param('id') id: number, @Res() res: Response) {
if (!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
const response = await this.userAnswersService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `User answer with ID ${id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
} }

View File

@ -1,46 +1,60 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript'; import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'user_answers' , paranoid : true}) @Table({ tableName: 'user_answers', paranoid: true })
export default class UserAnswers extends Model { export default class UserAnswers extends Model {
@ApiProperty({ type: Number })
@Column(DataType.BIGINT) @Column(DataType.BIGINT)
testId: number; testId: number;
@ApiProperty({ type: Number })
@Column(DataType.BIGINT) @Column(DataType.BIGINT)
userId: number; userId: number;
@ApiProperty({ type: Number })
@Column(DataType.BIGINT) @Column(DataType.BIGINT)
questionId: number; questionId: number;
@ApiProperty({ type: String })
@Column(DataType.TEXT) @Column(DataType.TEXT)
answers: string; answers: string;
@ApiProperty({ type: Date, default: new Date() })
@Default(new Date()) @Default(new Date())
@Column(DataType.DATEONLY) @Column(DataType.DATEONLY)
validFrom: Date; validFrom: Date;
@ApiProperty({ type: Date, default: new Date("2070-12-31") })
@Default(new Date("2070-12-31")) @Default(new Date("2070-12-31"))
@Column(DataType.DATEONLY) @Column(DataType.DATEONLY)
validTill: Date; validTill: Date;
@Column(DataType.DATEONLY) @ApiProperty({ type: String, format: 'date-time' })
@Column(DataType.DATE)
createdAt: Date; createdAt: Date;
@Column(DataType.DATEONLY) @ApiProperty({ type: String, format: 'date-time' })
@Column(DataType.DATE)
updatedAt: Date; updatedAt: Date;
@ApiProperty({ type: String, required: false })
@Column(DataType.TEXT) @Column(DataType.TEXT)
createdBy: string; createdBy: string;
@ApiProperty({ type: String, required: false })
@Column(DataType.TEXT) @Column(DataType.TEXT)
modifiedBy: string; modifiedBy: string;
@ApiProperty({ type: Date, required: false })
@Column(DataType.DATEONLY) @Column(DataType.DATEONLY)
deletedAt: Date; deletedAt: Date;
@Column(DataType.NUMBER) @ApiProperty({ type: Number })
@Column(DataType.INTEGER)
version: number; version: number;
@ApiProperty({ type: String })
@Column(DataType.TEXT) @Column(DataType.TEXT)
status: string; status: string;
} }