init commit

This commit is contained in:
harshithnrao 2025-03-18 23:02:21 +05:30
parent abe3b4744e
commit 831ea0eeef
89 changed files with 10038 additions and 5539 deletions

View File

@ -12,6 +12,7 @@ CREATE TABLE "actions_ref" (
"deletedAt" DATE, "deletedAt" DATE,
"version" NUMERIC "version" NUMERIC
); );
CREATE TABLE "crud_config_info" ( CREATE TABLE "crud_config_info" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"endPtNum" NUMERIC, "endPtNum" NUMERIC,
@ -27,6 +28,7 @@ CREATE TABLE "crud_config_info" (
"createdAt" DATE, "createdAt" DATE,
"updatedAt" DATE "updatedAt" DATE
); );
CREATE TABLE "policies_ref" ( CREATE TABLE "policies_ref" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"appCode" TEXT, "appCode" TEXT,
@ -44,6 +46,7 @@ CREATE TABLE "policies_ref" (
"deletedAt" DATE, "deletedAt" DATE,
"version" NUMERIC "version" NUMERIC
); );
CREATE TABLE "resources_ref" ( CREATE TABLE "resources_ref" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"appCode" TEXT, "appCode" TEXT,
@ -58,6 +61,7 @@ CREATE TABLE "resources_ref" (
"deletedAt" DATE, "deletedAt" DATE,
"version" NUMERIC "version" NUMERIC
); );
CREATE TABLE "rules_ref" ( CREATE TABLE "rules_ref" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"ruleCode" TEXT, "ruleCode" TEXT,
@ -74,6 +78,7 @@ CREATE TABLE "rules_ref" (
"deletedAt" DATE, "deletedAt" DATE,
"version" NUMERIC "version" NUMERIC
); );
CREATE TABLE "rules_details_ref" ( CREATE TABLE "rules_details_ref" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"ruleCode" TEXT, "ruleCode" TEXT,
@ -88,3 +93,292 @@ CREATE TABLE "rules_details_ref" (
"deletedAt" DATE, "deletedAt" DATE,
"version" NUMERIC "version" NUMERIC
); );
CREATE TABLE "users" (
"id" BIGSERIAL PRIMARY KEY NOT NULL,
"email" TEXT UNIQUE NOT NULL,
"password" TEXT,
"userTypeCode" TEXT,
"name" TEXT,
"phoneNumber" TEXT,
"primaryRole" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "user_type" (
"id" BIGSERIAL PRIMARY KEY NOT NULL,
"userTypeCode" TEXT UNIQUE NOT NULL,
"userTypeName" TEXT,
"userTypeDesc" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "user_additional_details" (
"id" BIGSERIAL PRIMARY KEY NOT NULL,
"user_id" NUMERIC NOT NULL,
"addlDataType" TEXT,
"addlDataName" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "theatres" (
"id" BIGSERIAL PRIMARY KEY,
"theatre_name" TEXT,
"rows" NUMERIC,
"columns" NUMERIC,
"address" TEXT,
"city" TEXT,
"images" JSON,
"total_seats" NUMERIC,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "theatre_additional_details" (
"id" BIGSERIAL PRIMARY KEY NOT NULL,
"theatre_id" NUMERIC NOT NULL,
"addlDataType" TEXT,
"addlDataName" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "events" (
"id" BIGSERIAL PRIMARY KEY,
"org_email" TEXT NOT NULL,
"event_name" TEXT,
"start_date" DATE,
"end_date" DATE,
"theatre_id" NUMERIC NOT NULL,
"event_time" TIME,
"chief_guests" TEXT,
"description" TEXT,
"images" JSON,
"categories" TEXT,
"age_restriction" NUMERIC,
"purchase_limit" NUMERIC,
"cast" TEXT,
"max_seating" NUMERIC,
"event_type" TEXT,
"promoted" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "events_additional_details" (
"id" BIGSERIAL PRIMARY KEY NOT NULL,
"events_id" NUMERIC NOT NULL,
"addlDataType" TEXT,
"addlDataName" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "event_categories" (
"id" BIGSERIAL PRIMARY KEY,
"category_name" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "time_slots" (
"id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL,
"start_time" DATE,
"end_time" DATE,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "ticket_pricing" (
"id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL,
"time_slot_id" NUMERIC,
"ticket_type" TEXT,
"price" NUMERIC,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "tickets" (
"id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL,
"ticket_type" TEXT,
"price" NUMERIC,
"seat_number" TEXT,
"qr_code" TEXT,
"buyer_email" TEXT NOT NULL,
"booking_date" DATE,
"payment_status" TEXT,
"rescheduled_at" DATE,
"scanned" DATE,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "reviews" (
"id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL,
"buyer_email" TEXT NOT NULL,
"rating" NUMERIC,
"comment" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "seats" (
"id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL,
"seat_number" TEXT,
"row" TEXT,
"column" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "payouts" (
"id" BIGSERIAL PRIMARY KEY,
"payee_email" TEXT NOT NULL,
"amount" NUMERIC,
"payment_method" TEXT,
"transaction_id" TEXT,
"paid_to_email" TEXT,
"payout_date" DATE,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "refunds" (
"id" BIGSERIAL PRIMARY KEY,
"ticket_id" NUMERIC NOT NULL,
"refund_amount" NUMERIC,
"refund_percentage" NUMERIC NOT NULL,
"refund_reason" TEXT NOT NULL,
"refund_date" DATE,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "push_notification" (
"id" BIGSERIAL PRIMARY KEY,
"endpoint" TEXT NOT NULL,
"p256dh" TEXT,
"auth" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);

8471
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
{ {
"name": "abnandan-skeleton-be", "name": "ticket-booking-be",
"version": "0.0.1", "version": "0.0.1",
"description": "", "description": "",
"author": "", "author": "",
@ -23,33 +23,40 @@
"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/common": "^10.0.0", "@nestjs/common": "^10.0.0",
"@nestjs/config": "^3.1.1", "@nestjs/config": "^3.3.0",
"@nestjs/core": "^10.0.0", "@nestjs/core": "^10.0.0",
"@nestjs/jwt": "^11.0.0",
"@nestjs/passport": "^11.0.5",
"@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",
"moment": "^2.30.1", "moment": "^2.30.1",
"nodemailer": "^6.9.9", "nodemailer": "^6.9.9",
"otp-generator": "^4.0.1", "otp-generator": "^4.0.1",
"pg": "^8.11.3", "passport-jwt": "^4.0.1",
"pg": "^8.14.1",
"reflect-metadata": "^0.1.14", "reflect-metadata": "^0.1.14",
"rxjs": "^7.8.1", "rxjs": "^7.8.1",
"sequelize": "^6.35.2", "sequelize": "^6.35.2",
"sequelize-typescript": "^2.1.6", "sequelize-typescript": "^2.1.6",
"typeorm": "^0.3.17" "typeorm": "^0.3.17",
"web-push": "^3.6.7"
}, },
"devDependencies": { "devDependencies": {
"@nestjs/cli": "^10.0.0", "@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0", "@nestjs/schematics": "^10.2.3",
"@nestjs/testing": "^10.0.0", "@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17", "@types/express": "^4.17.17",
"@types/jest": "^29.5.2", "@types/jest": "^29.5.2",
"@types/multer": "^1.4.11", "@types/multer": "^1.4.11",
"@types/node": "^20.10.6", "@types/node": "^20.10.6",
"@types/nodemailer": "^6.4.14", "@types/nodemailer": "^6.4.14",
"@types/passport": "^1.0.17",
"@types/passport-jwt": "^4.0.1",
"@types/supertest": "^2.0.12", "@types/supertest": "^2.0.12",
"@types/validator": "^13.11.7", "@types/validator": "^13.11.7",
"@typescript-eslint/eslint-plugin": "^6.0.0", "@typescript-eslint/eslint-plugin": "^6.0.0",
@ -63,10 +70,12 @@
"source-map-support": "^0.5.21", "source-map-support": "^0.5.21",
"supertest": "^6.3.3", "supertest": "^6.3.3",
"ts-jest": "^29.1.0", "ts-jest": "^29.1.0",
"ts-loader": "^9.4.3", "ts-loader": "^9.5.2",
"ts-node": "^10.9.2", "ts-node": "^10.9.2",
"tsconfig-paths": "^4.2.0", "tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3" "typescript": "^5.1.3",
"webpack": "^5.98.0",
"webpack-cli": "^6.0.1"
}, },
"jest": { "jest": {
"moduleFileExtensions": [ "moduleFileExtensions": [

View File

@ -41,4 +41,12 @@ export class AppConfigService {
getMailConfig() { getMailConfig() {
return configMaster[this.defaultEnv].mailConfig; return configMaster[this.defaultEnv].mailConfig;
} }
getJwtConfig(){
return configMaster[this.defaultEnv].jwtConfig;
}
getVapidConfig(){
return configMaster[this.defaultEnv].vapidConfig;
}
} }

View File

@ -1,14 +1,14 @@
{ {
"local": { "local": {
"appConfig": { "appConfig": {
"port": 3003 "port": 3000
}, },
"dbConfig": { "dbConfig": {
"host": "localhost", "host": "localhost",
"port": 5432, "port": 5432,
"user": "postgres", "user": "postgres",
"password": "postgres", "password": "postgres",
"database": "remedify-dataservice-local", "database": "ticket_booking_db",
"MODE": "DEV", "MODE": "DEV",
"loggerEnabled": true "loggerEnabled": true
}, },
@ -29,6 +29,32 @@
"defaults": { "defaults": {
"from": "\"No Reply\" <admin@wct.co.in>" "from": "\"No Reply\" <admin@wct.co.in>"
} }
},
"urlConfig": {
"textbookBaseUrl": "http://localhost/content/textbooks/"
},
"swaggerConfig": {
"swagger": {
"title": "ticket-booking application",
"description": "API",
"version": "1.0.0",
"tag": "API"
}
},
"jwtConfig": {
"accessToken": {
"secretOrKey": "8c0f4160ecc3764c2c749f64434ac77863e372319f2b236cb9a6541b30b830f1",
"expiresIn": "15m"
},
"refreshToken": {
"secretOrKey": "40a75dccc55f08f7558f99d97079aa2d2698a61ece0434d435f036f1c8fac21c",
"expiresIn": "7d"
}
},
"vapidConfig": {
"email": "mailto:example@domain.com",
"publicKey": "BPcIQx6jQlD0m2WA5qzXnHtKtsBhvIf_aRf6foXx3ESiw2Tks6b8tVzzX3hHwerGtWy4togFEiJtk5X-Sq36uVQ",
"privateKey": "v-pRrypniFnPn6UOyDNIKatxoHCI6aqsXCM86L7aTfY"
} }
} }
} }

View File

@ -1,14 +1,14 @@
{ {
"local": { "local": {
"appConfig": { "appConfig": {
"port": 3003 "port": 3000
}, },
"dbConfig": { "dbConfig": {
"host": "localhost", "host": "localhost",
"port": 5432, "port": 5432,
"user": "postgres", "user": "postgres",
"password": "postgres", "password": "postgres",
"database": "remedify-dataservice-local", "database": "ticket_booking_db",
"MODE": "DEV", "MODE": "DEV",
"loggerEnabled": true "loggerEnabled": true
}, },
@ -29,6 +29,32 @@
"defaults": { "defaults": {
"from": "\"No Reply\" <admin@wct.co.in>" "from": "\"No Reply\" <admin@wct.co.in>"
} }
},
"urlConfig": {
"textbookBaseUrl": "http://localhost/content/textbooks/"
},
"swaggerConfig": {
"swagger": {
"title": "ticket-booking application",
"description": "API",
"version": "1.0.0",
"tag": "API"
}
},
"jwtConfig": {
"accessToken": {
"secretOrKey": "8c0f4160ecc3764c2c749f64434ac77863e372319f2b236cb9a6541b30b830f1",
"expiresIn": "15m"
},
"refreshToken": {
"secretOrKey": "40a75dccc55f08f7558f99d97079aa2d2698a61ece0434d435f036f1c8fac21c",
"expiresIn": "7d"
}
},
"vapidConfig": {
"email": "mailto:example@domain.com",
"publicKey": "BPcIQx6jQlD0m2WA5qzXnHtKtsBhvIf_aRf6foXx3ESiw2Tks6b8tVzzX3hHwerGtWy4togFEiJtk5X-Sq36uVQ",
"privateKey": "v-pRrypniFnPn6UOyDNIKatxoHCI6aqsXCM86L7aTfY"
} }
} }
} }

View File

@ -4,24 +4,44 @@ import { AppService } from './app.service';
import { CommonService } from './common/common.service'; import { CommonService } from './common/common.service';
import { AppConfigService } from './app-config/app-config.service'; import { AppConfigService } from './app-config/app-config.service';
import { DataModule } from './data/data.module'; import { DataModule } from './data/data.module';
import { MailModule } from './mail/mail.module';
import { AppConfigController } from './app-config/app-config.controller'; import { AppConfigController } from './app-config/app-config.controller';
import { ConfigModule } from './config/config.module';
import { ActionsModule } from './actions/actions.module'; import { ActionsModule } from './actions/actions.module';
import { AuthModule } from './auth/auth.module';
import { PolicyModule } from './policy/policy.module'; import { PolicyModule } from './policy/policy.module';
import { ResourcesModule } from './resources/resources.module'; import { ResourcesModule } from './resources/resources.module';
import { RulesModule } from './rules/rules.module'; import { RulesModule } from './rules/rules.module';
import { RulesDetailModule } from './rules-detail/rules-detail.module'; import { UserModule } from './user/user.module';
import { EventModule } from './event/event.module';
import { PayoutModule } from './payout/payout.module';
import { RefundModule } from './refund/refund.module';
import { ReviewModule } from './review/review.module';
import { SeatModule } from './seat/seat.module';
import { TheatreModule } from './theatre/theatre.module';
import { TicketModule } from './ticket/ticket.module';
import { TicketPricingModule } from './ticketPricing/ticketPricing.module';
import { TimeSlotModule } from './timeSlot/timeSlot.module';
import { PushSubscriptionModule } from './push-subscription/push-subscription.module';
@Module({ @Module({
imports: [ imports: [
DataModule,
MailModule,
ActionsModule, ActionsModule,
AuthModule,
DataModule,
EventModule,
PayoutModule,
PolicyModule, PolicyModule,
RefundModule,
ResourcesModule, ResourcesModule,
ReviewModule,
RulesModule, RulesModule,
RulesDetailModule, SeatModule,
ConfigModule, TheatreModule,
TicketModule,
TicketPricingModule,
TimeSlotModule,
UserModule,
PushSubscriptionModule
], ],
controllers: [AppController, AppConfigController], controllers: [AppController, AppConfigController],
providers: [CommonService, AppConfigService, AppService], providers: [CommonService, AppConfigService, AppService],

View File

@ -41,6 +41,13 @@ export class AppService {
const emailConfig = this.configService.getMailConfig(); const emailConfig = this.configService.getMailConfig();
this.commonService.mailConfig = emailConfig; this.commonService.mailConfig = emailConfig;
Utility.mailConfig = emailConfig; Utility.mailConfig = emailConfig;
const jwtConfig = this.configService.getJwtConfig();
this.commonService.jwtConfig = jwtConfig;
Utility.jwtConfig = jwtConfig;
// const urlConfig = this.configService.getUrlConfig();
// this.commonService.urlConfig = urlConfig;
// Utility.urlConfig = urlConfig;
} }
getModels() { getModels() {

103
src/auth/auth.controller.ts Normal file
View File

@ -0,0 +1,103 @@
import { Body, Controller, Delete, Post, Res } from '@nestjs/common';
import { GenericResponse } from 'src/common/GenericResponse.model';
import { AuthService } from './auth.service';
import { Response } from 'express';
import { ApiOperation, ApiResponse, ApiTags } from '@nestjs/swagger';
@ApiTags('Auth')
@Controller('auth')
export class AuthController {
constructor(private authService: AuthService) { }
@Post('login')
@ApiOperation({ summary: 'Login' })
@ApiResponse({
status: 200,
description: 'User logged in successfully',
})
@ApiResponse({
status: 404,
description: 'User not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User not found"
},
"data": null
}
})
async login(@Body() userDto: { email: string; password: string }, @Res() res: Response) {
const user = await this.authService.validateUser(userDto);
if (!user) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'User not found'
}, null);
res.status(404).send(errorResponse);
}
const tokens = await this.authService.login(user);
const httpResponse = new GenericResponse(null, tokens);
res.status(200).send(httpResponse);
}
@Post('refresh')
async refresh(@Body() body: { refresh_token: string }, @Res() res: Response) {
const newToken = await this.authService.refreshAccessToken(body.refresh_token);
// console.log("new token is",newToken);
if (!newToken) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'Token not found'
}, null)
res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, newToken);
res.status(201).send(httpResponse);
}
@Delete('logout')
delete(@Body() body: { refresh_token: string }, @Res() res: Response) {
const deleteToken = this.authService.logout(body.refresh_token);
res.status(200).send(deleteToken);
}
@Post('verifyAccess')
async verifyAccessToken(@Body() body: { access_token: string }, @Res() res: Response) {
const token = await this.authService.verifyAccessToken(body.access_token);
if (token) {
res.status(200).send(token);
}
else {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'Token not valid'
}, null)
res.status(404).send(errorResponse);
}
}
@Post('verifyRefresh')
async verifyRefreshToken(@Body() body: { refresh_token: string }, @Res() res: Response) {
const token = await this.authService.verifyRefreshToken(body.refresh_token);
if (token) {
res.status(200).send(token);
}
else {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'Token not valid'
}, null)
res.status(404).send(errorResponse);
}
}
}

32
src/auth/auth.module.ts Normal file
View File

@ -0,0 +1,32 @@
import { Module } from '@nestjs/common';
import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { PassportModule } from '@nestjs/passport';
import { JwtModule } from '@nestjs/jwt';
import { UserModule } from 'src/user/user.module';
import { JwtStrategy } from 'src/jwt/jwt.strategy';
import { Utility } from 'src/common/Utility';
import { ConfigModule, ConfigService } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot(),
PassportModule.register({ defaultStrategy: 'jwt' }),
JwtModule.registerAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
secret: Utility.jwtConfig?.accessToken?.secretOrKey,
signOptions: {
expiresIn: Utility.jwtConfig?.accessToken?.expiresIn,
},
}),
inject: [ConfigService],
}),
UserModule,
],
controllers: [AuthController],
providers: [AuthService, JwtStrategy],
exports: [AuthService],
})
export class AuthModule {}

