added cast, event-analytics, event-categories, episodes, and watchlist

This commit is contained in:
harshithnrao 2025-04-10 23:25:52 +05:30
parent 75673ae96d
commit 90f378a877
33 changed files with 3071 additions and 11 deletions

View File

@ -183,7 +183,7 @@ CREATE TABLE "theatre_additional_details" (
CREATE TABLE "events" ( CREATE TABLE "events" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"org_email" TEXT NOT NULL, "organizer_id" TEXT NOT NULL,
"event_name" TEXT, "event_name" TEXT,
"start_date" DATE, "start_date" DATE,
"end_date" DATE, "end_date" DATE,
@ -280,7 +280,7 @@ CREATE TABLE "tickets" (
"price" NUMERIC, "price" NUMERIC,
"seat_number" TEXT, "seat_number" TEXT,
"qr_code" TEXT, "qr_code" TEXT,
"buyer_email" TEXT NOT NULL, "buyer_id" NUMERIC NOT NULL,
"booking_date" DATE, "booking_date" DATE,
"payment_status" TEXT, "payment_status" TEXT,
"rescheduled_at" DATE, "rescheduled_at" DATE,
@ -299,7 +299,7 @@ CREATE TABLE "tickets" (
CREATE TABLE "reviews" ( CREATE TABLE "reviews" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL, "event_id" NUMERIC NOT NULL,
"buyer_email" TEXT NOT NULL, "buyer_id" TEXT NOT NULL,
"rating" NUMERIC, "rating" NUMERIC,
"comment" TEXT, "comment" TEXT,
"status" TEXT, "status" TEXT,
@ -332,11 +332,11 @@ CREATE TABLE "seats" (
CREATE TABLE "payouts" ( CREATE TABLE "payouts" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"payee_email" TEXT NOT NULL, "payee_id" TEXT NOT NULL,
"amount" NUMERIC, "amount" NUMERIC,
"payment_method" TEXT, "payment_method" TEXT,
"transaction_id" TEXT, "transaction_id" TEXT,
"paid_to_email" TEXT, "paid_to_id" TEXT,
"payout_date" DATE, "payout_date" DATE,
"status" TEXT, "status" TEXT,
"validFrom" DATE, "validFrom" DATE,
@ -369,6 +369,7 @@ CREATE TABLE "refunds" (
CREATE TABLE "push_notification" ( CREATE TABLE "push_notification" (
"id" BIGSERIAL PRIMARY KEY, "id" BIGSERIAL PRIMARY KEY,
"user_id" NUMERIC NOT NULL,
"endpoint" TEXT NOT NULL, "endpoint" TEXT NOT NULL,
"p256dh" TEXT, "p256dh" TEXT,
"auth" TEXT, "auth" TEXT,
@ -382,3 +383,96 @@ CREATE TABLE "push_notification" (
"deletedAt" DATE, "deletedAt" DATE,
"version" NUMERIC "version" NUMERIC
); );
CREATE TABLE "promotions" (
"id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL,
"start_date" DATE,
"end_date" DATE,
"location" TEXT,
"type" TEXT,
"description" TEXT,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "event_episodes" (
"id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL,
"episode_name" TEXT,
"episode_description" TEXT,
"episode_start_date" DATE,
"episode_end_date" DATE,
"episode_location" TEXT,
"episode_type" TEXT,
"images" JSON,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "cast_members" (
"id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL,
"cast_name" TEXT,
"role" TEXT,
"images" JSON,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "user_watchlist" (
"id" BIGSERIAL PRIMARY KEY,
"user_id" NUMERIC NOT NULL,
"event_id" NUMERIC NOT NULL,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);
CREATE TABLE "event_analytics" (
"id" BIGSERIAL PRIMARY KEY,
"event_id" NUMERIC NOT NULL,
"views" NUMERIC,
"ticket_sales" NUMERIC,
"engagement_rate" NUMERIC,
"promotion_views" NUMERIC,
"promotion_sales" NUMERIC,
"status" TEXT,
"validFrom" DATE,
"validTill" DATE,
"createdAt" DATE,
"updatedAt" DATE,
"createdBy" TEXT,
"modifiedBy" TEXT,
"deletedAt" DATE,
"version" NUMERIC
);

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

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

71
src/cast/cast.dto.ts Normal file
View File

@ -0,0 +1,71 @@
import { IsString, IsNumber, IsDate, IsOptional, IsNotEmpty } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
export class CastMemberDTO {
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
eventId: number;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
castName: string;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
role: string;
@ApiProperty({ type: Object })
@IsOptional()
images: object;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
status: string;
@ApiProperty({ type: Date })
@IsDate()
@IsOptional()
@Transform(({ value }) => new Date(value))
validFrom: Date;
@ApiProperty({ type: Date })
@IsDate()
@IsOptional()
@Transform(({ value }) => new Date(value))
validTill: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
createdAt: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
updatedAt: Date;
@ApiProperty({ type: String })
@IsString()
createdBy: string;
@ApiProperty({ type: String })
@IsString()
modifiedBy: string;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => value ? new Date(value) : null)
deletedAt: Date;
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
version: number;
}

58
src/cast/cast.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: 'cast', paranoid: true })
export default class Cast extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, allowNull: false, field: 'event_id' })
eventId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'cast_name' })
castName: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'role' })
role: string;
@ApiProperty({ type: Object })
@Column({ type: DataType.JSON, field: 'images' })
images: object;
@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/cast/cast.module.ts Normal file
View File

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

41
src/cast/cast.service.ts Normal file
View File

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

View File

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

View File

@ -0,0 +1,92 @@
import { IsString, IsNumber, IsDate, IsOptional, IsNotEmpty } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
export class EventAnalyticsDTO {
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
eventId: number;
@ApiProperty({ type: Number })
@IsOptional()
@IsNumber()
views: number;
@ApiProperty({ type: Number })
@IsOptional()
@IsNumber()
ticketSales: number;
@ApiProperty({ type: Number })
@IsOptional()
@IsNumber()
engagementRate: number;
@ApiProperty({ type: Number })
@IsOptional()
@IsNumber()
promotionViews: number;
@ApiProperty({ type: Number })
@IsOptional()
@IsNumber()
promotionSales: number;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
status: string;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => new Date(value))
validFrom: Date;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => new Date(value))
validTill: Date;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => new Date(value))
createdAt: Date;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => new Date(value))
updatedAt: Date;
@ApiProperty({ type: String })
@IsOptional()
@IsString()
createdBy: string;
@ApiProperty({ type: String })
@IsOptional()
@IsString()
modifiedBy: string;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => value ? new Date(value) : null)
deletedAt: Date;
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
version: number;
}
export class EventAnalyticsUpdateDTO extends EventAnalyticsDTO {
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
id: number;
}

