This commit is contained in:
Roba Boru
2026-07-11 01:10:01 +03:00
17 changed files with 79 additions and 29 deletions

View File

@@ -3,6 +3,7 @@ import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { AgentsService } from './agents.service'; import { AgentsService } from './agents.service';
import { CreateAgentDto, CreateAgentBookingDto, OpenShiftDto, CloseShiftDto } from './agents.dto'; import { CreateAgentDto, CreateAgentBookingDto, OpenShiftDto, CloseShiftDto } from './agents.dto';
import { JwtGuard as IamJwtGuard } from '@tria-plc/api-common/modules/auth/services/jwt.guard'; import { JwtGuard as IamJwtGuard } from '@tria-plc/api-common/modules/auth/services/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Agents') @ApiTags('Agents')
@Controller('agents') @Controller('agents')
@@ -36,6 +37,8 @@ export class AgentsController {
} }
@Delete(':id') @Delete(':id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete agent profile' }) @ApiOperation({ summary: 'Delete agent profile' })
deleteAgent(@Param('id') id: string) { deleteAgent(@Param('id') id: string) {
return this.service.deleteAgent(id); return this.service.deleteAgent(id);

View File

@@ -7,6 +7,7 @@ import { GuestBookingService } from './guest-booking.service';
import { CreateBookingDto, ModifyBookingDto, CancelBookingDto } from './bookings.dto'; import { CreateBookingDto, ModifyBookingDto, CancelBookingDto } from './bookings.dto';
import { CreateGuestBookingDto, GetSavedPassengersDto } from './guest-booking.dto'; import { CreateGuestBookingDto, GetSavedPassengersDto } from './guest-booking.dto';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Booking') @ApiTags('Booking')
@Controller('bookings') @Controller('bookings')
@@ -466,7 +467,8 @@ export class BookingsController {
} }
@Delete(':id') @Delete(':id')
@SetMetadata('isPublic', true) @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ @ApiOperation({
description: 'Permanently deletes a booking record' description: 'Permanently deletes a booking record'
}) })

View File