93
src/auth/auth.service.ts Normal file
View File

@ -0,0 +1,93 @@
import { Injectable } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { Utility } from 'src/common/Utility';
import JwtPayload from 'src/jwt/jwt-payload.dto';
import RefreshToken from 'src/jwt/refresh-token.entity';
import { UserService } from 'src/user/user.service';
@Injectable()
export class AuthService {
constructor(private userService: UserService, private jwtService: JwtService) { }
private signToken(payload: any, type: 'accessToken' | 'refreshToken'): string {
console.log("yav type andre", type)
const config = Utility.jwtConfig[type];
console.log("yav expiry andre", config.expiresIn)
return this.jwtService.sign(payload, {
secret: config.secretOrKey,
expiresIn: config.expiresIn,
});
}
private verifyToken(token: string, type: 'accessToken' | 'refreshToken'): any {
const config = Utility.jwtConfig[type];
try {
return this.jwtService.verify(token, {
secret: config.secretOrKey,
});
} catch (error) {
console.log(`${type} token is invalid`, error);
return null;
}
}
async validateUser(payload: JwtPayload) {
return this.userService.findByEmail(payload.email);
}
async login(user: any) {
const payload: JwtPayload = { email: user.email, password: user.password };
console.log("illig bandu nilthu", payload)
const accessToken = this.signToken(payload, 'accessToken');
console.log("illig bandu nilthu", accessToken)
const refreshToken = this.signToken(payload, 'refreshToken');
await RefreshToken.create({ email: user.email, token: refreshToken });
return {
access_token: accessToken,
refresh_token: refreshToken,
};
}
async refreshAccessToken(refreshToken: string) {
const payload = this.verifyToken(refreshToken, 'refreshToken');
if (!payload) {
throw new Error('Invalid refresh token');
}
console.log(refreshToken);
console.log(payload);
const user = await this.userService.findByEmail(payload.email);
if (!user) {
throw new Error('User not found');
}
console.log(user)
const accessToken = this.signToken({
email: payload.email
}, 'accessToken');
console.log(accessToken)
return { access_token: accessToken };
}
async verifyRefreshToken(refreshToken: string) {
const payload = this.verifyToken(refreshToken, 'refreshToken');
if (payload) {
console.log("Refresh token is valid", payload);
}
return payload;
}
async verifyAccessToken(accessToken: string) {
const payload = this.verifyToken(accessToken, 'accessToken');
if (payload) {
console.log("Access token is valid", payload);
}
return payload;
}
async logout(refreshToken: string) {
return RefreshToken.destroy({ where: { token: refreshToken } });
}
}

