import { Body, Controller, Delete, Get, HttpCode, HttpStatus, Param, ParseUUIDPipe, Patch, Post, Query, } from "@nestjs/common"; import { ApiBearerAuth, ApiOperation, ApiTags } from "@nestjs/swagger"; import { PortalCustomer } from "../../common/booking-guards"; import { RuleEngineCreate, RuleEngineDelete, RuleEngineUpdate, RuleEngineView, } from "../../common/rule-engine-guards"; import { BackofficeResetPasswordDto } from "../auth/dto/forgot-password.dto"; import { CreateTransitAgentDto } from "./dto/create-transit-agent.dto"; import { InviteTransitAgentDto } from "./dto/invite-transit-agent.dto"; import { UpdateTransitAgentDto } from "./dto/update-transit-agent.dto"; import { TransitAgentsService } from "./transit-agents.service"; @ApiTags("transit-agents") @Controller("transit-agents") @ApiBearerAuth() export class TransitAgentsController { constructor(private readonly transitAgentsService: TransitAgentsService) {} @Get() @RuleEngineView("transit-agents") @ApiOperation({ summary: "List transit agents" }) findAll(@Query() query: Record) { return this.transitAgentsService.findAll({ isActive: query.isActive === "all" ? undefined : query.isActive !== undefined ? query.isActive === "true" : undefined, page: query.page ? parseInt(query.page, 10) : undefined, pageSize: query.pageSize ? parseInt(query.pageSize, 10) : undefined, sortBy: query.sortBy, sortOrder: query.sortOrder, }); } /** Active officers — the transit-assignee assignment dropdown. */ @Get("assignable") @RuleEngineView("transit-agents") @ApiOperation({ summary: "List active transit agents (assignable)" }) findAssignable() { return this.transitAgentsService.findAssignable(); } /** * The Ethiopian roster, id + name only, for a customer registering as a * freight forwarder to pick itself from. Declared before `:id` so the * literal path is not swallowed by the UUID route. */ @Get("forwarder-options") @PortalCustomer() @ApiOperation({ summary: "List active Ethiopian transit agents (id + name) a freight forwarder can register as", }) findForwarderOptions() { return this.transitAgentsService.findForwarderOptions(); } /** * The Djibouti roster, id + name only, for the clearing agent on a booking * to name the transit officer. Also before `:id` for the same reason. */ @Get("djibouti-options") @PortalCustomer() @ApiOperation({ summary: "List active Djibouti transit agents (id + name) an assigned clearing agent can hand the transit leg to", }) findDjiboutiOptions() { return this.transitAgentsService.findDjiboutiOptions(); } @Get(":id") @RuleEngineView("transit-agents") @ApiOperation({ summary: "Get a transit agent by ID" }) findOne(@Param("id", ParseUUIDPipe) id: string) { return this.transitAgentsService.findById(id); } @Post() @RuleEngineCreate("transit-agents") @ApiOperation({ summary: "Create a transit agent; with an email, also creates its portal account and sends the activation link", }) create(@Body() dto: CreateTransitAgentDto) { return this.transitAgentsService.createWithInvite(dto); } /** * The path for the roster entries already in production: they were created * before transit agents had logins, so they get their account here rather * than at create time. */ @Post(":id/invite") @RuleEngineUpdate("transit-agents") @ApiOperation({ summary: "Create a portal account for an existing transit agent and send the activation link", }) invite( @Param("id", ParseUUIDPipe) id: string, @Body() dto: InviteTransitAgentDto, ) { return this.transitAgentsService.invite(id, dto); } @Post(":id/resend-activation") @RuleEngineUpdate("transit-agents") @ApiOperation({ summary: "Resend a transit agent's activation / password-reset link", }) resendActivation( @Param("id", ParseUUIDPipe) id: string, @Body() dto: BackofficeResetPasswordDto, ) { return this.transitAgentsService.resendActivation(id, dto.channel); } @Patch(":id") @RuleEngineUpdate("transit-agents") @ApiOperation({ summary: "Update a transit agent" }) update( @Param("id", ParseUUIDPipe) id: string, @Body() dto: UpdateTransitAgentDto, ) { return this.transitAgentsService.update(id, dto); } @Delete(":id") @RuleEngineDelete("transit-agents") @HttpCode(HttpStatus.NO_CONTENT) @ApiOperation({ summary: "Soft-delete a transit agent" }) remove(@Param("id", ParseUUIDPipe) id: string) { return this.transitAgentsService.remove(id); } }