src/loading-bays/loading-bays.controller.ts
loading-bays
Methods |
|
| Async assignVehicle | ||||||||||||
assignVehicle(orgId: string, id: string, dto: AssignBayDto)
|
||||||||||||
Decorators :
@Post(':id/assign')
|
||||||||||||
|
Parameters :
Returns :
unknown
|
| Async bulkUpload | |||||||||
bulkUpload(orgId: string, file: Express.Multer.File)
|
|||||||||
Decorators :
@Post('upload')
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async create | |||||||||
create(orgId: string, dto: CreateLoadingBayDto)
|
|||||||||
Decorators :
@Post()
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async findAll | |||||||||
findAll(orgId: string, query: PaginationParams)
|
|||||||||
Decorators :
@Get()
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async findOne |
findOne(orgId: string, id: string)
|
Decorators :
@Get(':id')
|
|
Returns :
unknown
|
| Async getConformance |
getConformance(orgId: string, from?: string, to?: string)
|
Decorators :
@Get('conformance')
|
|
Returns :
unknown
|
| Async getShiftCapacity | ||||||
getShiftCapacity(orgId: string)
|
||||||
Decorators :
@Get('shift-capacity')
|
||||||
|
Parameters :
Returns :
unknown
|
| Async getStatus | ||||||
getStatus(orgId: string)
|
||||||
Decorators :
@Get('status')
|
||||||
|
Parameters :
Returns :
unknown
|
| Async listEvents |
listEvents(orgId: string, bayId?: string, limit?: string)
|
Decorators :
@Get('events')
|
|
Returns :
unknown
|
| Async recordEvent | |||||||||
recordEvent(orgId: string, dto: RecordBayEventDto)
|
|||||||||
Decorators :
@Post('events')
|
|||||||||
|
Parameters :
Returns :
unknown
|
| Async releaseBay |
releaseBay(orgId: string, id: string)
|
Decorators :
@Post(':id/release')
|
|
Returns :
unknown
|
| Async remove |
remove(orgId: string, id: string)
|
Decorators :
@Delete(':id')
|
|
Returns :
unknown
|
| Async update | ||||||||||||
update(orgId: string, id: string, dto: UpdateLoadingBayDto)
|
||||||||||||
Decorators :
@Patch(':id')
|
||||||||||||
|
Parameters :
Returns :
unknown
|
import {
Controller,
Get,
Post,
Patch,
Delete,
Body,
Param,
Query,
UseGuards,
UseInterceptors,
UploadedFile,
BadRequestException,
} from '@nestjs/common';
import { FileInterceptor } from '@nestjs/platform-express';
import { ApiTags, ApiBearerAuth, ApiOperation, ApiConsumes } from '@nestjs/swagger';
import { LoadingBaysService } from './loading-bays.service';
import { BayConformanceService } from './bay-conformance.service';
import { CreateLoadingBayDto } from './dto/create-loading-bay.dto';
import { UpdateLoadingBayDto } from './dto/update-loading-bay.dto';
import { AssignBayDto } from './dto/assign-bay.dto';
import { RecordBayEventDto } from './dto/record-bay-event.dto';
import { CombinedAuthGuard } from '../auth/guards/combined-auth.guard';
import { RolesGuard } from '../auth/guards/roles.guard';
import { Roles } from '../auth/decorators/roles.decorator';
import { CurrentUser } from '../auth/decorators/current-user.decorator';
import { ApiPagination } from '../common/decorators/api-pagination.decorator';
import { PaginationParams } from '../common/utils/pagination.util';
const BAY_WRITERS = [
'SUPER_ADMIN',
'ADMIN',
'OPERATIONS_MANAGER',
'PLANNER',
'DISPATCHER',
] as const;
@ApiTags('Loading Bays')
@ApiBearerAuth()
@UseGuards(CombinedAuthGuard, RolesGuard)
@Controller('loading-bays')
export class LoadingBaysController {
constructor(
private readonly loadingBaysService: LoadingBaysService,
private readonly bayConformanceService: BayConformanceService,
) {}
@Post()
@Roles(...BAY_WRITERS)
@ApiOperation({ summary: 'Create a new loading bay' })
async create(
@CurrentUser('organizationId') orgId: string,
@Body() dto: CreateLoadingBayDto,
) {
return this.loadingBaysService.create(orgId, dto);
}
@Get('status')
@ApiOperation({ summary: 'Get all bays with current status summary' })
async getStatus(@CurrentUser('organizationId') orgId: string) {
return this.loadingBaysService.getStatus(orgId);
}
@Get('shift-capacity')
@ApiOperation({ summary: 'Calculate shift capacity across all active bays' })
async getShiftCapacity(@CurrentUser('organizationId') orgId: string) {
return this.loadingBaysService.getShiftCapacity(orgId);
}
@Post('events')
@Roles(...BAY_WRITERS, 'DRIVER')
@ApiOperation({ summary: 'Record a bay event (arrival, departure, etc.)' })
async recordEvent(
@CurrentUser('organizationId') orgId: string,
@Body() dto: RecordBayEventDto,
) {
return this.bayConformanceService.recordEvent(orgId, {
loadingBayId: dto.loadingBayId,
vehicleId: dto.vehicleId,
tripId: dto.tripId,
eventType: dto.eventType,
scheduledAt: dto.scheduledAt ? new Date(dto.scheduledAt) : undefined,
actualAt: dto.actualAt ? new Date(dto.actualAt) : undefined,
notes: dto.notes,
});
}
@Get('conformance')
@ApiOperation({ summary: 'Get bay conformance statistics' })
async getConformance(
@CurrentUser('organizationId') orgId: string,
@Query('from') from?: string,
@Query('to') to?: string,
) {
return this.bayConformanceService.getConformanceStats(orgId, from, to);
}
@Get('events')
@ApiOperation({ summary: 'List recent bay events' })
async listEvents(
@CurrentUser('organizationId') orgId: string,
@Query('bayId') bayId?: string,
@Query('limit') limit?: string,
) {
return this.bayConformanceService.listEvents(
orgId,
bayId,
limit ? parseInt(limit, 10) : 50,
);
}
@Get()
@ApiPagination()
@ApiOperation({ summary: 'List all loading bays' })
async findAll(
@CurrentUser('organizationId') orgId: string,
@Query() query: PaginationParams,
) {
return this.loadingBaysService.findAll(orgId, query);
}
@Get(':id')
@ApiOperation({ summary: 'Get loading bay by ID (org-scoped)' })
async findOne(
@CurrentUser('organizationId') orgId: string,
@Param('id') id: string,
) {
return this.loadingBaysService.findOne(orgId, id);
}
@Patch(':id')
@Roles(...BAY_WRITERS)
@ApiOperation({ summary: 'Update a loading bay (org-scoped)' })
async update(
@CurrentUser('organizationId') orgId: string,
@Param('id') id: string,
@Body() dto: UpdateLoadingBayDto,
) {
return this.loadingBaysService.update(orgId, id, dto);
}
@Delete(':id')
@Roles('SUPER_ADMIN', 'ADMIN', 'OPERATIONS_MANAGER')
@ApiOperation({ summary: 'Delete a loading bay (blocked when occupied)' })
async remove(
@CurrentUser('organizationId') orgId: string,
@Param('id') id: string,
) {
return this.loadingBaysService.remove(orgId, id);
}
@Post(':id/assign')
@Roles(...BAY_WRITERS)
@ApiOperation({ summary: 'Assign a vehicle to a loading bay (race-safe)' })
async assignVehicle(
@CurrentUser('organizationId') orgId: string,
@Param('id') id: string,
@Body() dto: AssignBayDto,
) {
return this.loadingBaysService.assignVehicle(orgId, id, dto.vehicleId);
}
@Post(':id/release')
@Roles(...BAY_WRITERS, 'DRIVER')
@ApiOperation({ summary: 'Release a loading bay' })
async releaseBay(
@CurrentUser('organizationId') orgId: string,
@Param('id') id: string,
) {
return this.loadingBaysService.releaseBay(orgId, id);
}
@Post('upload')
@Roles(...BAY_WRITERS)
@ApiOperation({ summary: 'Bulk upload loading bays from Excel/CSV' })
@ApiConsumes('multipart/form-data')
@UseInterceptors(FileInterceptor('file', { limits: { fileSize: 10 * 1024 * 1024 } }))
async bulkUpload(
@CurrentUser('organizationId') orgId: string,
@UploadedFile() file: Express.Multer.File,
) {
if (!file) throw new BadRequestException('No file uploaded');
return this.loadingBaysService.bulkUploadFromFile(orgId, file);
}
}