View File

@ -4,6 +4,8 @@ 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 jwtConfig: any;
static fileConfig: any = {"storagePath": "./uploads"}; static fileConfig: any = {"storagePath": "./uploads"};
static mailConfig: any = { static mailConfig: any = {
"transport": { "transport": {
@ -19,4 +21,6 @@ export class Utility {
"from": "\"No Reply\" <admin@wct.co.in>" "from": "\"No Reply\" <admin@wct.co.in>"
} }
}; };
static urlConfig:any;
static vapidConfig: any;
} }

View File

@ -7,6 +7,9 @@ export class CommonService {
models: any; models: any;
fileConfig: any; fileConfig: any;
mailConfig: any; mailConfig: any;
urlConfig:any;
jwtConfig:any;
vapidConfig:any;
constructor() { constructor() {
} }

View File

@ -4,7 +4,7 @@ import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
export default class DataModel extends Model { export default class DataModel extends Model {
@Column({type: DataType.NUMBER}) @Column({type: DataType.NUMBER})
endPtNm: string; endPtNum: string;
@Column({type: DataType.TEXT}) @Column({type: DataType.TEXT})
sqlQueryText: string; sqlQueryText: string;
@ -21,7 +21,7 @@ export default class DataModel extends Model {
validTill: Date; validTill: Date;
@Column({type: DataType.TEXT}) @Column({type: DataType.TEXT})
createBy: string; createdBy: string;
@Column({type: DataType.TEXT}) @Column({type: DataType.TEXT})
modifiedBy: string; modifiedBy: string;

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { EventService } from './event.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Event from './event.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('event')
@Controller('event')
export class EventController {
constructor(private eventService: EventService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all events' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all events',
})
@ApiResponse({
status: 404,
description: 'No events found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No events found"
},
"data": null
}
})
async getAllEvents(@Res() res: Response) {
const response = await this.eventService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No events found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get event by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Event 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: 'Event not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Event not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved event by ID',
})
async findById(@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.eventService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Event 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')
@ApiOperation({ summary: 'Filter events based on criteria' })
@ApiBody({ type: Event, description: 'Filter criteria for events' })
@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 events found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No events found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered events',
})
async filter(@Body() event: Event, @Res() res: Response) {
if (!event) {
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.eventService.filter(event) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No events 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 event' })
@ApiBody({ type: Event, description: 'Event data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid event data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a event',
})
async insert(@Body() event: Event, @Res() res: Response) {
if (!event) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete event.id;
const response = await this.eventService.upsert(event, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing event' })
@ApiBody({ type: Event, description: 'Event data to update' })
@ApiResponse({
status: 400,
description: 'Invalid event data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Event not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Event not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated event',
})
async update(@Body() event: Event, @Res() res: Response) {
if (!event || !event.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.eventService.upsert(event, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Event with ID ${event.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 event by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Event 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: 'Event not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Event not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted event',
})
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.eventService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Event with ID ${id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
}

106
src/event/event.entity.ts Normal file
View File

@ -0,0 +1,106 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'events', paranoid: true })
export default class Event extends Model {
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'org_email' })
orgEmail: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'event_name' })
eventName: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'start_date' })
startDate: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'end_date' })
endDate: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'theatre_id' })
theatreId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TIME, field: 'event_time' })
eventTime: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'chief_guests' })
chiefGuests: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'description' })
description: string;
@ApiProperty({ type: Object })
@Column({ type: DataType.JSON, field: 'images' })
images: object;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'categories' })
categories: string;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'age_restriction' })
ageRestriction: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'purchase_limit' })
purchaseLimit: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'cast' })
cast: string;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'max_seating' })
maxSeating: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'event_type' })
eventType: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'promoted' })
promoted: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

14
src/event/event.module.ts Normal file
View File

@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { EventController } from './event.controller';
import { EventService } from './event.service';
import { HttpModule } from '@nestjs/axios';
import { EventAdditionalDetailService } from './eventAdditionalDetail/eventAdditionalDetail.service';
import { EventAdditionalDetailController } from './eventAdditionalDetail/eventAdditionalDetail.controller';
@Module({
controllers: [EventController,EventAdditionalDetailController],
providers: [EventService,EventAdditionalDetailService],
exports: [EventService,EventAdditionalDetailService],
imports: [HttpModule],
})
export class EventModule { }

