File

src/vehicles/vehicles.controller.ts

Prefix

vehicles

Index

Methods

Methods

Async bulkUpload
bulkUpload(orgId: string, file: Express.Multer.File)
Decorators :
@Post('upload')
@Roles(undefined)
@ApiOperation({summary: 'Bulk upload vehicles from Excel/CSV'})
@ApiConsumes('multipart/form-data')
@UseInterceptors(undefined)
Parameters :
Name Type Optional
orgId string No
file Express.Multer.File No
Returns : unknown
Async create
create(orgId: string, dto: CreateVehicleDto)
Decorators :
@Post()
@Roles(undefined)
@ApiOperation({summary: 'Create a new vehicle'})
Parameters :
Name Type Optional
orgId string No
dto CreateVehicleDto No
Returns : unknown
Async createClass
createClass(orgId: string, body: literal type)
Decorators :
@Post('classes')
@Roles(undefined)
@ApiOperation({summary: 'Create a vehicle class (e.g. 30T, 10T)'})
Parameters :
Name Type Optional
orgId string No
body literal type No
Returns : unknown
Async deleteClass
deleteClass(orgId: string, id: string)
Decorators :
@Delete('classes/:id')
@Roles(undefined)
@ApiOperation({summary: 'Delete a vehicle class (blocked when vehicles still belong)'})
Parameters :
Name Type Optional
orgId string No
id string No
Returns : unknown
Async findAll
findAll(orgId: string, query: PaginationParams)
Decorators :
@Get()
@ApiPagination()
@ApiOperation({summary: 'List all vehicles (org-scoped)'})
Parameters :
Name Type Optional
orgId string No
query PaginationParams No
Returns : unknown
Async findOne
findOne(orgId: string, id: string)
Decorators :
@Get(':id')
@ApiOperation({summary: 'Get vehicle by ID (org-scoped)'})
Parameters :
Name Type Optional
orgId string No
id string No
Returns : unknown
Async listClasses
listClasses(orgId: string)
Decorators :
@Get('classes/list')
@ApiOperation({summary: 'List vehicle classes (tonnage categories)'})
Parameters :
Name Type Optional
orgId string No
Returns : unknown
Async remove
remove(orgId: string, id: string)
Decorators :
@Delete(':id')
@Roles(undefined)
@ApiOperation({summary: 'Delete a vehicle (blocked when in use by an active trip)'})
Parameters :
Name Type Optional
orgId string No
id string No
Returns : unknown
Async update
update(orgId: string, id: string, dto: UpdateVehicleDto)
Decorators :
@Patch(':id')
@Roles(undefined)
@ApiOperation({summary: 'Update a vehicle (org-scoped)'})
Parameters :
Name Type Optional
orgId string No
id string No
dto UpdateVehicleDto No
Returns : unknown
Async updateClass
updateClass(orgId: string, id: string, body: literal type)
Decorators :
@Patch('classes/:id')
@Roles(undefined)
@ApiOperation({summary: 'Update a vehicle class'})
Parameters :
Name Type Optional
orgId string No
id string No
body literal type No
Returns : unknown
import {
  Controller,
  Get,
  Post,
  Patch,
  Delete,
  Body,
  Param,
  Query,
  UseGuards,
  UseInterceptors,
  UploadedFile,
  BadRequestException,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiTags, ApiBearerAuth, ApiOperation, ApiConsumes } from '@nestjs/swagger';
import { VehiclesService } from './vehicles.service';
import { CreateVehicleDto } from './dto/create-vehicle.dto';
import { UpdateVehicleDto } from './dto/update-vehicle.dto';
import { CombinedAuthGuard } from '../auth/guards/combined-auth.guard';
import { RolesGuard } from '../auth/guards/roles.guard';
import { Roles } from '../auth/decorators/roles.decorator';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { ApiPagination } from '../common/decorators/api-pagination.decorator';
import { PaginationParams } from '../common/utils/pagination.util';

/**
 * Roles allowed to MUTATE the vehicle fleet. Reads stay open to all
 * authenticated staff because dispatchers, expeditors and customer
 * service all need to know what's in the fleet.
 */
