src/tracking/tracking.controller.ts
tracking
Methods |
|
| Async getTripTracking | ||||||
getTripTracking(id: string)
|
||||||
Decorators :
@Get('trips/:id')
|
||||||
|
Defined in src/tracking/tracking.controller.ts:67
|
||||||
|
Parameters :
Returns :
unknown
|
| Async getVehiclePosition | ||||||
getVehiclePosition(id: string)
|
||||||
Decorators :
@Get('vehicles/:id')
|
||||||
|
Defined in src/tracking/tracking.controller.ts:45
|
||||||
|
Parameters :
Returns :
unknown
|
| Async getVehiclePositions | ||||||
getVehiclePositions(orgId: string)
|
||||||
Decorators :
@Get('vehicles')
|
||||||
|
Defined in src/tracking/tracking.controller.ts:35
|
||||||
|
Parameters :
Returns :
unknown
|
| Async getVehicleTrail |
getVehicleTrail(id: string, from: string, to: string)
|
Decorators :
@Get('vehicles/:id/trail')
|
|
Defined in src/tracking/tracking.controller.ts:53
|
|
Returns :
unknown
|
| Async mixTelematicsWebhook |
mixTelematicsWebhook(body: any, secret: string)
|
Decorators :
@SkipThrottle()
|
|
Defined in src/tracking/tracking.controller.ts:99
|
|
Returns :
unknown
|
| Async updatePosition | |||||||||
updatePosition(id: string, body: literal type)
|
|||||||||
Decorators :
@Post('vehicles/:id/position')
|
|||||||||
|
Defined in src/tracking/tracking.controller.ts:76
|
|||||||||
|
Parameters :
Returns :
unknown
|
import {
Controller,
Get,
Post,
Body,
Param,
Query,
UseGuards,
HttpCode,
HttpStatus,
UnauthorizedException,
Logger,
} from '@nestjs/common';
import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger';
import { SkipThrottle } from '@nestjs/throttler';
import { TrackingService } from './tracking.service';
import { TrackingGateway } from './tracking.gateway';
import { CombinedAuthGuard } from '../auth/guards/combined-auth.guard';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
@ApiTags('Tracking')
@Controller('tracking')
export class TrackingController {
private readonly logger = new Logger(TrackingController.name);
constructor(
private readonly trackingService: TrackingService,
private readonly trackingGateway: TrackingGateway,
) {}
@Get('vehicles')
@ApiBearerAuth()
@UseGuards(CombinedAuthGuard)
@ApiOperation({ summary: 'Get all vehicle positions for the organization' })
async getVehiclePositions(
@CurrentUser('organizationId') orgId: string,
) {
return this.trackingService.getVehiclePositions(orgId);
}
@Get('vehicles/:id')
@ApiBearerAuth()
@UseGuards(CombinedAuthGuard)
@ApiOperation({ summary: 'Get single vehicle position with recent trail' })
async getVehiclePosition(@Param('id') id: string) {
return this.trackingService.getVehiclePosition(id);
}
@Get('vehicles/:id/trail')
@ApiBearerAuth()
@UseGuards(CombinedAuthGuard)
@ApiOperation({ summary: 'Get GPS trail for a vehicle in a time range' })
async getVehicleTrail(
@Param('id') id: string,
@Query('from') from: string,
@Query('to') to: string,
) {
const fromDate = from ? new Date(from) : new Date(Date.now() - 24 * 60 * 60 * 1000);
const toDate = to ? new Date(to) : new Date();
return this.trackingService.getVehicleTrail(id, fromDate, toDate);
}
@Get('trips/:id')
@ApiBearerAuth()
@UseGuards(CombinedAuthGuard)
@ApiOperation({ summary: 'Get trip tracking data with ETA' })
async getTripTracking(@Param('id') id: string) {
return this.trackingService.getTripTracking(id);
}
@Post('vehicles/:id/position')
@ApiBearerAuth()
@UseGuards(CombinedAuthGuard)
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Manually update vehicle position (testing/demo)' })
async updatePosition(
@Param('id') id: string,
@Body() body: { lat: number; lng: number; speed: number; heading: number },
) {
const position = await this.trackingService.updateVehiclePosition(
id,
body.lat,
body.lng,
body.speed,
body.heading,
'manual',
);
// Broadcast via WebSocket
this.trackingGateway.broadcastPosition(id, position);
return position;
}
@SkipThrottle()
@Post('webhook/mix-telematics')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Webhook for Mix Telematics position updates' })
async mixTelematicsWebhook(
@Body() body: any,
@Query('secret') secret: string,
) {
const webhookSecret = process.env.MIX_TELEMATICS_WEBHOOK_SECRET;
if (!webhookSecret || secret !== webhookSecret) {
throw new UnauthorizedException('Invalid webhook secret');
}
this.logger.log(
`Mix Telematics webhook received: ${Array.isArray(body) ? body.length : 1} events`,
);
// Process position updates from webhook payload
const events = Array.isArray(body) ? body : [body];
for (const event of events) {
try {
if (event.vehicleId && event.lat !== undefined && event.lng !== undefined) {
const position = await this.trackingService.updateVehiclePosition(
event.vehicleId,
event.lat,
event.lng,
event.speed || 0,
event.heading || 0,
'mix_telematics',
);
// Broadcast to connected WebSocket clients
this.trackingGateway.broadcastPosition(event.vehicleId, position);
}
} catch (err: any) {
this.logger.error(
`Failed to process webhook event for vehicle ${event.vehicleId}: ${err.message}`,
);
}
}
return { received: events.length };
}
}