View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import Event from './event.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class EventService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: Event[], count: number }> {
return Event.findAndCountAll();
}
async findByPk(id: number): Promise<Event> {
const event = Event.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await event).textbookId);
return event
}
findOne(event: Event): Promise<Event> {
return Event.findOne({ where: event as any, })
}
filter(event: Event): Promise<Event[]> {
return Event.findAll({ where: event as any, })
}
async remove(id: number): Promise<number> {
return Event.destroy({ where: { id: id } });
}
async upsert(event: Event, insertIfNotFound: boolean): Promise<Event | [affectedCount: number]> {
if (event.id) {
const existingEvent = await this.findByPk(event.id);
if (existingEvent) {
return Event.update(event, { where: { id: event.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(event.textbookId);
return Event.create(event as any)
}
}
}

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { EventAdditionalDetailService } from './eventAdditionalDetail.service';
import { Response } from 'express';
import { GenericResponse } from '../../common/GenericResponse.model';
import EventAdditionalDetail from './eventAdditionalDetail.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('event/addl')
@Controller('event/addl/')
export class EventAdditionalDetailController {
constructor(private eventAdditionalDetailService: EventAdditionalDetailService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all eventAdditionalDetails' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all eventAdditionalDetails',
})
@ApiResponse({
status: 404,
description: 'No eventAdditionalDetails found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No eventAdditionalDetails found"
},
"data": null
}
})
async getAllEventAdditionalDetails(@Res() res: Response) {
const response = await this.eventAdditionalDetailService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No eventAdditionalDetails found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get eventAdditionalDetail by ID' })
@ApiParam({ name: 'id', type: Number, description: 'EventAdditionalDetail 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: 'EventAdditionalDetail not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "EventAdditionalDetail not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved eventAdditionalDetail by ID',
})
async findById(@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.eventAdditionalDetailService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `EventAdditionalDetail 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')
@ApiOperation({ summary: 'Filter eventAdditionalDetails based on criteria' })
@ApiBody({ type: EventAdditionalDetail, description: 'Filter criteria for eventAdditionalDetails' })
@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 eventAdditionalDetails found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No eventAdditionalDetails found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered eventAdditionalDetails',
})
async filter(@Body() eventAdditionalDetail: EventAdditionalDetail, @Res() res: Response) {
if (!eventAdditionalDetail) {
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.eventAdditionalDetailService.filter(eventAdditionalDetail) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No eventAdditionalDetails 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 eventAdditionalDetail' })
@ApiBody({ type: EventAdditionalDetail, description: 'EventAdditionalDetail data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid eventAdditionalDetail data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a eventAdditionalDetail',
})
async insert(@Body() eventAdditionalDetail: EventAdditionalDetail, @Res() res: Response) {
if (!eventAdditionalDetail) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete eventAdditionalDetail.id;
const response = await this.eventAdditionalDetailService.upsert(eventAdditionalDetail, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing eventAdditionalDetail' })
@ApiBody({ type: EventAdditionalDetail, description: 'EventAdditionalDetail data to update' })
@ApiResponse({
status: 400,
description: 'Invalid eventAdditionalDetail data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'EventAdditionalDetail not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "EventAdditionalDetail not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated eventAdditionalDetail',
})
async update(@Body() eventAdditionalDetail: EventAdditionalDetail, @Res() res: Response) {
if (!eventAdditionalDetail || !eventAdditionalDetail.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.eventAdditionalDetailService.upsert(eventAdditionalDetail, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `EventAdditionalDetail with ID ${eventAdditionalDetail.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 eventAdditionalDetail by ID' })
@ApiParam({ name: 'id', type: Number, description: 'EventAdditionalDetail 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: 'EventAdditionalDetail not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "EventAdditionalDetail not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted eventAdditionalDetail',
})
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.eventAdditionalDetailService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `EventAdditionalDetail 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

@ -0,0 +1,54 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'events_additional_details', paranoid: true })
export default class EventAdditionalDetail extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'events_id' })
eventsId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'addlDataType' })
addlDataType: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'addlDataName' })
addlDataName: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import EventAdditionalDetail from './eventAdditionalDetail.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class EventAdditionalDetailService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: EventAdditionalDetail[], count: number }> {
return EventAdditionalDetail.findAndCountAll();
}
async findByPk(id: number): Promise<EventAdditionalDetail> {
const eventAdditionalDetail = EventAdditionalDetail.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await eventAdditionalDetail).textbookId);
return eventAdditionalDetail
}
findOne(eventAdditionalDetail: EventAdditionalDetail): Promise<EventAdditionalDetail> {
return EventAdditionalDetail.findOne({ where: eventAdditionalDetail as any, })
}
filter(eventAdditionalDetail: EventAdditionalDetail): Promise<EventAdditionalDetail[]> {
return EventAdditionalDetail.findAll({ where: eventAdditionalDetail as any, })
}
async remove(id: number): Promise<number> {
return EventAdditionalDetail.destroy({ where: { id: id } });
}
async upsert(eventAdditionalDetail: EventAdditionalDetail, insertIfNotFound: boolean): Promise<EventAdditionalDetail | [affectedCount: number]> {
if (eventAdditionalDetail.id) {
const existingEventAdditionalDetail = await this.findByPk(eventAdditionalDetail.id);
if (existingEventAdditionalDetail) {
return EventAdditionalDetail.update(eventAdditionalDetail, { where: { id: eventAdditionalDetail.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(eventAdditionalDetail.textbookId);
return EventAdditionalDetail.create(eventAdditionalDetail as any)
}
}
}

View File

@ -0,0 +1,5 @@
import { Injectable } from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
@Injectable()
export class JwtAuthGuard extends AuthGuard('jwt') {}

View File

@ -0,0 +1,10 @@
import { ApiProperty } from '@nestjs/swagger';
export default class JwtPayload {
@ApiProperty({ type: String, description: 'User email' })
email: string;
@ApiProperty({ type: String, description: 'User password' })
password: string;
}

20
src/jwt/jwt.strategy.ts Normal file
View File

@ -0,0 +1,20 @@
import { Injectable } from '@nestjs/common';
import { PassportStrategy } from '@nestjs/passport';
import { Strategy, ExtractJwt } from 'passport-jwt';
import { AuthService } from 'src/auth/auth.service';
import JwtPayload from './jwt-payload.dto';
import { Utility } from 'src/common/Utility';
@Injectable()
export class JwtStrategy extends PassportStrategy(Strategy) {
constructor(private authService: AuthService) {
super({
jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(),
secretOrKey: Utility.jwtConfig.accessToken.secretOrKey,
});
}
async validate(payload: JwtPayload) {
return this.authService.validateUser(payload);
}
}

View File

@ -0,0 +1,14 @@
import { Table, Column, Model, DataType, Unique } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'refresh_tokens', paranoid: true })
export default class RefreshToken extends Model {
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
email: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
token: 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 mailerService: 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,28 @@ 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;
Utility.vapidConfig = configMaster.local.vapidConfig;
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

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { PayoutService } from './payout.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Payout from './payout.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('payout')
@Controller('payout')
export class PayoutController {
constructor(private payoutService: PayoutService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all payouts' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all payouts',
})
@ApiResponse({
status: 404,
description: 'No payouts found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No payouts found"
},
"data": null
}
})
async getAllPayouts(@Res() res: Response) {
const response = await this.payoutService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No payouts found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get payout by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Payout 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: 'Payout not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Payout not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved payout by ID',
})
async findById(@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.payoutService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Payout 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')
@ApiOperation({ summary: 'Filter payouts based on criteria' })
@ApiBody({ type: Payout, description: 'Filter criteria for payouts' })
@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 payouts found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No payouts found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered payouts',
})
async filter(@Body() payout: Payout, @Res() res: Response) {
if (!payout) {
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.payoutService.filter(payout) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No payouts 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 payout' })
@ApiBody({ type: Payout, description: 'Payout data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid payout data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a payout',
})
async insert(@Body() payout: Payout, @Res() res: Response) {
if (!payout) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete payout.id;
const response = await this.payoutService.upsert(payout, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing payout' })
@ApiBody({ type: Payout, description: 'Payout data to update' })
@ApiResponse({
status: 400,
description: 'Invalid payout data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Payout not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Payout not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated payout',
})
async update(@Body() payout: Payout, @Res() res: Response) {
if (!payout || !payout.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.payoutService.upsert(payout, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Payout with ID ${payout.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 payout by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Payout 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: 'Payout not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Payout not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted payout',
})
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.payoutService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Payout 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

@ -0,0 +1,66 @@
import { Table, Column, Model, Default, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'payouts', paranoid: true })
export default class Payout extends Model {
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'payee_email' })
payeeEmail: string;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'amount' })
amount: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'payment_method' })
paymentMethod: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'transaction_id' })
transactionId: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'paid_to_email' })
paidToEmail: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'payout_date' })
payoutDate: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { PayoutController } from './payout.controller';
import { PayoutService } from './payout.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [PayoutService],
controllers: [PayoutController],
})
export class PayoutModule { }

View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import Payout from './payout.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class PayoutService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: Payout[], count: number }> {
return Payout.findAndCountAll();
}
async findByPk(id: number): Promise<Payout> {
const payout = Payout.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await payout).textbookId);
return payout
}
findOne(payout: Payout): Promise<Payout> {
return Payout.findOne({ where: payout as any, })
}
filter(payout: Payout): Promise<Payout[]> {
return Payout.findAll({ where: payout as any, })
}
async remove(id: number): Promise<number> {
return Payout.destroy({ where: { id: id } });
}
async upsert(payout: Payout, insertIfNotFound: boolean): Promise<Payout | [affectedCount: number]> {
if (payout.id) {
const existingPayout = await this.findByPk(payout.id);
if (existingPayout) {
return Payout.update(payout, { where: { id: payout.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(payout.textbookId);
return Payout.create(payout as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { PushSubscriptionController } from './push-subscription.controller';
describe('PushSubscriptionController', () => {
let controller: PushSubscriptionController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [PushSubscriptionController],
}).compile();
controller = module.get<PushSubscriptionController>(PushSubscriptionController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,21 @@
import { Body, Controller, Post } from '@nestjs/common';
import { PushSubscriptionService } from './push-subscription.service';
@Controller('push')
export class PushSubscriptionController {
constructor(private readonly pushSubscriptionService: PushSubscriptionService) { }
@Post('subscribe')
async subscribe(@Body() body: any) {
console.log(body);
await this.pushSubscriptionService.saveSubscription(body);
return 'subscribed';
}
@Post('send-notification')
async sendNotification(@Body() body: any) {
await this.pushSubscriptionService.sendPushNotification(body.title, body.message);
return 'notification sent';
}
}

View File

@ -0,0 +1,54 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'push_notification', paranoid: true })
export default class PushSubscription extends Model {
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'endpoint' })
endpoint: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'p256dh' })
p256dh: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'auth' })
auth: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,14 @@
import { Module } from '@nestjs/common';
import { PushSubscriptionController } from './push-subscription.controller';
import { PushSubscriptionService } from './push-subscription.service';
import { HttpModule } from '@nestjs/axios';
@Module({
controllers: [PushSubscriptionController],
imports: [HttpModule],
providers: [PushSubscriptionService],
exports: [PushSubscriptionService]
})
export class PushSubscriptionModule {
}

View File

@ -0,0 +1,43 @@
import * as webPush from 'web-push';
import { Injectable } from '@nestjs/common';
import PushSubscription from './push-subscription.entity';
import { Utility } from 'src/common/Utility';
@Injectable()
export class PushSubscriptionService {
constructor() {
webPush.setVapidDetails(
Utility.vapidConfig.email,
Utility.vapidConfig.publicKey,
Utility.vapidConfig.privateKey,
);
}
async saveSubscription(subscription: any) {
const { endpoint, p256dh, auth } = subscription;
await PushSubscription.create({ endpoint, p256dh, auth });
return 'saved subscription';
}
async sendPushNotification(title: any, message: any) {
const subs = await PushSubscription.findAll();
var pushSub: any;
for (const sub of subs) {
pushSub = {
endpoint: sub.endpoint,
keys: {
p256dh: sub.p256dh,
auth: sub.auth,
},
};
}
const payload = JSON.stringify({ title, message })
try {
await webPush.sendPushNotification(pushSub, payload)
} catch (err) {
console.log("error occurred", err)
}
}
}

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { RefundService } from './refund.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Refund from './refund.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('refund')
@Controller('refund')
export class RefundController {
constructor(private refundService: RefundService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all refunds' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all refunds',
})
@ApiResponse({
status: 404,
description: 'No refunds found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No refunds found"
},
"data": null
}
})
async getAllRefunds(@Res() res: Response) {
const response = await this.refundService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No refunds found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get refund by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Refund 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: 'Refund not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Refund not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved refund by ID',
})
async findById(@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.refundService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Refund 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')
@ApiOperation({ summary: 'Filter refunds based on criteria' })
@ApiBody({ type: Refund, description: 'Filter criteria for refunds' })
@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 refunds found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No refunds found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered refunds',
})
async filter(@Body() refund: Refund, @Res() res: Response) {
if (!refund) {
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.refundService.filter(refund) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No refunds 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 refund' })
@ApiBody({ type: Refund, description: 'Refund data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid refund data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a refund',
})
async insert(@Body() refund: Refund, @Res() res: Response) {
if (!refund) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete refund.id;
const response = await this.refundService.upsert(refund, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing refund' })
@ApiBody({ type: Refund, description: 'Refund data to update' })
@ApiResponse({
status: 400,
description: 'Invalid refund data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Refund not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Refund not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated refund',
})
async update(@Body() refund: Refund, @Res() res: Response) {
if (!refund || !refund.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.refundService.upsert(refund, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Refund with ID ${refund.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 refund by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Refund 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: 'Refund not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Refund not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted refund',
})
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.refundService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Refund 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

@ -0,0 +1,62 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'refunds', paranoid: true })
export default class Refund extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'ticket_id' })
ticketId: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'refund_amount' })
refundAmount: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'refund_percentage' })
refundPercentage: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'refund_reason' })
refundReason: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'refund_date' })
refundDate: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { RefundController } from './refund.controller';
import { RefundService } from './refund.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [RefundService],
controllers: [RefundController],
})
export class RefundModule { }

View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import Refund from './refund.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class RefundService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: Refund[], count: number }> {
return Refund.findAndCountAll();
}
async findByPk(id: number): Promise<Refund> {
const refund = Refund.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await refund).textbookId);
return refund
}
findOne(refund: Refund): Promise<Refund> {
return Refund.findOne({ where: refund as any, })
}
filter(refund: Refund): Promise<Refund[]> {
return Refund.findAll({ where: refund as any, })
}
async remove(id: number): Promise<number> {
return Refund.destroy({ where: { id: id } });
}
async upsert(refund: Refund, insertIfNotFound: boolean): Promise<Refund | [affectedCount: number]> {
if (refund.id) {
const existingRefund = await this.findByPk(refund.id);
if (existingRefund) {
return Refund.update(refund, { where: { id: refund.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(refund.textbookId);
return Refund.create(refund as any)
}
}
}

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { ReviewService } from './review.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Review from './review.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('review')
@Controller('review')
export class ReviewController {
constructor(private reviewService: ReviewService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all reviews' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all reviews',
})
@ApiResponse({
status: 404,
description: 'No reviews found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No reviews found"
},
"data": null
}
})
async getAllReviews(@Res() res: Response) {
const response = await this.reviewService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No reviews found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get review by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Review 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: 'Review not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Review not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved review by ID',
})
async findById(@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.reviewService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Review 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')
@ApiOperation({ summary: 'Filter reviews based on criteria' })
@ApiBody({ type: Review, description: 'Filter criteria for reviews' })
@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 reviews found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No reviews found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered reviews',
})
async filter(@Body() review: Review, @Res() res: Response) {
if (!review) {
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.reviewService.filter(review) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No reviews 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 review' })
@ApiBody({ type: Review, description: 'Review data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid review data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a review',
})
async insert(@Body() review: Review, @Res() res: Response) {
if (!review) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete review.id;
const response = await this.reviewService.upsert(review, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing review' })
@ApiBody({ type: Review, description: 'Review data to update' })
@ApiResponse({
status: 400,
description: 'Invalid review data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Review not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Review not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated review',
})
async update(@Body() review: Review, @Res() res: Response) {
if (!review || !review.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.reviewService.upsert(review, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Review with ID ${review.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 review by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Review 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: 'Review not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Review not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted review',
})
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.reviewService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Review 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

@ -0,0 +1,58 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'reviews', paranoid: true })
export default class Review extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'event_id' })
eventId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'buyer_email' })
buyerEmail: string;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'rating' })
rating: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'comment' })
comment: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { ReviewController } from './review.controller';
import { ReviewService } from './review.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [ReviewService],
controllers: [ReviewController],
})
export class ReviewModule { }

View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import Review from './review.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class ReviewService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: Review[], count: number }> {
return Review.findAndCountAll();
}
async findByPk(id: number): Promise<Review> {
const review = Review.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await review).textbookId);
return review
}
findOne(review: Review): Promise<Review> {
return Review.findOne({ where: review as any, })
}
filter(review: Review): Promise<Review[]> {
return Review.findAll({ where: review as any, })
}
async remove(id: number): Promise<number> {
return Review.destroy({ where: { id: id } });
}
async upsert(review: Review, insertIfNotFound: boolean): Promise<Review | [affectedCount: number]> {
if (review.id) {
const existingReview = await this.findByPk(review.id);
if (existingReview) {
return Review.update(review, { where: { id: review.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(review.textbookId);
return Review.create(review as any)
}
}
}

View File

@ -1,7 +1,7 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common'; import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { RulesDetailService } from './rules-detail.service'; import { RulesDetailService } from './rules-detail.service';
import { Response } from 'express'; import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model'; import { GenericResponse } from '../../common/GenericResponse.model';
import RulesDetail from './rules-detail.entity'; import RulesDetail from './rules-detail.entity';
@Controller('rulesDetail') @Controller('rulesDetail')

View File

@ -1,10 +1,13 @@
import { Module } from '@nestjs/common'; import { Module } from '@nestjs/common';
import { RulesController } from './rules.controller'; import { RulesController } from './rules.controller';
import { RulesService } from './rules.service'; import { RulesService } from './rules.service';
import { RulesDetailController } from './rules-detail/rules-detail.controller';
import { RulesDetailService } from './rules-detail/rules-detail.service';
@Module({ @Module({
providers: [RulesService], controllers: [RulesController,RulesDetailController],
controllers: [RulesController], providers: [RulesService,RulesDetailService],
exports:[RulesService,RulesDetailService],
imports: [] imports: []
}) })
export class RulesModule { } export class RulesModule { }

310
src/seat/seat.controller.ts Normal file
View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { SeatService } from './seat.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Seat from './seat.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('seat')
@Controller('seat')
export class SeatController {
constructor(private seatService: SeatService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all seats' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all seats',
})
@ApiResponse({
status: 404,
description: 'No seats found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No seats found"
},
"data": null
}
})
async getAllSeats(@Res() res: Response) {
const response = await this.seatService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No seats found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get seat by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Seat 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: 'Seat not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Seat not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved seat by ID',
})
async findById(@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.seatService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Seat 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')
@ApiOperation({ summary: 'Filter seats based on criteria' })
@ApiBody({ type: Seat, description: 'Filter criteria for seats' })
@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 seats found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No seats found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered seats',
})
async filter(@Body() seat: Seat, @Res() res: Response) {
if (!seat) {
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.seatService.filter(seat) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No seats 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 seat' })
@ApiBody({ type: Seat, description: 'Seat data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid seat data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a seat',
})
async insert(@Body() seat: Seat, @Res() res: Response) {
if (!seat) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete seat.id;
const response = await this.seatService.upsert(seat, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing seat' })
@ApiBody({ type: Seat, description: 'Seat data to update' })
@ApiResponse({
status: 400,
description: 'Invalid seat data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Seat not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Seat not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated seat',
})
async update(@Body() seat: Seat, @Res() res: Response) {
if (!seat || !seat.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.seatService.upsert(seat, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Seat with ID ${seat.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 seat by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Seat 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: 'Seat not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Seat not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted seat',
})
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.seatService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Seat with ID ${id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
}

58
src/seat/seat.entity.ts Normal file
View File

@ -0,0 +1,58 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'seats', paranoid: true })
export default class Seat extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'event_id' })
eventId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'seat_number' })
seatNumber: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'row' })
row: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'column' })
column: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

11
src/seat/seat.module.ts Normal file
View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { SeatController } from './seat.controller';
import { SeatService } from './seat.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [SeatService],
controllers: [SeatController],
})
export class SeatModule { }

49
src/seat/seat.service.ts Normal file
View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import Seat from './seat.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class SeatService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: Seat[], count: number }> {
return Seat.findAndCountAll();
}
async findByPk(id: number): Promise<Seat> {
const seat = Seat.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await seat).textbookId);
return seat
}
findOne(seat: Seat): Promise<Seat> {
return Seat.findOne({ where: seat as any, })
}
filter(seat: Seat): Promise<Seat[]> {
return Seat.findAll({ where: seat as any, })
}
async remove(id: number): Promise<number> {
return Seat.destroy({ where: { id: id } });
}
async upsert(seat: Seat, insertIfNotFound: boolean): Promise<Seat | [affectedCount: number]> {
if (seat.id) {
const existingSeat = await this.findByPk(seat.id);
if (existingSeat) {
return Seat.update(seat, { where: { id: seat.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(seat.textbookId);
return Seat.create(seat as any)
}
}
}

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { TheatreService } from './theatre.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Theatre from './theatre.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('theatre')
@Controller('theatre')
export class TheatreController {
constructor(private theatreService: TheatreService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all theatres' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all theatres',
})
@ApiResponse({
status: 404,
description: 'No theatres found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No theatres found"
},
"data": null
}
})
async getAllTheatres(@Res() res: Response) {
const response = await this.theatreService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No theatres found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get theatre by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Theatre 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: 'Theatre not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Theatre not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved theatre by ID',
})
async findById(@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.theatreService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Theatre 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')
@ApiOperation({ summary: 'Filter theatres based on criteria' })
@ApiBody({ type: Theatre, description: 'Filter criteria for theatres' })
@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 theatres found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No theatres found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered theatres',
})
async filter(@Body() theatre: Theatre, @Res() res: Response) {
if (!theatre) {
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.theatreService.filter(theatre) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No theatres 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 theatre' })
@ApiBody({ type: Theatre, description: 'Theatre data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid theatre data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a theatre',
})
async insert(@Body() theatre: Theatre, @Res() res: Response) {
if (!theatre) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete theatre.id;
const response = await this.theatreService.upsert(theatre, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing theatre' })
@ApiBody({ type: Theatre, description: 'Theatre data to update' })
@ApiResponse({
status: 400,
description: 'Invalid theatre data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Theatre not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Theatre not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated theatre',
})
async update(@Body() theatre: Theatre, @Res() res: Response) {
if (!theatre || !theatre.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.theatreService.upsert(theatre, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Theatre with ID ${theatre.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 theatre by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Theatre 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: 'Theatre not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Theatre not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted theatre',
})
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.theatreService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Theatre 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

@ -0,0 +1,70 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'theatres', paranoid: true })
export default class Theatre extends Model {
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'theatre_name' })
theatreName: string;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'rows' })
rows: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'columns' })
columns: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'address' })
address: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'city' })
city: string;
@ApiProperty({ type: Object })
@Column({ type: DataType.JSON, field: 'images' })
images: object;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'total_seats' })
totalSeats: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,13 @@
import { Module } from '@nestjs/common';
import { TheatreController } from './theatre.controller';
import { TheatreService } from './theatre.service';
import { HttpModule } from '@nestjs/axios';
import { TheatreAdditionalDetailsService } from './theatreAdditionalDetails/theatreAdditionalDetails.service';
import { TheatreAdditionalDetailsController } from './theatreAdditionalDetails/theatreAdditionalDetails.controller';
@Module({
imports: [HttpModule],
providers: [TheatreService,TheatreAdditionalDetailsService],
controllers: [TheatreController,TheatreAdditionalDetailsController],
})
export class TheatreModule { }

View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import Theatre from './theatre.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class TheatreService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: Theatre[], count: number }> {
return Theatre.findAndCountAll();
}
async findByPk(id: number): Promise<Theatre> {
const theatre = Theatre.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await theatre).textbookId);
return theatre
}
findOne(theatre: Theatre): Promise<Theatre> {
return Theatre.findOne({ where: theatre as any, })
}
filter(theatre: Theatre): Promise<Theatre[]> {
return Theatre.findAll({ where: theatre as any, })
}
async remove(id: number): Promise<number> {
return Theatre.destroy({ where: { id: id } });
}
async upsert(theatre: Theatre, insertIfNotFound: boolean): Promise<Theatre | [affectedCount: number]> {
if (theatre.id) {
const existingTheatre = await this.findByPk(theatre.id);
if (existingTheatre) {
return Theatre.update(theatre, { where: { id: theatre.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(theatre.textbookId);
return Theatre.create(theatre as any)
}
}
}

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { TheatreAdditionalDetailsService } from './theatreAdditionalDetails.service';
import { Response } from 'express';
import { GenericResponse } from '../../common/GenericResponse.model';
import TheatreAdditionalDetails from './theatreAdditionalDetails.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('theatreAdditionalDetails')
@Controller('theatreAdditionalDetails')
export class TheatreAdditionalDetailsController {
constructor(private theatreAdditionalDetailsService: TheatreAdditionalDetailsService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all theatreAdditionalDetailss' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all theatreAdditionalDetailss',
})
@ApiResponse({
status: 404,
description: 'No theatreAdditionalDetailss found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No theatreAdditionalDetailss found"
},
"data": null
}
})
async getAllTheatreAdditionalDetailss(@Res() res: Response) {
const response = await this.theatreAdditionalDetailsService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No theatreAdditionalDetailss found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get theatreAdditionalDetails by ID' })
@ApiParam({ name: 'id', type: Number, description: 'TheatreAdditionalDetails 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: 'TheatreAdditionalDetails not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "TheatreAdditionalDetails not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved theatreAdditionalDetails by ID',
})
async findById(@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.theatreAdditionalDetailsService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `TheatreAdditionalDetails 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')
@ApiOperation({ summary: 'Filter theatreAdditionalDetailss based on criteria' })
@ApiBody({ type: TheatreAdditionalDetails, description: 'Filter criteria for theatreAdditionalDetailss' })
@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 theatreAdditionalDetailss found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No theatreAdditionalDetailss found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered theatreAdditionalDetailss',
})
async filter(@Body() theatreAdditionalDetails: TheatreAdditionalDetails, @Res() res: Response) {
if (!theatreAdditionalDetails) {
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.theatreAdditionalDetailsService.filter(theatreAdditionalDetails) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No theatreAdditionalDetailss 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 theatreAdditionalDetails' })
@ApiBody({ type: TheatreAdditionalDetails, description: 'TheatreAdditionalDetails data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid theatreAdditionalDetails data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a theatreAdditionalDetails',
})
async insert(@Body() theatreAdditionalDetails: TheatreAdditionalDetails, @Res() res: Response) {
if (!theatreAdditionalDetails) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete theatreAdditionalDetails.id;
const response = await this.theatreAdditionalDetailsService.upsert(theatreAdditionalDetails, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing theatreAdditionalDetails' })
@ApiBody({ type: TheatreAdditionalDetails, description: 'TheatreAdditionalDetails data to update' })
@ApiResponse({
status: 400,
description: 'Invalid theatreAdditionalDetails data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'TheatreAdditionalDetails not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "TheatreAdditionalDetails not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated theatreAdditionalDetails',
})
async update(@Body() theatreAdditionalDetails: TheatreAdditionalDetails, @Res() res: Response) {
if (!theatreAdditionalDetails || !theatreAdditionalDetails.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.theatreAdditionalDetailsService.upsert(theatreAdditionalDetails, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `TheatreAdditionalDetails with ID ${theatreAdditionalDetails.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 theatreAdditionalDetails by ID' })
@ApiParam({ name: 'id', type: Number, description: 'TheatreAdditionalDetails 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: 'TheatreAdditionalDetails not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "TheatreAdditionalDetails not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted theatreAdditionalDetails',
})
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.theatreAdditionalDetailsService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `TheatreAdditionalDetails 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

@ -0,0 +1,54 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'theatre_additional_details', paranoid: true })
export default class TheatreAdditionalDetails extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'theatre_id' })
theatreId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'addlDataType' })
addlDataType: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'addlDataName' })
addlDataName: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import TheatreAdditionalDetails from './theatreAdditionalDetails.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class TheatreAdditionalDetailsService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: TheatreAdditionalDetails[], count: number }> {
return TheatreAdditionalDetails.findAndCountAll();
}
async findByPk(id: number): Promise<TheatreAdditionalDetails> {
const theatreAdditionalDetails = TheatreAdditionalDetails.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await theatreAdditionalDetails).textbookId);
return theatreAdditionalDetails
}
findOne(theatreAdditionalDetails: TheatreAdditionalDetails): Promise<TheatreAdditionalDetails> {
return TheatreAdditionalDetails.findOne({ where: theatreAdditionalDetails as any, })
}
filter(theatreAdditionalDetails: TheatreAdditionalDetails): Promise<TheatreAdditionalDetails[]> {
return TheatreAdditionalDetails.findAll({ where: theatreAdditionalDetails as any, })
}
async remove(id: number): Promise<number> {
return TheatreAdditionalDetails.destroy({ where: { id: id } });
}
async upsert(theatreAdditionalDetails: TheatreAdditionalDetails, insertIfNotFound: boolean): Promise<TheatreAdditionalDetails | [affectedCount: number]> {
if (theatreAdditionalDetails.id) {
const existingTheatreAdditionalDetails = await this.findByPk(theatreAdditionalDetails.id);
if (existingTheatreAdditionalDetails) {
return TheatreAdditionalDetails.update(theatreAdditionalDetails, { where: { id: theatreAdditionalDetails.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(theatreAdditionalDetails.textbookId);
return TheatreAdditionalDetails.create(theatreAdditionalDetails as any)
}
}
}

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { TicketService } from './ticket.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Ticket from './ticket.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('ticket')
@Controller('ticket')
export class TicketController {
constructor(private ticketService: TicketService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all tickets' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all tickets',
})
@ApiResponse({
status: 404,
description: 'No tickets found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No tickets found"
},
"data": null
}
})
async getAllTickets(@Res() res: Response) {
const response = await this.ticketService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No tickets found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get ticket by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Ticket 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: 'Ticket not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Ticket not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved ticket by ID',
})
async findById(@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.ticketService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Ticket 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')
@ApiOperation({ summary: 'Filter tickets based on criteria' })
@ApiBody({ type: Ticket, description: 'Filter criteria for tickets' })
@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 tickets found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No tickets found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered tickets',
})
async filter(@Body() ticket: Ticket, @Res() res: Response) {
if (!ticket) {
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.ticketService.filter(ticket) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No tickets 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 ticket' })
@ApiBody({ type: Ticket, description: 'Ticket data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid ticket data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a ticket',
})
async insert(@Body() ticket: Ticket, @Res() res: Response) {
if (!ticket) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete ticket.id;
const response = await this.ticketService.upsert(ticket, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing ticket' })
@ApiBody({ type: Ticket, description: 'Ticket data to update' })
@ApiResponse({
status: 400,
description: 'Invalid ticket data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Ticket not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Ticket not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated ticket',
})
async update(@Body() ticket: Ticket, @Res() res: Response) {
if (!ticket || !ticket.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.ticketService.upsert(ticket, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Ticket with ID ${ticket.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 ticket by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Ticket 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: 'Ticket not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Ticket not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted ticket',
})
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.ticketService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Ticket 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

@ -0,0 +1,82 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'tickets', paranoid: true })
export default class Ticket extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'event_id', allowNull: false })
eventId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'ticket_type' })
ticketType: string;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'price' })
price: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'seat_number' })
seatNumber: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'qr_code' })
qrCode: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'buyer_email', allowNull: false })
buyerEmail: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'booking_date' })
bookingDate: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'payment_status' })
paymentStatus: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'rescheduled_at' })
rescheduledAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'scanned' })
scanned: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { TicketController } from './ticket.controller';
import { TicketService } from './ticket.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [TicketService],
controllers: [TicketController],
})
export class TicketModule { }

