Updated seat class and coach mangement

This commit is contained in:
Roba Boru
2026-05-19 16:49:22 +03:00
parent 071a57a668
commit a73277ae38
23 changed files with 310 additions and 61 deletions

View File

@@ -0,0 +1,40 @@
import { Body, Controller, Get, Param, Patch, Post, UseGuards } from '@nestjs/common';
import { ApiTags, ApiOperation, ApiBearerAuth, ApiParam, ApiResponse, ApiBody } from '@nestjs/swagger';
import { SeatClassesService } from './seat-classes.service';
import { CreateSeatClassDto, UpdateSeatClassDto } from './seat-classes.dto';
import { JwtGuard } from '../../common/jwt.guard';
@ApiTags('Seat Classes')
@Controller('seat-classes')
export class SeatClassesController {
constructor(private service: SeatClassesService) {}
@Get()
@ApiOperation({ summary: 'List all seat classes' })
@ApiResponse({ status: 200, description: 'Returns all seat classes with their coaches' })
listSeatClasses() { return this.service.listSeatClasses(); }
@Get(':id')
@ApiOperation({ summary: 'Get a seat class by ID' })
@ApiParam({ name: 'id', description: 'Seat class UUID' })
@ApiResponse({ status: 200, description: 'Returns seat class with its coaches' })
@ApiResponse({ status: 404, description: 'Seat class not found' })
getSeatClass(@Param('id') id: string) { return this.service.getSeatClass(id); }
@Post()
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
@ApiOperation({ summary: 'Create a seat class' })
@ApiBody({ type: CreateSeatClassDto })
@ApiResponse({ status: 201, description: 'Seat class created' })
@ApiResponse({ status: 409, description: 'Seat class name already exists' })
createSeatClass(@Body() dto: CreateSeatClassDto) { return this.service.createSeatClass(dto); }
@Patch(':id')
@UseGuards(JwtGuard) @ApiBearerAuth('JWT-auth')
@ApiOperation({ summary: 'Update a seat class' })
@ApiParam({ name: 'id', description: 'Seat class UUID' })
@ApiBody({ type: UpdateSeatClassDto })
@ApiResponse({ status: 200, description: 'Seat class updated' })
@ApiResponse({ status: 404, description: 'Seat class not found' })
updateSeatClass(@Param('id') id: string, @Body() dto: UpdateSeatClassDto) { return this.service.updateSeatClass(id, dto); }
}

View File

@@ -0,0 +1,24 @@
import { IsString, IsInt, IsBoolean, IsOptional } from 'class-validator';
import { ApiProperty, ApiPropertyOptional, PartialType } from '@nestjs/swagger';
export class CreateSeatClassDto {
@ApiProperty({ example: 'Economy Seat' })
@IsString()
name: string;
@ApiPropertyOptional({ example: 'Standard economy seating' })
@IsOptional()
@IsString()
description?: string;
@ApiProperty({ example: 45000, description: 'Base price in minor currency units' })
@IsInt()
basePrice: number;
@ApiPropertyOptional({ example: true })
@IsOptional()
@IsBoolean()
isActive?: boolean;
}
export class UpdateSeatClassDto extends PartialType(CreateSeatClassDto) {}

View File

@@ -0,0 +1,6 @@
import { Module } from '@nestjs/common';
import { SeatClassesController } from './seat-classes.controller';
import { SeatClassesService } from './seat-classes.service';
@Module({ controllers: [SeatClassesController], providers: [SeatClassesService], exports: [SeatClassesService] })
export class SeatClassesModule {}

View File

@@ -0,0 +1,40 @@
import { Injectable, NotFoundException, ConflictException } from '@nestjs/common';
import { PrismaService } from '../../common/prisma.service';
import { CreateSeatClassDto, UpdateSeatClassDto } from './seat-classes.dto';
@Injectable()
export class SeatClassesService {
constructor(private prisma: PrismaService) {}
private readonly coachInclude = {
coaches: {
select: { id: true, label: true, tripId: true, _count: { select: { seats: true } } },
orderBy: { label: 'asc' as const },
},
};
listSeatClasses() {
return this.prisma.seatClass.findMany({ orderBy: { createdAt: 'asc' }, include: this.coachInclude });
}
async getSeatClass(id: string) {
const sc = await this.prisma.seatClass.findUnique({ where: { id }, include: this.coachInclude });
if (!sc) throw new NotFoundException('SeatClass not found');
return sc;
}
async createSeatClass(dto: CreateSeatClassDto) {
try {
return await this.prisma.seatClass.create({ data: dto });
} catch (e: any) {
if (e.code === 'P2002') throw new ConflictException(`Seat class "${dto.name}" already exists`);
throw e;
}
}
async updateSeatClass(id: string, dto: UpdateSeatClassDto) {
const sc = await this.prisma.seatClass.findUnique({ where: { id } });
if (!sc) throw new NotFoundException('SeatClass not found');
return this.prisma.seatClass.update({ where: { id }, data: dto, include: this.coachInclude });
}
}