mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-09-04 20:43:40 +00:00
Nest runs class and method guards together, so a class gate naming only the view key silently required view AND action. Staff granted just an action were denied before their key was checked. Each class gate now names every key its routes use, and FleetView accepts an array so the fleet controllers keep their coarse fallback. Drops the one-off grant mapping SQL with it: already applied to dev, and this fix removes the companion-view rule that was its recurring part.
87 lines
2.9 KiB
TypeScript
87 lines
2.9 KiB
TypeScript
import {
|
|
Controller,
|
|
Post,
|
|
Get,
|
|
Patch,
|
|
Delete,
|
|
Body,
|
|
Param,
|
|
Query,
|
|
} from '@nestjs/common';
|
|
import { ApiBearerAuth, ApiTags, ApiOperation } from '@nestjs/swagger';
|
|
import { BookingStaff } from '../../common/booking-guards';
|
|
import { FREIGHT_PERMS } from '../../seed/freight-permissions.registry';
|
|
import { IncidentsService } from './incidents.service';
|
|
import { CreateIncidentDto } from './dto/create-incident.dto';
|
|
import { UpdateIncidentDto } from './dto/update-incident.dto';
|
|
import { IncidentStatus, IncidentType } from './entities/incident.entity';
|
|
|
|
@ApiTags('Accident & Incident Management')
|
|
@ApiBearerAuth()
|
|
@Controller('incidents')
|
|
// No incidents-specific permission exists in the registry, so this reuses the
|
|
// (real) drivers.* fleet-road keys — incident records are driver-safety data
|
|
// (driver stats / incident history). TODO: add a dedicated incidents:* key.
|
|
// 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.drivers.view,
|
|
FREIGHT_PERMS.drivers.create,
|
|
FREIGHT_PERMS.drivers.update,
|
|
FREIGHT_PERMS.drivers.delete,
|
|
])
|
|
export class IncidentsController {
|
|
constructor(private readonly incidentsService: IncidentsService) {}
|
|
|
|
@Post()
|
|
@BookingStaff(FREIGHT_PERMS.drivers.create)
|
|
@ApiOperation({ summary: 'Report an incident' })
|
|
async create(@Body() dto: CreateIncidentDto) {
|
|
return this.incidentsService.create(dto);
|
|
}
|
|
|
|
@Get()
|
|
@ApiOperation({ summary: 'List incidents (optionally filtered)' })
|
|
async findAll(
|
|
@Query('vehicleId') vehicleId?: string,
|
|
@Query('driverId') driverId?: string,
|
|
@Query('status') status?: IncidentStatus,
|
|
@Query('type') type?: IncidentType,
|
|
) {
|
|
return this.incidentsService.findAll({ vehicleId, driverId, status, type });
|
|
}
|
|
|
|
@Get('driver/:driverId/stats')
|
|
@ApiOperation({ summary: 'Get incident statistics for a driver' })
|
|
async statsForDriver(@Param('driverId') driverId: string) {
|
|
return this.incidentsService.statsForDriver(driverId);
|
|
}
|
|
|
|
@Get('driver/:driverId')
|
|
@ApiOperation({ summary: 'List incidents for a driver (incident history)' })
|
|
async findByDriver(@Param('driverId') driverId: string) {
|
|
return this.incidentsService.findByDriver(driverId);
|
|
}
|
|
|
|
@Get(':id')
|
|
@ApiOperation({ summary: 'Get an incident by id' })
|
|
async findById(@Param('id') id: string) {
|
|
return this.incidentsService.findById(id);
|
|
}
|
|
|
|
@Patch(':id')
|
|
@BookingStaff(FREIGHT_PERMS.drivers.update)
|
|
@ApiOperation({ summary: 'Update an incident' })
|
|
async update(@Param('id') id: string, @Body() dto: UpdateIncidentDto) {
|
|
return this.incidentsService.update(id, dto);
|
|
}
|
|
|
|
@Delete(':id')
|
|
@BookingStaff(FREIGHT_PERMS.drivers.delete)
|
|
@ApiOperation({ summary: 'Delete an incident' })
|
|
async remove(@Param('id') id: string) {
|
|
await this.incidentsService.remove(id);
|
|
return { success: true };
|
|
}
|
|
}
|