View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import Ticket from './ticket.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class TicketService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: Ticket[], count: number }> {
return Ticket.findAndCountAll();
}
async findByPk(id: number): Promise<Ticket> {
const ticket = Ticket.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await ticket).textbookId);
return ticket
}
findOne(ticket: Ticket): Promise<Ticket> {
return Ticket.findOne({ where: ticket as any, })
}
filter(ticket: Ticket): Promise<Ticket[]> {
return Ticket.findAll({ where: ticket as any, })
}
async remove(id: number): Promise<number> {
return Ticket.destroy({ where: { id: id } });
}
async upsert(ticket: Ticket, insertIfNotFound: boolean): Promise<Ticket | [affectedCount: number]> {
if (ticket.id) {
const existingTicket = await this.findByPk(ticket.id);
if (existingTicket) {
return Ticket.update(ticket, { where: { id: ticket.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(ticket.textbookId);
return Ticket.create(ticket as any)
}
}
}

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { TicketPricingService } from './ticketPricing.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import TicketPricing from './ticketPricing.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('ticketPricing')
@Controller('ticketPricing')
export class TicketPricingController {
constructor(private ticketPricingService: TicketPricingService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all ticketPricings' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all ticketPricings',
})
@ApiResponse({
status: 404,
description: 'No ticketPricings found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No ticketPricings found"
},
"data": null
}
})
async getAllTicketPricings(@Res() res: Response) {
const response = await this.ticketPricingService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No ticketPricings found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get ticketPricing by ID' })
@ApiParam({ name: 'id', type: Number, description: 'TicketPricing 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: 'TicketPricing not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "TicketPricing not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved ticketPricing by ID',
})
async findById(@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.ticketPricingService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `TicketPricing 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')
@ApiOperation({ summary: 'Filter ticketPricings based on criteria' })
@ApiBody({ type: TicketPricing, description: 'Filter criteria for ticketPricings' })
@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 ticketPricings found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No ticketPricings found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered ticketPricings',
})
async filter(@Body() ticketPricing: TicketPricing, @Res() res: Response) {
if (!ticketPricing) {
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.ticketPricingService.filter(ticketPricing) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No ticketPricings 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 ticketPricing' })
@ApiBody({ type: TicketPricing, description: 'TicketPricing data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid ticketPricing data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a ticketPricing',
})
async insert(@Body() ticketPricing: TicketPricing, @Res() res: Response) {
if (!ticketPricing) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete ticketPricing.id;
const response = await this.ticketPricingService.upsert(ticketPricing, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing ticketPricing' })
@ApiBody({ type: TicketPricing, description: 'TicketPricing data to update' })
@ApiResponse({
status: 400,
description: 'Invalid ticketPricing data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'TicketPricing not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "TicketPricing not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated ticketPricing',
})
async update(@Body() ticketPricing: TicketPricing, @Res() res: Response) {
if (!ticketPricing || !ticketPricing.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.ticketPricingService.upsert(ticketPricing, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `TicketPricing with ID ${ticketPricing.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 ticketPricing by ID' })
@ApiParam({ name: 'id', type: Number, description: 'TicketPricing 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: 'TicketPricing not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "TicketPricing not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted ticketPricing',
})
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.ticketPricingService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `TicketPricing 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

@ -0,0 +1,58 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'ticket_pricing', paranoid: true })
export default class TicketPricing extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'event_id', allowNull: false })
eventId: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'time_slot_id' })
timeSlotId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'ticket_type' })
ticketType: string;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'price' })
price: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { TicketPricingController } from './ticketPricing.controller';
import { TicketPricingService } from './ticketPricing.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [TicketPricingService],
controllers: [TicketPricingController],
})
export class TicketPricingModule { }

View File

@ -0,0 +1,49 @@
import { Injectable } from '@nestjs/common';
import TicketPricing from './ticketPricing.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class TicketPricingService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: TicketPricing[], count: number }> {
return TicketPricing.findAndCountAll();
}
async findByPk(id: number): Promise<TicketPricing> {
const ticketPricing = TicketPricing.findByPk(id,)
// //const textbookExists = await this.checkTextbookExists((await ticketPricing).textbookId);
return ticketPricing
}
findOne(ticketPricing: TicketPricing): Promise<TicketPricing> {
return TicketPricing.findOne({ where: ticketPricing as any, })
}
filter(ticketPricing: TicketPricing): Promise<TicketPricing[]> {
return TicketPricing.findAll({ where: ticketPricing as any, })
}
async remove(id: number): Promise<number> {
return TicketPricing.destroy({ where: { id: id } });
}
async upsert(ticketPricing: TicketPricing, insertIfNotFound: boolean): Promise<TicketPricing | [affectedCount: number]> {
if (ticketPricing.id) {
const existingTicketPricing = await this.findByPk(ticketPricing.id);
if (existingTicketPricing) {
return TicketPricing.update(ticketPricing, { where: { id: ticketPricing.id } });
}
}
if (insertIfNotFound) {
//const textbookExists = await this.checkTextbookExists(ticketPricing.textbookId);
return TicketPricing.create(ticketPricing as any)
}
}
}

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { TimeSlotService } from './timeSlot.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import TimeSlot from './timeSlot.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('timeSlot')
@Controller('timeSlot')
export class TimeSlotController {
constructor(private timeSlotService: TimeSlotService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all timeSlots' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all timeSlots',
})
@ApiResponse({
status: 404,
description: 'No timeSlots found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No timeSlots found"
},
"data": null
}
})
async getAllTimeSlots(@Res() res: Response) {
const response = await this.timeSlotService.findAll() || [];
if(!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No timeSlots found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get timeSlot by ID' })
@ApiParam({ name: 'id', type: Number, description: 'TimeSlot 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: 'TimeSlot not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "TimeSlot not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved timeSlot by ID',
})
async findById(@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.timeSlotService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `TimeSlot 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')
@ApiOperation({ summary: 'Filter timeSlots based on criteria' })
@ApiBody({ type: TimeSlot, description: 'Filter criteria for timeSlots' })
@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 timeSlots found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No timeSlots found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered timeSlots',
})
async filter(@Body() timeSlot: TimeSlot, @Res() res: Response) {
if (!timeSlot) {
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.timeSlotService.filter(timeSlot) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No timeSlots 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 timeSlot' })
@ApiBody({ type: TimeSlot, description: 'TimeSlot data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid timeSlot data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a timeSlot',
})
async insert(@Body() timeSlot: TimeSlot, @Res() res: Response) {
if (!timeSlot) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete timeSlot.id;
const response = await this.timeSlotService.upsert(timeSlot, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing timeSlot' })
@ApiBody({ type: TimeSlot, description: 'TimeSlot data to update' })
@ApiResponse({
status: 400,
description: 'Invalid timeSlot data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'TimeSlot not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "TimeSlot not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated timeSlot',
})
async update(@Body() timeSlot: TimeSlot, @Res() res: Response) {
if (!timeSlot || !timeSlot.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.timeSlotService.upsert(timeSlot, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `TimeSlot with ID ${timeSlot.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 timeSlot by ID' })
@ApiParam({ name: 'id', type: Number, description: 'TimeSlot 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: 'TimeSlot not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "TimeSlot not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted timeSlot',
})
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.timeSlotService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `TimeSlot 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

@ -0,0 +1,54 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'time_slots', paranoid: true })
export default class TimeSlot extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, allowNull: false, field: 'event_id' })
eventId: number;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'start_time' })
startTime: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'end_time' })
endTime: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'status' })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validFrom' })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'validTill' })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'createdAt' })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'updatedAt' })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'createdBy' })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'modifiedBy' })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE, field: 'deletedAt' })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'version' })
version: number;
}

