import { Body, Controller, Get, Param, ParseIntPipe, Post, Query, UseGuards, } from '@nestjs/common'; import { IsLatitude, IsLongitude, IsOptional, IsString, MaxLength, } from 'class-validator'; import { Type } from 'class-transformer'; import { SightingsService } from './sightings.service'; import { CurrentUser, JwtAuthGuard, type JwtPayload } from '../auth/roles'; class CreateSightingDto { @Type(() => Number) @IsLatitude() lat!: number; @Type(() => Number) @IsLongitude() lng!: number; @IsOptional() @IsString() @MaxLength(60) station?: string; @IsOptional() @IsString() @MaxLength(20) spottedAt?: string; @IsOptional() @IsString() @MaxLength(40) carNumber?: string; @IsOptional() @IsString() @MaxLength(300) description?: string; } @Controller('api') export class SightingsController { constructor(private readonly sightings: SightingsService) {} @Get('models/:id/sightings') forModel(@Param('id', ParseIntPipe) id: number) { return this.sightings.listForModel(id); } @Post('models/:id/sightings') @UseGuards(JwtAuthGuard) create( @Param('id', ParseIntPipe) id: number, @Body() dto: CreateSightingDto, @CurrentUser() user: JwtPayload, ) { return this.sightings.create(user.sub, id, dto); } @Get('sightings/recent') recent(@Query('limit') limit?: string) { return this.sightings.recent(limit ? Number(limit) : 30); } @Get('sightings/map') map() { return this.sightings.mapPoints(); } @Get('sightings/spots') spots() { return this.sightings.spots(); } }