@@ -1,5 +1,5 @@
import { Controller, Get, Post, Patch, Delete, Body, Param, HttpCode } from '@nestjs/common'; import { Body, Controller, Delete, Get, HttpCode, Param, Patch, Post, UseGuards } from '@nestjs/common';
import { ApiTags, ApiBearerAuth } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { CurrenciesService } from './currencies.service'; import { CurrenciesService } from './currencies.service';
import { CreateCurrencyDto, UpdateCurrencyDto } from './currencies.dto'; import { CreateCurrencyDto, UpdateCurrencyDto } from './currencies.dto';
import { PassengerAdmin, PassengerStaff } from '../../common/passenger-guards'; import { PassengerAdmin, PassengerStaff } from '../../common/passenger-guards';
@@ -31,7 +31,7 @@ export class CurrenciesController {
} }
@Delete(':id') @Delete(':id')
@PassengerStaff(PASSENGER_PERMS.currencies.manage) @PassengerAdmin()
@ApiBearerAuth('IAM-auth') @ApiBearerAuth('IAM-auth')
deleteCurrency(@Param('id') id: string) { deleteCurrency(@Param('id') id: string) {
return this.currenciesService.deleteCurrency(id); return this.currenciesService.deleteCurrency(id);

View File

@@ -8,6 +8,7 @@ import {
InitiateExcessPaymentDto, InitiateExcessPaymentDto,
} from './excess-baggage.dto'; } from './excess-baggage.dto';
import { JwtGuard as IamJwtGuard } from '@tria-plc/api-common/modules/auth/services/jwt.guard'; import { JwtGuard as IamJwtGuard } from '@tria-plc/api-common/modules/auth/services/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
class UpsertBaggageAllowanceDto { class UpsertBaggageAllowanceDto {
@IsString() seatClassId: string; @IsString() seatClassId: string;
@@ -70,6 +71,8 @@ export class ExcessBaggageAgentController {
} }
@Delete('allowances/:id') @Delete('allowances/:id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete baggage allowance rule' }) @ApiOperation({ summary: 'Delete baggage allowance rule' })
deleteAllowance(@Param('id') id: string) { deleteAllowance(@Param('id') id: string) {
return this.service.deleteAllowance(id); return this.service.deleteAllowance(id);
@@ -94,6 +97,8 @@ export class ExcessBaggageAgentController {
} }
@Delete(':id') @Delete(':id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete excess baggage charge (admin only)' }) @ApiOperation({ summary: 'Delete excess baggage charge (admin only)' })
deleteCharge(@Param('id') id: string) { deleteCharge(@Param('id') id: string) {
return this.service.deleteCharge(id); return this.service.deleteCharge(id);

View File

@@ -1,9 +1,10 @@
import { Body, Controller, Delete, Get, Param, Patch, Put, Post } from '@nestjs/common'; import { Body, Controller, Delete, Get, Param, Patch, Put, Post } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiParam, ApiProperty, ApiResponse } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiParam, ApiProperty, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
import { CurrencyService } from '../currency/currency.service'; import { CurrencyService } from '../currency/currency.service';
import { UpsertExchangeRateDto } from './currency.dto'; import { UpsertExchangeRateDto } from './currency.dto';
import { IsNumber, IsPositive, IsOptional, IsString } from 'class-validator'; import { IsNumber, IsPositive, IsOptional, IsString } from 'class-validator';
import { Type } from 'class-transformer'; import { Type } from 'class-transformer';
import { PassengerAdmin } from '../../common/passenger-guards';
class UpdateExchangeRateDto { class UpdateExchangeRateDto {
@ApiProperty({ example: 3.5 }) @Type(() => Number) @IsNumber() @IsPositive() rate: number; @ApiProperty({ example: 3.5 }) @Type(() => Number) @IsNumber() @IsPositive() rate: number;
@@ -38,6 +39,8 @@ export class CurrencyController {
} }
@Delete(':id') @Delete(':id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete an exchange rate record by ID' }) @ApiOperation({ summary: 'Delete an exchange rate record by ID' })
@ApiParam({ name: 'id', description: 'CurrencyExchangeRate UUID' }) @ApiParam({ name: 'id', description: 'CurrencyExchangeRate UUID' })
@ApiResponse({ status: 200, description: 'Rate deleted' }) @ApiResponse({ status: 200, description: 'Rate deleted' })

View File

@@ -3,6 +3,7 @@ import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiBody, ApiR
import { FleetService } from './fleet.service'; import { FleetService } from './fleet.service';
import { CreateTrainDto, CreateCoachDto, UpdateCoachDto, AssignCoachDto, ListCoachesDto, CreateCoachTypeDto, UpdateCoachTypeDto, CreateClassDto, UpdateClassDto, GenerateSeatMapDto } from './fleet.dto'; import { CreateTrainDto, CreateCoachDto, UpdateCoachDto, AssignCoachDto, ListCoachesDto, CreateCoachTypeDto, UpdateCoachTypeDto, CreateClassDto, UpdateClassDto, GenerateSeatMapDto } from './fleet.dto';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Fleet') @ApiTags('Fleet')
@Controller('fleet') @Controller('fleet')
@@ -38,6 +39,8 @@ export class FleetController {
} }
@Delete('coach-types/:id') @Delete('coach-types/:id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a coach type' }) @ApiOperation({ summary: 'Delete a coach type' })
@ApiParam({ name: 'id', description: 'Coach Type UUID' }) @ApiParam({ name: 'id', description: 'Coach Type UUID' })
@ApiResponse({ status: 200, description: 'Coach type deleted' }) @ApiResponse({ status: 200, description: 'Coach type deleted' })
@@ -74,6 +77,8 @@ export class FleetController {
} }
@Delete('classes/:id') @Delete('classes/:id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a class' }) @ApiOperation({ summary: 'Delete a class' })
@ApiParam({ name: 'id', description: 'Class UUID' }) @ApiParam({ name: 'id', description: 'Class UUID' })
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' }) @ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
@@ -111,6 +116,8 @@ export class FleetController {
} }
@Delete('seat-classes/:id') @Delete('seat-classes/:id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a class (DEPRECATED - use /fleet/classes)' }) @ApiOperation({ summary: 'Delete a class (DEPRECATED - use /fleet/classes)' })
@ApiParam({ name: 'id', description: 'Class UUID' }) @ApiParam({ name: 'id', description: 'Class UUID' })
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' }) @ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
@@ -147,6 +154,8 @@ export class FleetController {
} }
@Delete('trains/:id') @Delete('trains/:id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a train service' }) @ApiOperation({ summary: 'Delete a train service' })
@ApiParam({ name: 'id', description: 'Train UUID' }) @ApiParam({ name: 'id', description: 'Train UUID' })
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' }) @ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
@@ -310,6 +319,8 @@ export class FleetController {
} }
@Delete('coaches/:id') @Delete('coaches/:id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a coach' }) @ApiOperation({ summary: 'Delete a coach' })
@ApiParam({ name: 'id', description: 'Coach UUID' }) @ApiParam({ name: 'id', description: 'Coach UUID' })
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' }) @ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
@@ -329,6 +340,8 @@ export class FleetController {
} }
@Delete('assignments/:id') @Delete('assignments/:id')
@PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Remove a coach assignment' }) @ApiOperation({ summary: 'Remove a coach assignment' })
@ApiParam({ name: 'id', description: 'Assignment UUID' }) @ApiParam({ name: 'id', description: 'Assignment UUID' })
@ApiResponse({ status: 200, description: 'Assignment removed' }) @ApiResponse({ status: 200, description: 'Assignment removed' })

