mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-07 20:05:41 +00:00
IAM, package, luggage, app health, rate limit, and more
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { Body, Controller, Get, Param, Post, Patch, UseGuards, Request, Query } from '@nestjs/common';
|
||||
import { Body, Controller, Get, Param, Post, Patch, Delete, UseGuards, Request, Query } from '@nestjs/common';
|
||||
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
|
||||
import { PackagesService } from './packages.service';
|
||||
import { CreatePackageDto, BookPackageDto } from './packages.dto';
|
||||
import { CreatePackageDto, BookPackageDto, CreatePriceTierDto, UpdatePriceTierDto } from './packages.dto';
|
||||
import { JwtGuard } from '../../common/jwt.guard';
|
||||
import { OptionalJwtGuard } from '../verifayda/optional-jwt.guard';
|
||||
|
||||
@@ -52,6 +52,14 @@ export class PackagesController {
|
||||
return this.service.create(dto);
|
||||
}
|
||||
|
||||
@Patch(':id')
|
||||
@UseGuards(JwtGuard)
|
||||
@ApiBearerAuth('JWT-auth')
|
||||
@ApiOperation({ summary: 'Update package (admin)' })
|
||||
update(@Param('id') id: string, @Body() dto: Partial<CreatePackageDto>) {
|
||||
return this.service.update(id, dto);
|
||||
}
|
||||
|
||||
@Patch(':id/activate')
|
||||
@UseGuards(JwtGuard)
|
||||
@ApiBearerAuth('JWT-auth')
|
||||
@@ -60,6 +68,30 @@ export class PackagesController {
|
||||
return this.service.activate(id);
|
||||
}
|
||||
|
||||
@Post(':id/tiers')
|
||||
@UseGuards(JwtGuard)
|
||||
@ApiBearerAuth('JWT-auth')
|
||||
@ApiOperation({ summary: 'Add price tier to package (admin)' })
|
||||
addTier(@Param('id') id: string, @Body() dto: CreatePriceTierDto) {
|
||||
return this.service.addTier(id, dto);
|
||||
}
|
||||
|
||||
@Patch('tiers/:tierId')
|
||||
@UseGuards(JwtGuard)
|
||||
@ApiBearerAuth('JWT-auth')
|
||||
@ApiOperation({ summary: 'Update price tier (admin)' })
|
||||
updateTier(@Param('tierId') tierId: string, @Body() dto: UpdatePriceTierDto) {
|
||||
return this.service.updateTier(tierId, dto);
|
||||
}
|
||||
|
||||
@Delete('tiers/:tierId')
|
||||
@UseGuards(JwtGuard)
|
||||
@ApiBearerAuth('JWT-auth')
|
||||
@ApiOperation({ summary: 'Delete price tier (admin)' })
|
||||
deleteTier(@Param('tierId') tierId: string) {
|
||||
return this.service.deleteTier(tierId);
|
||||
}
|
||||
|
||||
@Post('book')
|
||||
@UseGuards(OptionalJwtGuard)
|
||||
@ApiBearerAuth('JWT-auth')
|
||||
|
||||
@@ -16,6 +16,13 @@ export class CreatePriceTierDto {
|
||||
@IsInt() @Min(0) availableSeats: number;
|
||||
}
|
||||
|
||||
export class UpdatePriceTierDto {
|
||||
@ApiPropertyOptional() @IsOptional() @IsString() seatType?: string;
|
||||
@ApiPropertyOptional() @IsOptional() @IsString() label?: string;
|
||||
@ApiPropertyOptional() @IsOptional() @IsInt() @Min(0) priceMinor?: number;
|
||||
@ApiPropertyOptional() @IsOptional() @IsInt() @Min(0) availableSeats?: number;
|
||||
}
|
||||
|
||||
export class CreatePackageDto {
|
||||
@ApiProperty({ example: 'KULUBBI-2025' })
|
||||
@IsString() code: string;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable, NotFoundException, BadRequestException } from '@nestjs/common';
|
||||
import { PrismaService } from '../../common/prisma.service';
|
||||
import { CurrencyService } from '../currency/currency.service';
|
||||
import { CreatePackageDto, BookPackageDto } from './packages.dto';
|
||||
import { CreatePackageDto, BookPackageDto, UpdatePriceTierDto, CreatePriceTierDto } from './packages.dto';
|
||||
import { Currency } from '@prisma/client';
|
||||
|
||||
function generateRef(): string {
|
||||
@@ -70,6 +70,53 @@ export class PackagesService {
|
||||
});
|
||||
}
|
||||
|
||||
async update(id: string, dto: Partial<CreatePackageDto>) {
|
||||
const pkg = await this.prisma.travelPackage.findUnique({ where: { id } });
|
||||
if (!pkg) throw new NotFoundException('Package not found');
|
||||
return this.prisma.travelPackage.update({
|
||||
where: { id },
|
||||
data: {
|
||||
...(dto.code && { code: dto.code }),
|
||||
...(dto.name && { name: dto.name }),
|
||||
...(dto.description !== undefined && { description: dto.description }),
|
||||
...(dto.outboundScheduleId && { outboundScheduleId: dto.outboundScheduleId }),
|
||||
...(dto.returnScheduleId && { returnScheduleId: dto.returnScheduleId }),
|
||||
...(dto.originStationId && { originStationId: dto.originStationId }),
|
||||
...(dto.destinationStationId && { destinationStationId: dto.destinationStationId }),
|
||||
...(dto.boardingTime && { boardingTime: new Date(dto.boardingTime) }),
|
||||
...(dto.departureTime && { departureTime: new Date(dto.departureTime) }),
|
||||
...(dto.arrivalTime && { arrivalTime: new Date(dto.arrivalTime) }),
|
||||
...(dto.totalCapacity && { totalCapacity: dto.totalCapacity }),
|
||||
...(dto.coachConfiguration !== undefined && { coachConfiguration: dto.coachConfiguration }),
|
||||
...(dto.includedServices && { includedServices: dto.includedServices }),
|
||||
...(dto.busTransferIncluded !== undefined && { busTransferIncluded: dto.busTransferIncluded }),
|
||||
...(dto.busTransferRoute !== undefined && { busTransferRoute: dto.busTransferRoute }),
|
||||
...(dto.validFrom && { validFrom: new Date(dto.validFrom) }),
|
||||
...(dto.validUntil && { validUntil: new Date(dto.validUntil) }),
|
||||
},
|
||||
include: { priceTiers: true },
|
||||
});
|
||||
}
|
||||
|
||||
async addTier(packageId: string, dto: CreatePriceTierDto) {
|
||||
const pkg = await this.prisma.travelPackage.findUnique({ where: { id: packageId } });
|
||||
if (!pkg) throw new NotFoundException('Package not found');
|
||||
return this.prisma.packagePriceTier.create({ data: { ...dto, packageId } });
|
||||
}
|
||||
|
||||
async updateTier(tierId: string, dto: UpdatePriceTierDto) {
|
||||
const tier = await this.prisma.packagePriceTier.findUnique({ where: { id: tierId } });
|
||||
if (!tier) throw new NotFoundException('Price tier not found');
|
||||
return this.prisma.packagePriceTier.update({ where: { id: tierId }, data: dto });
|
||||
}
|
||||
|
||||
async deleteTier(tierId: string) {
|
||||
const tier = await this.prisma.packagePriceTier.findUnique({ where: { id: tierId } });
|
||||
if (!tier) throw new NotFoundException('Price tier not found');
|
||||
if (tier.bookedSeats > 0) throw new BadRequestException('Cannot delete a tier that has bookings');
|
||||
return this.prisma.packagePriceTier.delete({ where: { id: tierId } });
|
||||
}
|
||||
|
||||
async activate(id: string) {
|
||||
const pkg = await this.prisma.travelPackage.findUnique({ where: { id } });
|
||||
if (!pkg) throw new NotFoundException('Package not found');
|
||||
|
||||
Reference in New Issue
Block a user