import { Body, Controller, ForbiddenException, Get, Param, ParseUUIDPipe, Put, } from '@nestjs/common'; import { ApiBearerAuth, ApiOperation, ApiTags } from '@nestjs/swagger'; import { CurrentUser } from '@edr/api-common'; import type { TCurrentUser } from '@tria-plc/api-common/modules/auth/types/current-user.type'; import { BookingStaff, StaffReference } from '../../common/booking-guards'; import { isFreightApprovalAdmin } from '../../common/freight-permission.util'; import { FREIGHT_PERMS } from '../../seed/freight-permissions.registry'; import { UpsertUserTradeAccessDto } from './dto/upsert-user-trade-access.dto'; import { UserTradeAccessService } from './user-trade-access.service'; @ApiTags('user-trade-access') @Controller('user-trade-access') @StaffReference() @ApiBearerAuth() export class UserTradeAccessController { constructor(private readonly service: UserTradeAccessService) {} @Get() @BookingStaff(FREIGHT_PERMS.tradeAccess.view) @ApiOperation({ summary: 'List every configured user trade-direction scope' }) list(@CurrentUser() user: TCurrentUser) { this.assertAdmin(user); return this.service.listConfigs(); } @Get('me') @ApiOperation({ summary: "Current user's effective trade-direction scope" }) async me(@CurrentUser() user: TCurrentUser) { const allowed = await this.service.resolveAllowedDirections(user); return { restricted: allowed !== null, directions: allowed ?? ['IMPORT', 'EXPORT', 'DOMESTIC'], }; } @Put(':userId') @BookingStaff(FREIGHT_PERMS.tradeAccess.manage) @ApiOperation({ summary: 'Set the trade directions a backoffice user may see', }) upsert( @Param('userId', ParseUUIDPipe) userId: string, @Body() dto: UpsertUserTradeAccessDto, @CurrentUser() user: TCurrentUser, ) { this.assertAdmin(user); return this.service.upsert( userId, dto.directions, (user as { id?: string } | null)?.id ?? null, ); } private assertAdmin(user: TCurrentUser) { if (!isFreightApprovalAdmin(user)) { throw new ForbiddenException( 'Only super or organization admins can manage trade-direction access', ); } } }