View File

@@ -6,6 +6,7 @@ import { CreatePackageDto, BookPackageDto, CreatePriceTierDto, UpdatePriceTierDt
import { IamGuard } from '../../common/iam-adapter'; import { IamGuard } from '../../common/iam-adapter';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { OptionalJwtGuard } from '../verifayda/optional-jwt.guard'; import { OptionalJwtGuard } from '../verifayda/optional-jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Packages') @ApiTags('Packages')
@Controller('packages') @Controller('packages')
@@ -41,7 +42,7 @@ export class PackagesController {
} }
@Delete('inquiries/:id') @Delete('inquiries/:id')
@UseGuards(IamGuard) @PassengerAdmin()
@ApiBearerAuth('IAM-auth') @ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete inquiry (backoffice)' }) @ApiOperation({ summary: 'Delete inquiry (backoffice)' })
deleteInquiry(@Param('id') id: string) { deleteInquiry(@Param('id') id: string) {
@@ -139,7 +140,7 @@ export class PackagesController {
} }
@Delete(':id') @Delete(':id')
@UseGuards(IamGuard) @PassengerAdmin()
@ApiBearerAuth('IAM-auth') @ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete package (admin)' }) @ApiOperation({ summary: 'Delete package (admin)' })
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete even with active bookings' }) @ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete even with active bookings' })
@@ -180,7 +181,7 @@ export class PackagesController {
} }
@Delete('tiers/:tierId') @Delete('tiers/:tierId')
@UseGuards(IamGuard) @PassengerAdmin()
@ApiBearerAuth('IAM-auth') @ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete price tier (admin)' }) @ApiOperation({ summary: 'Delete price tier (admin)' })
deleteTier(@Param('tierId') tierId: string) { deleteTier(@Param('tierId') tierId: string) {

View File

@@ -4,6 +4,7 @@ import { SkipThrottle, Throttle } from '@nestjs/throttler';
import { PassengersService } from './passengers.service'; import { PassengersService } from './passengers.service';
import { CreateTravelerProfileDto, CreateSavedRouteDto, VerifyFaydaDto, SavePassengersDto, RegisterPassengerDto } from './passengers.dto'; import { CreateTravelerProfileDto, CreateSavedRouteDto, VerifyFaydaDto, SavePassengersDto, RegisterPassengerDto } from './passengers.dto';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
import { VerifaydaService } from '../verifayda/verifayda.service'; import { VerifaydaService } from '../verifayda/verifayda.service';
import { OptionalJwtGuard } from '../verifayda/optional-jwt.guard'; import { OptionalJwtGuard } from '../verifayda/optional-jwt.guard';
import { PrismaService } from '../../common/prisma.service'; import { PrismaService } from '../../common/prisma.service';
@@ -503,7 +504,8 @@ Returns saved passenger details with generated IDs and confirmation.`,
} }
@Delete(':id') @Delete(':id')
@SetMetadata('isPublic', true) @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ @ApiOperation({
summary: 'Delete passenger (admin only)', summary: 'Delete passenger (admin only)',
description: 'Permanently deletes a passenger record and associated data' description: 'Permanently deletes a passenger record and associated data'

View File

@@ -3,6 +3,7 @@ import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { PromosService } from './promos.service'; import { PromosService } from './promos.service';
import { CreatePromotionDto } from './promos.dto'; import { CreatePromotionDto } from './promos.dto';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Promotions') @ApiTags('Promotions')
@Controller('promos') @Controller('promos')
@@ -64,8 +65,8 @@ export class PromosController {
} }
@Delete(':id') @Delete(':id')
@UseGuards(JwtGuard) @PassengerAdmin()
@ApiBearerAuth('JWT-auth') @ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete promo (admin)' }) @ApiOperation({ summary: 'Delete promo (admin)' })
delete(@Param('id') id: string) { delete(@Param('id') id: string) {
return this.service.delete(id); return this.service.delete(id);

View File

@@ -3,6 +3,7 @@ import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiQuery, ApiResponse }
import { RoutesService } from './routes.service'; import { RoutesService } from './routes.service';
import { CreateRouteDto, AddRouteStopDto, UpdateRouteDto, SetRouteCoachTemplateDto } from './routes.dto'; import { CreateRouteDto, AddRouteStopDto, UpdateRouteDto, SetRouteCoachTemplateDto } from './routes.dto';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Routes') @ApiTags('Routes')
@Controller('routes') @Controller('routes')
@@ -48,7 +49,8 @@ Route stops carry distanceKm for fare-by-distance calculations.`,
updateRoute(@Param('id') id: string, @Body() dto: UpdateRouteDto) { return this.service.updateRoute(id, dto); } updateRoute(@Param('id') id: string, @Body() dto: UpdateRouteDto) { return this.service.updateRoute(id, dto); }
@Delete(':id') @Delete(':id')
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a route' }) @ApiOperation({ summary: 'Delete a route' })
@ApiParam({ name: 'id', description: 'Route UUID' }) @ApiParam({ name: 'id', description: 'Route UUID' })
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' }) @ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
@@ -75,7 +77,8 @@ Route stops carry distanceKm for fare-by-distance calculations.`,
addStop(@Param('id') id: string, @Body() dto: AddRouteStopDto) { return this.service.addStop(id, dto); } addStop(@Param('id') id: string, @Body() dto: AddRouteStopDto) { return this.service.addStop(id, dto); }
@Delete(':id/stops/:sequence') @Delete(':id/stops/:sequence')
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Remove a stop from a route by sequence number' }) @ApiOperation({ summary: 'Remove a stop from a route by sequence number' })
@ApiParam({ name: 'id', description: 'Route UUID' }) @ApiParam({ name: 'id', description: 'Route UUID' })
@ApiParam({ name: 'sequence', description: 'Stop sequence number to remove' }) @ApiParam({ name: 'sequence', description: 'Stop sequence number to remove' })
@@ -119,7 +122,8 @@ Route stops carry distanceKm for fare-by-distance calculations.`,
} }
@Delete(':id/coaches') @Delete(':id/coaches')
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Clear the default coach lineup for this route' }) @ApiOperation({ summary: 'Clear the default coach lineup for this route' })
@ApiParam({ name: 'id', description: 'Route UUID' }) @ApiParam({ name: 'id', description: 'Route UUID' })
@ApiResponse({ status: 200, description: 'Template cleared' }) @ApiResponse({ status: 200, description: 'Template cleared' })