View File

@ -0,0 +1,66 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'event_analytics', paranoid: true })
export default class EventAnalytics extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, allowNull: false, field: 'event_id' })
eventId: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'views' })
views: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'ticket_sales' })
ticketSales: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'engagement_rate' })
engagementRate: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'promotion_views' })
promotionViews: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, field: 'promotion_sales' })
promotionSales: 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 { EventAnalyticsController } from './event-analytics.controller';
import { EventAnalyticsService } from './event-analytics.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [EventAnalyticsService],
controllers: [EventAnalyticsController],
})
export class EventAnalyticsModule { }

View File

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

View File

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

View File

@ -0,0 +1,64 @@
import { IsString, IsNumber, IsDate, IsOptional, IsNotEmpty } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
export class EventCategoryDTO {
@ApiProperty({ type: String })
@IsString()
@IsNotEmpty()
categoryName: string;
@ApiProperty({ type: String })
@IsString()
@IsNotEmpty()
status: string;
@ApiProperty({ type: Date })
@IsDate()
@IsNotEmpty()
@Transform(({ value }) => new Date(value))
validFrom: Date;
@ApiProperty({ type: Date })
@IsDate()
@IsNotEmpty()
@Transform(({ value }) => new Date(value))
validTill: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
createdAt: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
updatedAt: Date;
@ApiProperty({ type: String })
@IsString()
createdBy: string;
@ApiProperty({ type: String })
@IsString()
modifiedBy: string;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => value ? new Date(value) : null)
deletedAt: Date;
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
version: number;
}
export class EventCategoryUpdateDTO extends EventCategoryDTO {
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
id: number;
}