const VEHICLE_WRITERS = ['SUPER_ADMIN', 'ADMIN', 'OPERATIONS_MANAGER'] as const;

@ApiTags('Vehicles')
@ApiBearerAuth()
@UseGuards(CombinedAuthGuard, RolesGuard)
@Controller('vehicles')
export class VehiclesController {
  constructor(private readonly vehiclesService: VehiclesService) {}

  @Post()
  @Roles(...VEHICLE_WRITERS)
  @ApiOperation({ summary: 'Create a new vehicle' })
  async create(
    @CurrentUser('organizationId') orgId: string,
    @Body() dto: CreateVehicleDto,
  ) {
    return this.vehiclesService.create(orgId, dto);
  }

  @Get()
  @ApiPagination()
  @ApiOperation({ summary: 'List all vehicles (org-scoped)' })
  async findAll(
    @CurrentUser('organizationId') orgId: string,
    @Query() query: PaginationParams,
  ) {
    return this.vehiclesService.findAll(orgId, query);
  }

  @Get(':id')
  @ApiOperation({ summary: 'Get vehicle by ID (org-scoped)' })
  async findOne(
    @CurrentUser('organizationId') orgId: string,
    @Param('id') id: string,
  ) {
    return this.vehiclesService.findOne(orgId, id);
  }

  @Patch(':id')
  @Roles(...VEHICLE_WRITERS)
  @ApiOperation({ summary: 'Update a vehicle (org-scoped)' })
  async update(
    @CurrentUser('organizationId') orgId: string,
    @Param('id') id: string,
    @Body() dto: UpdateVehicleDto,
  ) {
    return this.vehiclesService.update(orgId, id, dto);
  }

  @Delete(':id')
  @Roles(...VEHICLE_WRITERS)
  @ApiOperation({ summary: 'Delete a vehicle (blocked when in use by an active trip)' })
  async remove(
    @CurrentUser('organizationId') orgId: string,
    @Param('id') id: string,
  ) {
    return this.vehiclesService.remove(orgId, id);
  }

  @Post('upload')
  @Roles(...VEHICLE_WRITERS)
  @ApiOperation({ summary: 'Bulk upload vehicles from Excel/CSV' })
  @ApiConsumes('multipart/form-data')
  @UseInterceptors(FileInterceptor('file', { limits: { fileSize: 10 * 1024 * 1024 } }))
  async bulkUpload(
    @CurrentUser('organizationId') orgId: string,
    @UploadedFile() file: Express.Multer.File,
  ) {
    if (!file) throw new BadRequestException('No file uploaded');
    return this.vehiclesService.bulkUploadFromFile(orgId, file);
  }

  // ── Vehicle Classes ──────────────────────────────────────────────

  @Get('classes/list')
  @ApiOperation({ summary: 'List vehicle classes (tonnage categories)' })
  async listClasses(@CurrentUser('organizationId') orgId: string) {
    return this.vehiclesService.findAllClasses(orgId);
  }

  @Post('classes')
  @Roles(...VEHICLE_WRITERS)
  @ApiOperation({ summary: 'Create a vehicle class (e.g. 30T, 10T)' })
  async createClass(
    @CurrentUser('organizationId') orgId: string,
    @Body() body: { name: string; code: string; tonnage: number; description?: string },
  ) {
    return this.vehiclesService.createClass(orgId, body);
  }

  @Patch('classes/:id')
  @Roles(...VEHICLE_WRITERS)
  @ApiOperation({ summary: 'Update a vehicle class' })
  async updateClass(
    @CurrentUser('organizationId') orgId: string,
    @Param('id') id: string,
    @Body() body: { name?: string; code?: string; tonnage?: number; description?: string },
  ) {
    return this.vehiclesService.updateClass(orgId, id, body);
  }

  @Delete('classes/:id')
  @Roles(...VEHICLE_WRITERS)
  @ApiOperation({ summary: 'Delete a vehicle class (blocked when vehicles still belong)' })
  async deleteClass(
    @CurrentUser('organizationId') orgId: string,
    @Param('id') id: string,
  ) {
    return this.vehiclesService.deleteClass(orgId, id);
  }
}

results matching ""

    No results matching ""