View File

@@ -4,6 +4,7 @@ import { IsPublic } from '@tria-plc/api-common/modules/auth/decorators/public.de
import { SchedulesService } from './schedules.service'; import { SchedulesService } from './schedules.service';
import { CreateScheduleDto, UpdateScheduleDto, CreateFareRuleDto, UpdateScheduleStatusDto, UpdateStopTimeDto, ListSchedulesDto, BulkCreateSchedulesDto, BulkSchedulesResponseDto, TripStatus } from './schedules.dto'; import { CreateScheduleDto, UpdateScheduleDto, CreateFareRuleDto, UpdateScheduleStatusDto, UpdateStopTimeDto, ListSchedulesDto, BulkCreateSchedulesDto, BulkSchedulesResponseDto, TripStatus } from './schedules.dto';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Schedule') @ApiTags('Schedule')
@Controller('schedules') @Controller('schedules')
@@ -56,7 +57,8 @@ export class SchedulesController {
} }
@Delete('fares/:id') @Delete('fares/:id')
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a fare rule' }) @ApiOperation({ summary: 'Delete a fare rule' })
@ApiParam({ name: 'id', description: 'FareRule UUID' }) @ApiParam({ name: 'id', description: 'FareRule UUID' })
@ApiResponse({ status: 200, description: 'Fare rule deleted' }) @ApiResponse({ status: 200, description: 'Fare rule deleted' })
@@ -80,7 +82,8 @@ export class SchedulesController {
updateSegmentFareRule(@Param('id') id: string, @Body() dto: any) { return this.service.updateSegmentFareRule(id, dto); } updateSegmentFareRule(@Param('id') id: string, @Body() dto: any) { return this.service.updateSegmentFareRule(id, dto); }
@Delete('segment-fares/:id') @Delete('segment-fares/:id')
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a segment fare rule' }) @ApiOperation({ summary: 'Delete a segment fare rule' })
@ApiParam({ name: 'id', description: 'SegmentFareRule UUID' }) @ApiParam({ name: 'id', description: 'SegmentFareRule UUID' })
deleteSegmentFareRule(@Param('id') id: string) { return this.service.deleteSegmentFareRule(id); } deleteSegmentFareRule(@Param('id') id: string) { return this.service.deleteSegmentFareRule(id); }
@@ -110,7 +113,8 @@ export class SchedulesController {
} }
@Delete(':id') @Delete(':id')
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a schedule' }) @ApiOperation({ summary: 'Delete a schedule' })
@ApiParam({ name: 'id', description: 'TrainSchedule UUID' }) @ApiParam({ name: 'id', description: 'TrainSchedule UUID' })
@ApiQuery({ name: 'cascade', required: false, type: Boolean }) @ApiQuery({ name: 'cascade', required: false, type: Boolean })
@@ -203,7 +207,8 @@ export class SchedulesController {
getAssignedCoaches(@Param('id') id: string) { return this.service.getAssignedCoaches(id); } getAssignedCoaches(@Param('id') id: string) { return this.service.getAssignedCoaches(id); }
@Delete(':id/coaches/:coachId') @Delete(':id/coaches/:coachId')
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Remove a coach assignment' }) @ApiOperation({ summary: 'Remove a coach assignment' })
@ApiParam({ name: 'id', description: 'TrainSchedule UUID' }) @ApiParam({ name: 'id', description: 'TrainSchedule UUID' })
@ApiParam({ name: 'coachId', description: 'Coach UUID' }) @ApiParam({ name: 'coachId', description: 'Coach UUID' })

View File

@@ -4,6 +4,7 @@ import { IsPublic } from '@tria-plc/api-common/modules/auth/decorators/public.de
import { SeatClassesService } from './seat-classes.service'; import { SeatClassesService } from './seat-classes.service';
import { CreateSeatClassDto, UpdateSeatClassDto } from './seat-classes.dto'; import { CreateSeatClassDto, UpdateSeatClassDto } from './seat-classes.dto';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Seat Classes') @ApiTags('Seat Classes')
@Controller('seat-classes') @Controller('seat-classes')
@@ -42,7 +43,8 @@ export class SeatClassesController {
updateSeatClass(@Param('id') id: string, @Body() dto: UpdateSeatClassDto) { return this.service.updateSeatClass(id, dto); } updateSeatClass(@Param('id') id: string, @Body() dto: UpdateSeatClassDto) { return this.service.updateSeatClass(id, dto); }
@Delete(':id') @Delete(':id')
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth') @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete a seat class' }) @ApiOperation({ summary: 'Delete a seat class' })
@ApiParam({ name: 'id', description: 'Seat class UUID' }) @ApiParam({ name: 'id', description: 'Seat class UUID' })
@ApiResponse({ status: 200, description: 'Seat class deleted' }) @ApiResponse({ status: 200, description: 'Seat class deleted' })