View File

@ -0,0 +1,46 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'event_categories', paranoid: true })
export default class EventCategory extends Model {
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'category_name' })
categoryName: 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 { EventCategoryController } from './event-category.controller';
import { EventCategoryService } from './event-category.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [EventCategoryService],
controllers: [EventCategoryController],
})
export class EventCategoryModule {}

View File

@ -0,0 +1,40 @@
import { Injectable } from '@nestjs/common';
import EventCategory from './event-category.entity';
import { HttpService } from '@nestjs/axios';
@Injectable()
export class EventCategoryService {
constructor(private readonly httpService: HttpService) {}
async findAll(): Promise<{ rows: EventCategory[]; count: number }> {
return EventCategory.findAndCountAll();
}
async findByPk(id: number): Promise<EventCategory> {
return EventCategory.findByPk(id);
}
findOne(category: EventCategory): Promise<EventCategory> {
return EventCategory.findOne({ where: category as any });
}
filter(category: EventCategory): Promise<EventCategory[]> {
return EventCategory.findAll({ where: category as any });
}
async remove(id: number): Promise<number> {
return EventCategory.destroy({ where: { id } });
}
async upsert(category: EventCategory, insertIfNotFound: boolean): Promise<EventCategory | [affectedCount: number]> {
if (category.id) {
const existingCategory = await this.findByPk(category.id);
if (existingCategory) {
return EventCategory.update(category, { where: { id: category.id } });
}
}
if (insertIfNotFound) {
return EventCategory.create(category as any);
}
}
}

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { EventEpisodeService } from './event-episodes.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import EventEpisode from './event-episodes.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('event-episode')
@Controller('event-episode')
export class EventEpisodeController {
constructor(private eventEpisodeService: EventEpisodeService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all event episodes' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all event episodes',
})
@ApiResponse({
status: 404,
description: 'No event episodes found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No event episodes found"
},
"data": null
}
})
async getAllEventEpisodes(@Res() res: Response) {
const response = await this.eventEpisodeService.findAll() || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No event episodes found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get event episode by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Event Episode 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 episode not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Event episode not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved event episode 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.eventEpisodeService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Event episode 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 event episodes based on criteria' })
@ApiBody({ type: EventEpisode, description: 'Filter criteria for event episodes' })
@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 event episodes found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No event episodes found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered event episodes',
})
async filter(@Body() eventEpisode: EventEpisode, @Res() res: Response) {
if (!eventEpisode) {
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.eventEpisodeService.filter(eventEpisode) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No event episodes 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 episode' })
@ApiBody({ type: EventEpisode, description: 'Event episode data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid event episode data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created an event episode',
})
async insert(@Body() eventEpisode: EventEpisode, @Res() res: Response) {
if (!eventEpisode) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete eventEpisode.id; // Ensure no ID is passed in the creation
const response = await this.eventEpisodeService.upsert(eventEpisode, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing event episode' })
@ApiBody({ type: EventEpisode, description: 'Event episode data to update' })
@ApiResponse({
status: 400,
description: 'Invalid event episode data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Event episode not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Event episode not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated event episode',
})
async update(@Body() eventEpisode: EventEpisode, @Res() res: Response) {
if (!eventEpisode || !eventEpisode.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.eventEpisodeService.upsert(eventEpisode, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Event episode with ID ${eventEpisode.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 an event episode by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Event episode 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 episode not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Event episode not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted event episode',
})
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.eventEpisodeService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Event episode 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,93 @@
import { IsString, IsNumber, IsDate, IsOptional, IsNotEmpty } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
export class EventEpisodeDTO {
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
eventId: number;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
episodeName: string;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
episodeDescription: string;
@ApiProperty({ type: Date })
@IsDate()
@IsOptional()
@Transform(({ value }) => new Date(value))
episodeStartDate: Date;
@ApiProperty({ type: Date })
@IsDate()
@IsOptional()
@Transform(({ value }) => new Date(value))
episodeEndDate: Date;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
episodeLocation: string;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
episodeType: string;
@ApiProperty({ type: Object })
@IsOptional()
images: object;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
status: string;
@ApiProperty({ type: Date })
@IsDate()
@IsOptional()
@Transform(({ value }) => new Date(value))
validFrom: Date;
@ApiProperty({ type: Date })
@IsDate()
@IsOptional()
@Transform(({ value }) => new Date(value))
validTill: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
createdAt: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
updatedAt: Date;
@ApiProperty({ type: String })
@IsString()
createdBy: string;
@ApiProperty({ type: String })
@IsString()
modifiedBy: string;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => value ? new Date(value) : null)
deletedAt: Date;
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
version: number;
}

View File

@ -0,0 +1,74 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'event_episodes', paranoid: true })
export default class EventEpisode extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, allowNull: false, field: 'event_id' })
eventId: number;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'episode_name' })
episodeName: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'episode_description' })
episodeDescription: string;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'episode_start_date' })
episodeStartDate: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'episode_end_date' })
episodeEndDate: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'episode_location' })
episodeLocation: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'episode_type' })
episodeType: string;
@ApiProperty({ type: Object })
@Column({ type: DataType.JSON, field: 'images' })
images: object;
@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 { EventEpisodeController } from './event-episodes.controller';
import { EventEpisodeService } from './event-episodes.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [EventEpisodeService],
controllers: [EventEpisodeController],
})
export class EventEpisodeModule {}