View File

@ -0,0 +1,11 @@
import { Module } from '@nestjs/common';
import { TimeSlotController } from './timeSlot.controller';
import { TimeSlotService } from './timeSlot.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [TimeSlotService],
controllers: [TimeSlotController],
})
export class TimeSlotModule { }

View File

@ -0,0 +1,47 @@
import { Injectable } from '@nestjs/common';
import TimeSlot from './timeSlot.entity';
import { firstValueFrom } from 'rxjs';
import { HttpService } from "@nestjs/axios";
import { Utility } from 'src/common/Utility';
@Injectable()
export class TimeSlotService {
constructor(private readonly httpService: HttpService) { }
async findAll(): Promise<{ rows: TimeSlot[], count: number }> {
return TimeSlot.findAndCountAll();
}
async findByPk(id: number): Promise<TimeSlot> {
const timeSlot = TimeSlot.findByPk(id,)
return timeSlot
}
findOne(timeSlot: TimeSlot): Promise<TimeSlot> {
return TimeSlot.findOne({ where: timeSlot as any, })
}
filter(timeSlot: TimeSlot): Promise<TimeSlot[]> {
return TimeSlot.findAll({ where: timeSlot as any, })
}
async remove(id: number): Promise<number> {
return TimeSlot.destroy({ where: { id: id } });
}
async upsert(timeSlot: TimeSlot, insertIfNotFound: boolean): Promise<TimeSlot | [affectedCount: number]> {
if (timeSlot.id) {
const existingTimeSlot = await this.findByPk(timeSlot.id);
if (existingTimeSlot) {
return TimeSlot.update(timeSlot, { where: { id: timeSlot.id } });
}
}
if (insertIfNotFound) {
return TimeSlot.create(timeSlot as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserAdditionalDetailsController } from './user-additional-details.controller';
describe('UserAdditionalDetailsController', () => {
let controller: UserAdditionalDetailsController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserAdditionalDetailsController],
}).compile();
controller = module.get<UserAdditionalDetailsController>(UserAdditionalDetailsController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

View File

@ -0,0 +1,340 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { UserAdditionalDetailsService } from './user-additional-details.service';
import { GenericResponse } from 'src/common/GenericResponse.model';
import UserAdditionalDetail from './user-additional-details.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('user-additional-details')
@Controller('users/addl/')
export class UserAdditionalDetailsController {
constructor(private userAdditionalDetailsService: UserAdditionalDetailsService) { }
@Get("/all")
@ApiOperation({ summary: 'Get all user additional details' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all user additional details',
})
@ApiResponse({
status: 404,
description: 'No user additional details found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No user additional details found"
},
"data": null
}
})
async userAdditionalDetailsgetAll(@Res() res: Response) {
const response = await this.userAdditionalDetailsService.findAll() || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No user additional details found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get user additional details by ID' })
@ApiParam({ name: 'id', type: Number, description: 'User Additional Details ID' })
@ApiResponse({
status: 400,
description: 'ID parameter is missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_IN_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User additional details not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User additional details not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved user additional details by ID',
})
async userAdditionalDetailsFindById(@Param('id') id: number, @Res() res: Response) {
if (!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_IN_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
const response = await this.userAdditionalDetailsService.findByPk(id) || {};
if(!response) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'User additional details not found'
}, null);
res.status(404).send(response);
return;
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Post('/filter')
@ApiOperation({ summary: 'Filter user additional details based on criteria' })
@ApiBody({ type: UserAdditionalDetail, description: 'User additional detail filter criteria' })
@ApiResponse({
status: 400,
description: 'Request body is missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'No user additional details found matching criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No user additional details found matching criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered user additional details',
})
async userAdditionalDetailsFilter(@Body() user: UserAdditionalDetail, @Res() res: Response) {
if (!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
const response = await this.userAdditionalDetailsService.filter(user) || [];
if (!response) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No user additional details found matching criteria'
}, null);
res.status(404).send(response);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Post()
@ApiOperation({ summary: 'Insert a new user additional detail' })
@ApiBody({ type: UserAdditionalDetail, description: 'User additional detail data to insert' })
@ApiResponse({
status: 400,
description: 'Failed to insert user additional detail',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_CREATED",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User additional detail not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User additional detail not found"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'User additional detail successfully created',
})
async userAdditionalDetailsInsert(@Body() user: UserAdditionalDetail, @Res() res: Response) {
if (!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
delete user.id;
const response = await this.userAdditionalDetailsService.upsert(user, true);
if (!response) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_CREATED',
stackTrace: 'User additional detail not created'
}, null);
res.status(404).send(response);
return;
}
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing user additional detail' })
@ApiBody({ type: UserAdditionalDetail, description: 'User additional detail data to update' })
@ApiResponse({
status: 400,
description: 'Failed to update user additional detail',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_UPDATED",
"stackTrace": "User additional detail not updated"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User additional detail not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User additional detail not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'User additional detail successfully updated',
})
async userAdditionalDetailsUpdate(@Body() user: UserAdditionalDetail, @Res() res: Response) {
if (!user || !user.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
const response = await this.userAdditionalDetailsService.upsert(user, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'User additional detail 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 user additional detail by ID' })
@ApiParam({ name: 'id', type: Number, description: 'User additional detail ID to delete' })
@ApiResponse({
status: 400,
description: 'ID parameter is missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_IN_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User additional detail not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User additional detail not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'User additional detail successfully deleted',
})
async userAdditionalDetailsDeleteById(@Param('id') id: number, @Res() res: Response) {
if (!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_IN_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
const response = await this.userAdditionalDetailsService.remove(id) || {};
if (!response) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'User additional detail not found'
}, null);
res.status(404).send(response);
return;
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
}

View File

@ -0,0 +1,38 @@
import { Table, Column, Model, Default, DataType, ForeignKey, BelongsTo } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
import { User } from '../user.entity';
@Table({ tableName: 'user_additional_details', paranoid: true })
export default class UserAdditionalDetail extends Model {
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
addlDataType: string;
@ApiProperty({ type: Number })
@ForeignKey(() => User)
@Column({ type: DataType.NUMBER , field: 'user_id' })
userId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
addlDataName: string;
@ApiProperty({ type: Date, default: new Date() })
@Default(new Date())
@Column({ type: DataType.DATEONLY })
validFrom: Date;
@ApiProperty({ type: Date, default: new Date("2070-12-31") })
@Default(new Date("2070-12-31"))
@Column({ type: DataType.DATEONLY })
validTill: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
modifiedBy: string;
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserAdditionalDetailsService } from './user-additional-details.service';
describe('UserAdditionalDetailsService', () => {
let service: UserAdditionalDetailsService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserAdditionalDetailsService],
}).compile();
service = module.get<UserAdditionalDetailsService>(UserAdditionalDetailsService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,37 @@
import { Injectable } from '@nestjs/common';
import UserAdditionalDetail from './user-additional-details.entity';
@Injectable()
export class UserAdditionalDetailsService {
async findAll(): Promise<{rows: UserAdditionalDetail[], count: number}> {
return UserAdditionalDetail.findAndCountAll();
}
findByPk(id: number): Promise<UserAdditionalDetail> {
return UserAdditionalDetail.findByPk(id)
}
filter(userAdditionalDetail: UserAdditionalDetail) : Promise<UserAdditionalDetail[]> {
return UserAdditionalDetail.findAll({where: userAdditionalDetail as any})
}
findOne(user: UserAdditionalDetail): Promise<UserAdditionalDetail> {
return UserAdditionalDetail.findOne({where: user as any})
}
async remove(id: number): Promise<number> {
return UserAdditionalDetail.destroy({where: {id: id}});
}
async upsert(userDetail: UserAdditionalDetail, insertIfNotFound: boolean): Promise<UserAdditionalDetail | [affectedCount: number]> {
if(userDetail.id) {
const existingUser = await this.findByPk(userDetail.id);
if(existingUser) {
return UserAdditionalDetail.update(userDetail, {where: {id: userDetail.id}});
}
}
if(insertIfNotFound) {
return UserAdditionalDetail.create(userDetail as any)
}
}
}

View File

@ -0,0 +1,312 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { Response } from 'express';
import { GenericResponse } from 'src/common/GenericResponse.model';
import UserType from './user-type.entity';
import { UserTypesService } from './user-types.service';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('user-types')
@Controller('users/types')
export class UserTypesController {
constructor(private userTypeService: UserTypesService) { }
@Get("/all")
@ApiOperation({ summary: 'Get all user types' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all user types',
})
@ApiResponse({
status: 404,
description: 'No user types found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No user types found"
},
"data": null
}
})
async userTypegetAll(@Res() res: Response) {
const response = await this.userTypeService.findAll() || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No user types found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get user type by ID' })
@ApiParam({ name: 'id', type: Number, description: 'User Type ID' })
@ApiResponse({
status: 400,
description: 'ID parameter is missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_IN_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User type not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User type not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved user type by ID',
})
async userTypeFindById(@Param('id') id: number, @Res() res: Response) {
if (!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_IN_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
const response = await this.userTypeService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'User type not found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Post('/filter')
@ApiOperation({ summary: 'Filter user types based on criteria' })
@ApiBody({ type: UserType, description: 'User type filter criteria' })
@ApiResponse({
status: 404,
description: 'No user types matching criteria found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No user types found matching criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered user types',
})
async userTypeFilter(@Body() user: UserType, @Res() res: Response) {
if (!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
const response = await this.userTypeService.filter(user) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No user types found matching 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 type' })
@ApiBody({ type: UserType, description: 'User type data to insert' })
@ApiResponse({
status: 400,
description: 'Failed to insert user type',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_CREATED",
"stackTrace": "User type not created"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'User type successfully created',
})
async userTypeInsert(@Body() user: UserType, @Res() res: Response) {
if (!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
delete user.id;
const response = await this.userTypeService.upsert(user, true);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_CREATED',
stackTrace: 'User type not created'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing user type' })
@ApiBody({ type: UserType, description: 'User type data to update' })
@ApiResponse({
status: 400,
description: 'Failed to update user type',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_UPDATED",
"stackTrace": "User type not updated"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User type not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User type not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'User type successfully updated',
})
async userTypeUpdate(@Body() user: UserType, @Res() res: Response) {
if (!user || !user.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
const response = await this.userTypeService.upsert(user, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'User type 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 type by ID' })
@ApiParam({ name: 'id', type: Number, description: 'User type ID to delete' })
@ApiResponse({
status: 400,
description: 'ID parameter is missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_IN_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User type not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User type not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'User type successfully deleted',
})
async userTypeDeleteById(@Param('id') id: number, @Res() res: Response) {
if (!id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_IN_REQ',
stackTrace: 'Request'
}, null);
res.status(400).send(response);
return;
}
const response = await this.userTypeService.remove(id) || {};
if(!response){
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'User type not found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
}

View File

@ -0,0 +1,57 @@
import { Table, Column, Model, Default, DataType, Unique } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'user_type', paranoid: true })
export default class UserType extends Model {
@ApiProperty({ type: String })
@Unique(true)
@Column({ type: DataType.TEXT })
userTypeCode: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
userTypeName: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
userTypeDesc: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
status: string;
@ApiProperty({ type: Date, default: new Date() })
@Default(new Date())
@Column({ type: DataType.DATEONLY })
validFrom: Date;
@ApiProperty({ type: Date, default: new Date("2070-12-31") })
@Default(new Date("2070-12-31"))
@Column({ type: DataType.DATEONLY })
validTill: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE })
updatedAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER })
version: number;
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserTypesService } from './user-types.service';
describe('UserTypesService', () => {
let service: UserTypesService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserTypesService],
}).compile();
service = module.get<UserTypesService>(UserTypesService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

View File

@ -0,0 +1,39 @@
import { Injectable } from '@nestjs/common';
import UserType from './user-type.entity';
@Injectable()
export class UserTypesService {
async findAll(): Promise<{rows: UserType[], count: number}> {
return UserType.findAndCountAll();
}
findByPk(id: number): Promise<UserType> {
return UserType.findByPk(id)
}
filter(userType: UserType) : Promise<UserType[]> {
return UserType.findAll({where: userType as any})
}
findOne(user: UserType): Promise<UserType> {
return UserType.findOne({where: user as any})
}
async remove(id: number): Promise<number> {
return UserType.destroy({where: {id: id}});
}
async upsert(userDetail: UserType, insertIfNotFound: boolean): Promise<UserType | [affectedCount: number]> {
if(userDetail.id) {
const existingUser = await this.findByPk(userDetail.id);
if(existingUser) {
return UserType.update(userDetail, {where: {id: userDetail.id}});
}
}
if(insertIfNotFound) {
return UserType.create(userDetail as any)
}
}
}

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserController } from './user.controller';
describe('UserController', () => {
let controller: UserController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
controllers: [UserController],
}).compile();
controller = module.get<UserController>(UserController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
});

