feat: implement cohort module with entity, DTO, and CRUD service operations

This commit is contained in:
azeeee05
2026-07-10 10:42:43 +05:30
parent 18454d5197
commit 6e7ff937dc
3 changed files with 140 additions and 42 deletions
+61 -19
View File
@@ -1,4 +1,11 @@
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn } from 'typeorm';
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, ManyToMany, JoinTable } from 'typeorm';
import { CabinClass } from '../master-data/entities/cabin-class.entity';
import { PassengerType } from '../master-data/entities/passenger-type.entity';
import { AncillaryPurchase } from '../master-data/entities/ancillary-purchase.entity';
import { MembershipTier } from '../master-data/entities/membership-tier.entity';
import { RevenueSegment } from '../master-data/entities/revenue-segment.entity';
import { Region } from '../master-data/entities/region.entity';
import { TripPurpose } from '../master-data/entities/trip-purpose.entity';
@Entity('tbl_cohorts')
export class Cohort {
@@ -15,21 +22,46 @@ export class Cohort {
status: string; // Draft, Active, Inactive
// Passenger Attributes
@Column({ nullable: true })
cabinClassId: string;
@ManyToMany(() => CabinClass)
@JoinTable({
name: 'tbl_cohort_cabin_classes',
joinColumn: { name: 'cohortId', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'cabinClassId', referencedColumnName: 'id' }
})
cabinClasses: CabinClass[];
@Column({ nullable: true })
passengerTypeId: string;
@ManyToMany(() => PassengerType)
@JoinTable({
name: 'tbl_cohort_passenger_types',
joinColumn: { name: 'cohortId', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'passengerTypeId', referencedColumnName: 'id' }
})
passengerTypes: PassengerType[];
@Column({ nullable: true })
ancillaryPurchaseId: string;
@ManyToMany(() => AncillaryPurchase)
@JoinTable({
name: 'tbl_cohort_ancillary_purchases',
joinColumn: { name: 'cohortId', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'ancillaryPurchaseId', referencedColumnName: 'id' }
})
ancillaryPurchases: AncillaryPurchase[];
// Customer Value
@Column({ nullable: true })
loyaltyTierId: string;
@ManyToMany(() => MembershipTier)
@JoinTable({
name: 'tbl_cohort_loyalty_tiers',
joinColumn: { name: 'cohortId', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'membershipTierId', referencedColumnName: 'id' }
})
loyaltyTiers: MembershipTier[];
@Column({ nullable: true })
revenueSegmentId: string;
@ManyToMany(() => RevenueSegment)
@JoinTable({
name: 'tbl_cohort_revenue_segments',
joinColumn: { name: 'cohortId', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'revenueSegmentId', referencedColumnName: 'id' }
})
revenueSegments: RevenueSegment[];
@Column({
type: 'enum',
@@ -45,17 +77,27 @@ export class Cohort {
})
flightType: string;
@Column({ nullable: true })
regionId: string;
@ManyToMany(() => Region)
@JoinTable({
name: 'tbl_cohort_regions',
joinColumn: { name: 'cohortId', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'regionId', referencedColumnName: 'id' }
})
regions: Region[];
@Column({ nullable: true })
tripPurposeId: string;
@ManyToMany(() => TripPurpose)
@JoinTable({
name: 'tbl_cohort_trip_purposes',
joinColumn: { name: 'cohortId', referencedColumnName: 'id' },
inverseJoinColumn: { name: 'tripPurposeId', referencedColumnName: 'id' }
})
tripPurposes: TripPurpose[];
@Column({ nullable: true })
originAirport: string;
@Column('simple-array', { nullable: true })
originAirport: string[];
@Column({ nullable: true })
destinationAirport: string;
@Column('simple-array', { nullable: true })
destinationAirport: string[];
@CreateDateColumn()
createdAt: Date;
+51 -4
View File
@@ -1,6 +1,6 @@
import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Repository, DeepPartial } from 'typeorm';
import { Cohort } from './cohort.entity';
import { CreateCohortDto } from './dto/create-cohort.dto';
import { UpdateCohortDto } from './dto/update-cohort.dto';
@@ -12,8 +12,50 @@ export class CohortService {
private readonly cohortRepository: Repository<Cohort>,
) {}
private mapDtoToEntity(dto: CreateCohortDto | UpdateCohortDto) {
const {
cabinClassIds,
passengerTypeIds,
ancillaryPurchaseIds,
loyaltyTierIds,
revenueSegmentIds,
regionIds,
tripPurposeIds,
originAirports,
destinationAirports,
...rest
} = dto;
const mapping: any = { ...rest };
if (cabinClassIds) mapping.cabinClasses = cabinClassIds.map(id => ({ id }));
if (passengerTypeIds) mapping.passengerTypes = passengerTypeIds.map(id => ({ id }));
if (ancillaryPurchaseIds) mapping.ancillaryPurchases = ancillaryPurchaseIds.map(id => ({ id }));
if (loyaltyTierIds) mapping.loyaltyTiers = loyaltyTierIds.map(id => ({ id }));
if (revenueSegmentIds) mapping.revenueSegments = revenueSegmentIds.map(id => ({ id }));
if (regionIds) mapping.regions = regionIds.map(id => ({ id }));
if (tripPurposeIds) mapping.tripPurposes = tripPurposeIds.map(id => ({ id }));
if (originAirports !== undefined) mapping.originAirport = originAirports;
if (destinationAirports !== undefined) mapping.destinationAirport = destinationAirports;
return mapping as DeepPartial<Cohort>;
}
private getRelations() {
return {
cabinClasses: true,
passengerTypes: true,
ancillaryPurchases: true,
loyaltyTiers: true,
revenueSegments: true,
regions: true,
tripPurposes: true
};
}
async create(createCohortDto: CreateCohortDto): Promise<Cohort> {
const cohort = this.cohortRepository.create(createCohortDto);
const mappedData = this.mapDtoToEntity(createCohortDto);
const cohort = this.cohortRepository.create(mappedData);
return this.cohortRepository.save(cohort);
}
@@ -23,6 +65,7 @@ export class CohortService {
skip,
take: limit,
order: { createdAt: 'DESC' },
relations: this.getRelations(),
});
return {
@@ -35,7 +78,10 @@ export class CohortService {
}
async findOne(id: string): Promise<Cohort> {
const cohort = await this.cohortRepository.findOne({ where: { id } });
const cohort = await this.cohortRepository.findOne({
where: { id },
relations: this.getRelations(),
});
if (!cohort) {
throw new NotFoundException(`Cohort with ID ${id} not found`);
}
@@ -44,7 +90,8 @@ export class CohortService {
async update(id: string, updateCohortDto: UpdateCohortDto): Promise<Cohort> {
const cohort = await this.findOne(id);
Object.assign(cohort, updateCohortDto);
const mappedData = this.mapDtoToEntity(updateCohortDto);
Object.assign(cohort, mappedData);
return this.cohortRepository.save(cohort);
}
+28 -19
View File
@@ -1,4 +1,4 @@
import { IsString, IsNotEmpty, IsOptional } from 'class-validator';
import { IsString, IsNotEmpty, IsOptional, IsArray } from 'class-validator';
export class CreateCohortDto {
@IsString()
@@ -13,25 +13,30 @@ export class CreateCohortDto {
@IsOptional()
status?: string;
@IsString()
@IsArray()
@IsString({ each: true })
@IsOptional()
cabinClassId?: string;
cabinClassIds?: string[];
@IsString()
@IsArray()
@IsString({ each: true })
@IsOptional()
passengerTypeId?: string;
passengerTypeIds?: string[];
@IsString()
@IsArray()
@IsString({ each: true })
@IsOptional()
ancillaryPurchaseId?: string;
ancillaryPurchaseIds?: string[];
@IsString()
@IsArray()
@IsString({ each: true })
@IsOptional()
loyaltyTierId?: string;
loyaltyTierIds?: string[];
@IsString()
@IsArray()
@IsString({ each: true })
@IsOptional()
revenueSegmentId?: string;
revenueSegmentIds?: string[];
@IsString()
@IsOptional()
@@ -41,19 +46,23 @@ export class CreateCohortDto {
@IsOptional()
flightType?: string;
@IsString()
@IsArray()
@IsString({ each: true })
@IsOptional()
regionId?: string;
regionIds?: string[];
@IsString()
@IsArray()
@IsString({ each: true })
@IsOptional()
tripPurposeId?: string;
tripPurposeIds?: string[];
@IsString()
@IsArray()
@IsString({ each: true })
@IsOptional()
originAirport?: string;
originAirports?: string[];
@IsString()
@IsArray()
@IsString({ each: true })
@IsOptional()
destinationAirport?: string;
destinationAirports?: string[];
}