View File

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

View File

@ -4,9 +4,9 @@ import { Transform } from 'class-transformer';
export class EventDTO { export class EventDTO {
@ApiProperty({ type: String }) @ApiProperty({ type: Number })
@IsEmail() @IsNumber()
orgEmail: string; organizer_id: number;
@ApiProperty({ type: String }) @ApiProperty({ type: String })
@IsString() @IsString()

View File

@ -4,9 +4,9 @@ import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'events', paranoid: true }) @Table({ tableName: 'events', paranoid: true })
export default class Event extends Model { export default class Event extends Model {
@ApiProperty({ type: String }) @ApiProperty({ type: Number })
@Column({ type: DataType.TEXT, field: 'org_email' }) @Column({ type: DataType.NUMBER, field: 'organizer_id' })
orgEmail: string; organizerId: number;
@ApiProperty({ type: String }) @ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'event_name' }) @Column({ type: DataType.TEXT, field: 'event_name' })

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { PromotionService } from './promotions.service'; // Updated service
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import Promotion from './promotions.entity'; // Updated entity
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('promotion')
@Controller('promotion')
export class PromotionController {
constructor(private promotionService: PromotionService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all promotions' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all promotions',
})
@ApiResponse({
status: 404,
description: 'No promotions found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No promotions found"
},
"data": null
}
})
async getAllPromotions(@Res() res: Response) {
const response = await this.promotionService.findAll() || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No promotions found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get promotion by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Promotion 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: 'Promotion not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Promotion not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved promotion 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.promotionService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Promotion 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 promotions based on criteria' })
@ApiBody({ type: Promotion, description: 'Filter criteria for promotions' })
@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 promotions found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No promotions found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered promotions',
})
async filter(@Body() promotion: Promotion, @Res() res: Response) {
if (!promotion) {
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.promotionService.filter(promotion) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No promotions 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 promotion' })
@ApiBody({ type: Promotion, description: 'Promotion data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid promotion data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a promotion',
})
async insert(@Body() promotion: Promotion, @Res() res: Response) {
if (!promotion) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete promotion.id; // Ensure no ID is passed in the creation
const response = await this.promotionService.upsert(promotion, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing promotion' })
@ApiBody({ type: Promotion, description: 'Promotion data to update' })
@ApiResponse({
status: 400,
description: 'Invalid promotion data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'Promotion not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Promotion not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated promotion',
})
async update(@Body() promotion: Promotion, @Res() res: Response) {
if (!promotion || !promotion.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.promotionService.upsert(promotion, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Promotion with ID ${promotion.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 promotion by ID' })
@ApiParam({ name: 'id', type: Number, description: 'Promotion 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: 'Promotion not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "Promotion not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted promotion',
})
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.promotionService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `Promotion 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,91 @@
import { IsString, IsNumber, IsDate, IsOptional, IsNotEmpty } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
export class PromotionDTO {
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
eventId: number;
@ApiProperty({ type: Date })
@IsDate()
@IsNotEmpty()
@Transform(({ value }) => new Date(value))
startDate: Date;
@ApiProperty({ type: Date })
@IsDate()
@IsNotEmpty()
@Transform(({ value }) => new Date(value))
endDate: Date;
@ApiProperty({ type: String })
@IsString()
@IsNotEmpty()
location: string;
@ApiProperty({ type: String })
@IsString()
@IsNotEmpty()
type: string;
@ApiProperty({ type: String })
@IsString()
@IsNotEmpty()
description: string;
@ApiProperty({ type: String })
@IsString()
@IsNotEmpty()
status: string;
@ApiProperty({ type: Date })
@IsDate()
@IsNotEmpty()
@Transform(({ value }) => new Date(value))
validFrom: Date;
@ApiProperty({ type: Date })
@IsDate()
@IsNotEmpty()
@Transform(({ value }) => new Date(value))
validTill: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
createdAt: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
updatedAt: Date;
@ApiProperty({ type: String })
@IsString()
createdBy: string;
@ApiProperty({ type: String })
@IsString()
modifiedBy: string;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => value ? new Date(value) : null)
deletedAt: Date;
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
version: number;
}
export class PromotionUpdateDTO extends PromotionDTO {
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
id: number
}

View File

@ -0,0 +1,66 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'promotions', paranoid: true })
export default class Promotion 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_date' })
startDate: Date;
@ApiProperty({ type: Date })
@Column({ type: DataType.DATEONLY, field: 'end_date' })
endDate: Date;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'location' })
location: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'type' })
type: string;
@ApiProperty({ type: String })
@Column({ type: DataType.TEXT, field: 'description' })
description: 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 { PromotionController } from './promotions.controller';
import { PromotionService } from './promotions.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [PromotionService],
controllers: [PromotionController],
})
export class PromotionModule { }

View File

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

View File

@ -0,0 +1,310 @@
import { Body, Controller, Delete, Get, Param, Post, Put, Res } from '@nestjs/common';
import { UserWatchlistService } from './user-watchlist.service';
import { Response } from 'express';
import { GenericResponse } from '../common/GenericResponse.model';
import UserWatchlist from './user-watchlist.entity';
import { ApiTags, ApiOperation, ApiResponse, ApiParam, ApiBody } from '@nestjs/swagger';
@ApiTags('user-watchlist')
@Controller('user-watchlist')
export class UserWatchlistController {
constructor(private userWatchlistService: UserWatchlistService) {}
@Get("/all")
@ApiOperation({ summary: 'Get all user watchlists' })
@ApiResponse({
status: 200,
description: 'Successfully retrieved all user watchlists',
})
@ApiResponse({
status: 404,
description: 'No user watchlists found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No user watchlists found"
},
"data": null
}
})
async getAllUserWatchlists(@Res() res: Response) {
const response = await this.userWatchlistService.findAll() || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No user watchlists found'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.send(httpResponse);
}
@Get(':id')
@ApiOperation({ summary: 'Get user watchlist by ID' })
@ApiParam({ name: 'id', type: Number, description: 'User Watchlist 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: 'User watchlist not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User watchlist not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully retrieved user watchlist 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.userWatchlistService.findByPk(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `User watchlist 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 user watchlists based on criteria' })
@ApiBody({ type: UserWatchlist, description: 'Filter criteria for user watchlists' })
@ApiResponse({
status: 400,
description: 'Invalid filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_CRITERIA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'No user watchlists found based on filter criteria',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "No user watchlists found based on the filter criteria"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully filtered user watchlists',
})
async filter(@Body() userWatchlist: UserWatchlist, @Res() res: Response) {
if (!userWatchlist) {
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.userWatchlistService.filter(userWatchlist) || [];
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: 'No user watchlists found based on the filter criteria'
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Post()
@ApiOperation({ summary: 'Insert a new user watchlist' })
@ApiBody({ type: UserWatchlist, description: 'User watchlist data to insert' })
@ApiResponse({
status: 400,
description: 'Invalid user watchlist data',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 201,
description: 'Successfully created a user watchlist',
})
async insert(@Body() userWatchlist: UserWatchlist, @Res() res: Response) {
if (!userWatchlist) {
const response = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.INVALID_DATA',
stackTrace: 'Request'
}, null);
return res.status(400).send(response);
}
delete userWatchlist.id; // Ensure no ID is passed in the creation
const response = await this.userWatchlistService.upsert(userWatchlist, true);
const httpResponse = new GenericResponse(null, response);
res.status(201).send(httpResponse);
}
@Put()
@ApiOperation({ summary: 'Update an existing user watchlist' })
@ApiBody({ type: UserWatchlist, description: 'User watchlist data to update' })
@ApiResponse({
status: 400,
description: 'Invalid user watchlist data or ID missing',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.INVALID_DATA",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User watchlist not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User watchlist not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully updated user watchlist',
})
async update(@Body() userWatchlist: UserWatchlist, @Res() res: Response) {
if (!userWatchlist || !userWatchlist.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.userWatchlistService.upsert(userWatchlist, false);
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `User watchlist with ID ${userWatchlist.id} not found`
}, null);
return res.status(404).send(errorResponse);
}
const httpResponse = new GenericResponse(null, response);
res.status(200).send(httpResponse);
}
@Delete(':id')
@ApiOperation({ summary: 'Delete a user watchlist by ID' })
@ApiParam({ name: 'id', type: Number, description: 'User watchlist ID to delete' })
@ApiResponse({
status: 400,
description: 'ID parameter is required',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NO_ID_REQ",
"stackTrace": "Request"
},
"data": null
}
})
@ApiResponse({
status: 404,
description: 'User watchlist not found',
example: {
"notification": {
"exception": true,
"exceptionSeverity": "HIGH",
"exceptionMessage": "ERR.NOT_FOUND",
"stackTrace": "User watchlist not found"
},
"data": null
}
})
@ApiResponse({
status: 200,
description: 'Successfully deleted user watchlist',
})
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.userWatchlistService.remove(id) || {};
if (!response) {
const errorResponse = new GenericResponse({
exception: true,
exceptionSeverity: 'HIGH',
exceptionMessage: 'ERR.NOT_FOUND',
stackTrace: `User watchlist 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,69 @@
import { IsString, IsNumber, IsDate, IsOptional, IsNotEmpty } from 'class-validator';
import { ApiProperty } from '@nestjs/swagger';
import { Transform } from 'class-transformer';
export class UserWatchlistDTO {
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
userId: number;
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
eventId: number;
@ApiProperty({ type: String })
@IsString()
@IsOptional()
status: string;
@ApiProperty({ type: Date })
@IsDate()
@IsOptional()
@Transform(({ value }) => new Date(value))
validFrom: Date;
@ApiProperty({ type: Date })
@IsDate()
@IsOptional()
@Transform(({ value }) => new Date(value))
validTill: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
createdAt: Date;
@ApiProperty({ type: Date })
@IsDate()
@Transform(({ value }) => new Date(value))
updatedAt: Date;
@ApiProperty({ type: String })
@IsString()
createdBy: string;
@ApiProperty({ type: String })
@IsString()
modifiedBy: string;
@ApiProperty({ type: Date })
@IsOptional()
@IsDate()
@Transform(({ value }) => value ? new Date(value) : null)
deletedAt: Date;
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
version: number;
}
export class UserWatchlistUpdateDTO extends UserWatchlistDTO {
@ApiProperty({ type: Number })
@IsNumber()
@IsNotEmpty()
id: number;
}

View File

@ -0,0 +1,50 @@
import { Table, Column, Model, DataType } from 'sequelize-typescript';
import { ApiProperty } from '@nestjs/swagger';
@Table({ tableName: 'user_watchlist', paranoid: true })
export default class UserWatchlist extends Model {
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, allowNull: false, field: 'user_id' })
userId: number;
@ApiProperty({ type: Number })
@Column({ type: DataType.NUMBER, allowNull: false, field: 'event_id' })
eventId: 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 { UserWatchlistController } from './user-watchlist.controller';
import { UserWatchlistService } from './user-watchlist.service';
import { HttpModule } from '@nestjs/axios';
@Module({
imports: [HttpModule],
providers: [UserWatchlistService],
controllers: [UserWatchlistController],
})
export class UserWatchlistModule { }

View File

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