330
src/user/user.controller.ts Normal file
View File

@ -0,0 +1,330 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { UserService } from './user.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import { User } from './user.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('users')
@Controller('users')
export class UserController {
constructor(private userService: UserService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all users' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all users',
})
@ApiResponse({
status: 404,
description: 'No users found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No users found"
},
"data": null
}
})
async getAllUsers(@Res() res: Response) {
const response = await this.userService.findAll();
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No users found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get a user by ID' })
@ApiParam({ name: 'id', type: Number, description: 'User ID' })
@ApiResponse({
status: 400,
description: 'ID parameter is missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved user by ID',
})
async findById(@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.userService.findByPk(id);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `User 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')
@ApiOperation({ summary: 'Filter users based on criteria' })
@ApiBody({ type: User, description: 'User filter criteria' })
@ApiResponse({
status: 400,
description: 'Failed to insert user',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_CREATED",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'No users matching criteria found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No users found matching criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered users',
})
async filter(@Body() user: User, @Res() res: Response) {
if (!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
const response = await this.userService.filter(user);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No users found matching 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' })
@ApiBody({ type: User, description: 'User data to insert' })
@ApiResponse({
status: 400,
description: 'Failed to insert user',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_CREATED",
"stackTrace": "User not created"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'User successfully created',
})
async insert(@Body() user: User, @Res() res: Response) {
if (!user) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_REQ',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete user.id;
if (user.password) {
user.password = this.encryptPassword(user.password);
}
const response = await this.userService.upsert(user, true);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_CREATED',
stackTrace: 'User not created'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing user' })
@ApiBody({ type: User, description: 'User data to update' })
@ApiResponse({
status: 400,
description: 'Failed to update user',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_UPDATED",
"stackTrace": "User not updated"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'User successfully updated',
})
async update(@Body() user: User, @Res() res: Response) {
if (!user || !user.id) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NO_ID_REQ',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
if (user.password) {
user.password = this.encryptPassword(user.password);
}
const response = await this.userService.upsert(user, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'User 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 by ID' })
@ApiParam({ name: 'id', type: Number, description: 'User ID to delete' })
@ApiResponse({
status: 400,
description: 'ID parameter is missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'User 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.userService.remove(id);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `User with ID ${id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
encryptPassword(password: string) {
return Buffer.from(password).toString('base64');
}
}

75
src/user/user.entity.ts Normal file
View File

@ -0,0 +1,75 @@
import { Table, Column, Model, Default, DataType, HasMany, Unique, ForeignKey } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
import UserAdditionalDetail from './user-additional-details/user-additional-details.entity';
import UserType from './user-types/user-type.entity';
@Table({ tableName: 'users' })
export class User extends Model {
@ApiProperty({ type: String })
@Unique(true)
@Column({ type: DataType.TEXT, allowNull: false })
email: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
password: string;
@ApiProperty({ type: String })
@ForeignKey(() => UserType)
@Column({ type: DataType.TEXT })
userTypeCode: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
name: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
phoneNumber: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
primaryRole: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
status: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY })
validFrom: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY })
validTill: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE })
createdAt: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE })
updatedAt: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
createdBy: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT })
modifiedBy: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATE })
deletedAt: Date;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER })
version: number;
@ApiProperty({ type: [UserAdditionalDetail] })
@HasMany(() => UserAdditionalDetail)
additionalDetails: UserAdditionalDetail[];
}

