File

src/loading-bays/loading-bays.controller.ts

Prefix

loading-bays

Index

Methods

Methods

Async assignVehicle
assignVehicle(orgId: string, id: string, dto: AssignBayDto)
Decorators :
@Post(':id/assign')
@Roles(undefined)
@ApiOperation({summary: 'Assign a vehicle to a loading bay (race-safe)'})
Parameters :
Name Type Optional
orgId string No
id string No
dto AssignBayDto No
Returns : unknown
Async bulkUpload
bulkUpload(orgId: string, file: Express.Multer.File)
Decorators :
@Post('upload')
@Roles(undefined)
@ApiOperation({summary: 'Bulk upload loading bays from Excel/CSV'})
@ApiConsumes('multipart/form-data')
@UseInterceptors(undefined)
Parameters :
Name Type Optional
orgId string No
file Express.Multer.File No
Returns : unknown
Async create
create(orgId: string, dto: CreateLoadingBayDto)
Decorators :
@Post()
@Roles(undefined)
@ApiOperation({summary: 'Create a new loading bay'})
Parameters :
Name Type Optional
orgId string No
dto CreateLoadingBayDto No
Returns : unknown
Async findAll
findAll(orgId: string, query: PaginationParams)
Decorators :
@Get()
@ApiPagination()
@ApiOperation({summary: 'List all loading bays'})
Parameters :
Name Type Optional
orgId string No
query PaginationParams No
Returns : unknown
Async findOne
findOne(orgId: string, id: string)
Decorators :
@Get(':id')
@ApiOperation({summary: 'Get loading bay by ID (org-scoped)'})
Parameters :
Name Type Optional
orgId string No
id string No
Returns : unknown
Async getConformance
getConformance(orgId: string, from?: string, to?: string)
Decorators :
@Get('conformance')
@ApiOperation({summary: 'Get bay conformance statistics'})
Parameters :
Name Type Optional
orgId string No
from string Yes
to string Yes
Returns : unknown
Async getShiftCapacity
getShiftCapacity(orgId: string)
Decorators :
@Get('shift-capacity')
@ApiOperation({summary: 'Calculate shift capacity across all active bays'})
Parameters :
Name Type Optional
orgId string No
Returns : unknown
Async getStatus
getStatus(orgId: string)
Decorators :
@Get('status')
@ApiOperation({summary: 'Get all bays with current status summary'})
Parameters :
Name Type Optional
orgId string No
Returns : unknown
Async listEvents
listEvents(orgId: string, bayId?: string, limit?: string)
Decorators :
@Get('events')
@ApiOperation({summary: 'List recent bay events'})
Parameters :
Name Type Optional
orgId string No
bayId string Yes
limit string Yes
Returns : unknown
Async recordEvent
recordEvent(orgId: string, dto: RecordBayEventDto)
Decorators :
@Post('events')
@Roles(undefined, 'DRIVER')
@ApiOperation({summary: 'Record a bay event (arrival, departure, etc.)'})
Parameters :
Name Type Optional
orgId string No
dto RecordBayEventDto No
Returns : unknown
Async releaseBay
releaseBay(orgId: string, id: string)
Decorators :
@Post(':id/release')
@Roles(undefined, 'DRIVER')
@ApiOperation({summary: 'Release a loading bay'})
Parameters :
Name Type Optional
orgId string No
id string No
Returns : unknown
Async remove
remove(orgId: string, id: string)
Decorators :
@Delete(':id')
@Roles('SUPER_ADMIN', 'ADMIN', 'OPERATIONS_MANAGER')
@ApiOperation({summary: 'Delete a loading bay (blocked when occupied)'})
Parameters :
Name Type Optional
orgId string No
id string No
Returns : unknown
Async update
update(orgId: string, id: string, dto: UpdateLoadingBayDto)
Decorators :
@Patch(':id')
@Roles(undefined)
@ApiOperation({summary: 'Update a loading bay (org-scoped)'})
Parameters :
Name Type Optional
orgId string No
id string No
dto UpdateLoadingBayDto No
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);
  }
}

results matching ""

    No results matching ""