import { Body, Controller, Delete, Get, Param, ParseUUIDPipe, Patch, Post, Query, } from '@nestjs/common'; import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger'; import { BookingStaff } from '../../common/booking-guards'; import { FREIGHT_PERMS } from '../../seed/freight-permissions.registry'; import { GpsTrackingService } from './gps-tracking.service'; import { RegisterDeviceDto, UpdateDeviceDto } from './dto/gps-device.dto'; @ApiTags('gps-tracking') @ApiBearerAuth() @Controller('gps') // Class gate lists every key its routes use: Nest runs class AND method // guards, so a key missing here would deny before the route's own key runs. @BookingStaff([ FREIGHT_PERMS.tracking.view, FREIGHT_PERMS.tracking.manage, ]) export class GpsTrackingController { constructor(private readonly gps: GpsTrackingService) {} @Get('positions/latest') @ApiOperation({ summary: 'Latest fix per device (live map feed)' }) latest() { return this.gps.latest(); } @Get('positions/:vehicleId/history') @ApiOperation({ summary: 'Position history for a vehicle' }) history( @Param('vehicleId', ParseUUIDPipe) vehicleId: string, @Query('limit') limit?: string, ) { return this.gps.history(vehicleId, limit ? parseInt(limit, 10) : undefined); } @Get('devices') @ApiOperation({ summary: 'List GPS trackers' }) listDevices() { return this.gps.listDevices(); } @Post('devices') @BookingStaff(FREIGHT_PERMS.tracking.manage) @ApiOperation({ summary: 'Register a GPS tracker' }) register(@Body() dto: RegisterDeviceDto) { return this.gps.registerDevice(dto); } @Patch('devices/:id') @BookingStaff(FREIGHT_PERMS.tracking.manage) @ApiOperation({ summary: 'Update a GPS tracker (name / assigned vehicle)' }) update(@Param('id', ParseUUIDPipe) id: string, @Body() dto: UpdateDeviceDto) { return this.gps.updateDevice(id, dto); } @Delete('devices/:id') @BookingStaff(FREIGHT_PERMS.tracking.manage) @ApiOperation({ summary: 'Delete a GPS tracker' }) remove(@Param('id', ParseUUIDPipe) id: string) { return this.gps.removeDevice(id); } }