15
src/user/user.module.ts Normal file
View File

@ -0,0 +1,15 @@
import { Module } from '@nestjs/common';
import { UserController } from './user.controller';
import { UserService } from './user.service';
import { UserTypesService } from './user-types/user-types.service';
import { UserTypesController } from './user-types/user-type.controller';
import { UserAdditionalDetailsController } from './user-additional-details/user-additional-details.controller';
import { UserAdditionalDetailsService } from './user-additional-details/user-additional-details.service';
@Module({
controllers: [UserController, UserTypesController, UserAdditionalDetailsController],
providers: [UserService, UserTypesService, UserAdditionalDetailsService],
exports: [UserService, UserTypesService, UserAdditionalDetailsService],
imports: []
})
export class UserModule { }

View File

@ -0,0 +1,18 @@
import { Test, TestingModule } from '@nestjs/testing';
import { UserService } from './user.service';
describe('UserService', () => {
let service: UserService;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserService],
}).compile();
service = module.get<UserService>(UserService);
});
it('should be defined', () => {
expect(service).toBeDefined();
});
});

48
src/user/user.service.ts Normal file
View File

@ -0,0 +1,48 @@
import { Injectable } from '@nestjs/common';
import { User } from './user.entity';
import UserAdditionalDetail from './user-additional-details/user-additional-details.entity';
@Injectable()
export class UserService {
constructor() { }
async findAll(): Promise<{rows: User[], count: number}> {
return User.findAndCountAll();
}
findByPk(id: number): Promise<User> {
return User.findByPk(id, {include: UserAdditionalDetail})
}
findOne(user: any): Promise<User> {
return User.findOne({where: user as any, include: UserAdditionalDetail})
}
findByEmail(email: string): Promise<User> {
return User.findOne({where: {email: email}})
}
filter(user: User) : Promise<User[]> {
return User.findAll({where: user as any, include: UserAdditionalDetail})
}
async remove(id: number): Promise<number> {
return User.destroy({where: {id: id}});
}
async upsert(userDetail: User, insertIfNotFound: boolean): Promise<User | [affectedCount: number]> {
if(userDetail.id) {
const existingUser = await this.findByPk(userDetail.id);
if(existingUser) {
return User.update(userDetail, {where: {id: userDetail.id}});
}
}
if(insertIfNotFound) {
return User.create(userDetail as any)
}
}
async login(user: User): Promise<User> {
return User.findOne({where: user as any, include: UserAdditionalDetail})
}
}

5
vapid-script.js Normal file
View File

@ -0,0 +1,5 @@
const webPush = require('web-push');
const vapidKeys = webPush.generateVAPIDKeys();
console.log(vapidKeys);