View File

@@ -29,6 +29,11 @@ export class CreateSeatClassDto {
@IsInt() @IsInt()
basePrice: number; basePrice: number;
@ApiPropertyOptional({ example: 1200, description: 'Flat insurance fee in minor units' })
@IsOptional()
@IsInt()
insuranceFeeMinor?: number;
@ApiPropertyOptional({ example: true }) @ApiPropertyOptional({ example: true })
@IsOptional() @IsOptional()
@IsBoolean() @IsBoolean()

View File

@@ -4,6 +4,7 @@ import { IsPublic } from '@tria-plc/api-common/modules/auth/decorators/public.de
import { StationsService } from './stations.service'; import { StationsService } from './stations.service';
import { CreateStationDto } from './stations.dto'; import { CreateStationDto } from './stations.dto';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Stations') @ApiTags('Stations')
@Controller('stations') @Controller('stations')
@@ -133,8 +134,8 @@ export class StationsController {
} }
@Delete(':id') @Delete(':id')
@UseGuards(JwtGuard) @PassengerAdmin()
@ApiBearerAuth('JWT-auth') @ApiBearerAuth('IAM-auth')
@ApiOperation({ summary: 'Delete station' }) @ApiOperation({ summary: 'Delete station' })
@ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' }) @ApiQuery({ name: 'cascade', required: false, type: Boolean, description: 'Force delete with all related data' })
@ApiResponse({ status: 200, description: 'Station deleted successfully' }) @ApiResponse({ status: 200, description: 'Station deleted successfully' })

