import { Body, Controller, Get, Param, ParseUUIDPipe, Patch, Post, UploadedFiles, UseInterceptors, } from '@nestjs/common'; import { AnyFilesInterceptor } from '@nestjs/platform-express'; import { ApiBearerAuth, ApiConsumes, ApiOperation, ApiTags } from '@nestjs/swagger'; import { BookingStaff } from '../../common/booking-guards'; import { FREIGHT_PERMS } from '../../seed/freight-permissions.registry'; import { CreateInspectionReportDto } from './dto/create-inspection-report.dto'; import { UpdateInspectionReportDto } from './dto/update-inspection-report.dto'; import { WarehouseInspectionService } from './warehouse-inspection.service'; @ApiTags('warehouse-inspection') @ApiBearerAuth() // Baseline read: inspection reports are opened from inventory screens too — // either view permission grants reads; writes stack their own per route. @Controller() // 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.warehouseInspectionReports.view, FREIGHT_PERMS.warehouseInventory.view, FREIGHT_PERMS.warehouseInspectionReports.create, FREIGHT_PERMS.warehouseInspectionReports.update, ]) export class WarehouseInspectionController { constructor(private readonly inspectionService: WarehouseInspectionService) {} @Post('warehouse-inventory/:inventoryId/inspection-reports') @BookingStaff(FREIGHT_PERMS.warehouseInspectionReports.create) @ApiOperation({ summary: 'Create an inspection / damage report for an inventory item' }) create( @Param('inventoryId', ParseUUIDPipe) inventoryId: string, @Body() dto: CreateInspectionReportDto, ) { return this.inspectionService.create(inventoryId, dto); } @Get('warehouse-inventory/:inventoryId/inspection-reports') @ApiOperation({ summary: 'List inspection reports for an inventory item' }) listByInventory(@Param('inventoryId', ParseUUIDPipe) inventoryId: string) { return this.inspectionService.findByInventory(inventoryId); } @Get('warehouse-inspection-reports/:id') @ApiOperation({ summary: 'Get an inspection report (with attachments)' }) async findOne(@Param('id', ParseUUIDPipe) id: string) { const report = await this.inspectionService.findById(id); const attachments = await this.inspectionService.listAttachments(id); return { ...report, attachments }; } @Patch('warehouse-inspection-reports/:id') @BookingStaff(FREIGHT_PERMS.warehouseInspectionReports.update) @ApiOperation({ summary: 'Update an inspection report' }) update(@Param('id', ParseUUIDPipe) id: string, @Body() dto: UpdateInspectionReportDto) { return this.inspectionService.update(id, dto); } @Post('warehouse-inspection-reports/:id/attachments') @BookingStaff(FREIGHT_PERMS.warehouseInspectionReports.update) @UseInterceptors(AnyFilesInterceptor()) @ApiConsumes('multipart/form-data') @ApiOperation({ summary: 'Upload inspection images / documents' }) addAttachments( @Param('id', ParseUUIDPipe) id: string, @UploadedFiles() files: Express.Multer.File[], ) { return this.inspectionService.addAttachments(id, files); } }