View File

@@ -2,6 +2,7 @@ import { Body, Controller, Get, Param, Post, Query, UseGuards, Delete, Patch, Se
import { ApiTags, ApiOperation, ApiBearerAuth, ApiBody, ApiQuery } from '@nestjs/swagger'; import { ApiTags, ApiOperation, ApiBearerAuth, ApiBody, ApiQuery } from '@nestjs/swagger';
import { TicketsService } from './tickets.service'; import { TicketsService } from './tickets.service';
import { JwtGuard } from '../../common/jwt.guard'; import { JwtGuard } from '../../common/jwt.guard';
import { PassengerAdmin } from '../../common/passenger-guards';
@ApiTags('Tickets') @ApiTags('Tickets')
@Controller('tickets') @Controller('tickets')
@@ -9,7 +10,8 @@ export class TicketsController {
constructor(private service: TicketsService) {} constructor(private service: TicketsService) {}
@Post('generate/:bookingId') @Post('generate/:bookingId')
@SetMetadata('isPublic', true) @PassengerAdmin()
@ApiBearerAuth('IAM-auth')
@ApiOperation({ @ApiOperation({
summary: 'Generate ticket for booking (confirmation page)', summary: 'Generate ticket for booking (confirmation page)',
description: 'Creates a ticket when confirmation page is reached and permanently holds all associated seats with SeatBlock records.' description: 'Creates a ticket when confirmation page is reached and permanently holds all associated seats with SeatBlock records.'

View File

@@ -406,6 +406,7 @@ export default function TariffRatesPage() {
name="insuranceFeeMinor" name="insuranceFeeMinor"
className="input" className="input"
defaultValue={editingClass ? (editingClass.insuranceFeeMinor / 100).toFixed(2) : '0.00'} defaultValue={editingClass ? (editingClass.insuranceFeeMinor / 100).toFixed(2) : '0.00'}
key={editingClass?.id ?? 'new-insurance'}
min="0" min="0"
step="0.01" step="0.01"
placeholder="e.g. 25.00" placeholder="e.g. 25.00"

View File

@@ -90,21 +90,21 @@ const navigationSections: { title: string; items: NavItem[] }[] = [
{ {
title: 'Financial', title: 'Financial',
items: [ items: [
{ name: 'Pricing & Fares', href: '/pricing', icon: DollarSign, permission: PERMS.admin }, // { name: 'Pricing & Fares', href: '/pricing', icon: DollarSign, permission: PERMS.admin },
{ name: 'Tariff Rates', href: '/tariff-rates', icon: Banknote, permission: PERMS.admin }, { name: 'Tariff Rates', href: '/tariff-rates', icon: Banknote, permission: PERMS.admin },
{ name: 'Fare Rules', href: '/fare-management', icon: Settings, permission: PERMS.admin }, // { name: 'Fare Rules', href: '/fare-management', icon: Settings, permission: PERMS.admin },
{ name: 'Payments', href: '/payments', icon: CreditCard, permission: PERMS.payments.view }, { name: 'Payments', href: '/payments', icon: CreditCard, permission: PERMS.payments.view },
{ name: 'Currencies', href: '/currencies', icon: Banknote, permission: PERMS.currencies.manage }, { name: 'Currencies', href: '/currencies', icon: Banknote, permission: PERMS.currencies.manage },
{ name: 'Promo Codes', href: '/promos', icon: Gift, permission: PERMS.admin }, // { name: 'Promo Codes', href: '/promos', icon: Gift, permission: PERMS.admin },
{ name: 'Payment Methods', href: '/payment-methods', icon: CreditCard, permission: PERMS.payments.view }, { name: 'Payment Methods', href: '/payment-methods', icon: CreditCard, permission: PERMS.payments.view },
{ name: 'Wallet Accounts', href: '/wallet-accounts', icon: Wallet, permission: PERMS.payments.view }, // { name: 'Wallet Accounts', href: '/wallet-accounts', icon: Wallet, permission: PERMS.payments.view },
] ]
}, },
{ {
title: 'Customer Services', title: 'Customer Services',
items: [ items: [
{ name: 'Loyalty Program', href: '/loyalty', icon: Gift, permission: PERMS.passengers.view }, // { name: 'Loyalty Program', href: '/loyalty', icon: Gift, permission: PERMS.passengers.view },
{ name: 'Support Center', href: '/support', icon: MessageSquare, permission: PERMS.bookings.view }, // { name: 'Support Center', href: '/support', icon: MessageSquare, permission: PERMS.bookings.view },
{ name: 'Notifications', href: '/notifications', icon: Bell, permission: PERMS.notifications.send }, { name: 'Notifications', href: '/notifications', icon: Bell, permission: PERMS.notifications.send },
] ]
}, },
@@ -126,7 +126,7 @@ const navigationSections: { title: string; items: NavItem[] }[] = [
{ {
title: 'System', title: 'System',
items: [ items: [
{ name: 'Agents', href: '/agents', icon: Briefcase, permission: PERMS.agents.view }, // { name: 'Agents', href: '/agents', icon: Briefcase, permission: PERMS.agents.view },
{ name: 'Users', href: '/settings/users', icon: Users, permission: PERMS.admin }, { name: 'Users', href: '/settings/users', icon: Users, permission: PERMS.admin },
{ name: 'Settings', href: '/settings', icon: Settings, permission: PERMS.admin }, { name: 'Settings', href: '/settings', icon: Settings, permission: PERMS.admin },
{ name: 'Health', href: '/health', icon: Activity, permission: PERMS.admin }, { name: 'Health', href: '/health', icon: Activity, permission: PERMS.admin },