import { Controller, Get, Query } from '@nestjs/common'; import { ApiBearerAuth, ApiOkResponse, 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 } from '../../common/booking-guards'; import { FREIGHT_PERMS } from '../../seed/freight-permissions.registry'; import { OverviewQueryDto } from './dto/overview-query.dto'; import { OverviewResponseDto } from './dto/overview-response.dto'; import { OverviewBillingTabDto, OverviewBookingsTabDto, OverviewClearanceTabDto, OverviewContractsTabDto, OverviewCustomersTabDto, OverviewFleetTabDto, OverviewOperationsTabDto, OverviewStaffTabDto, } from './dto/overview-tab-response.dto'; import { OverviewService } from './overview.service'; import { UserTradeAccessService } from '../user-trade-access/user-trade-access.service'; @ApiTags('Overview') @ApiBearerAuth() @Controller('overview') export class OverviewController { constructor( private readonly overviewService: OverviewService, private readonly userTradeAccessService: UserTradeAccessService, ) {} @Get() @BookingStaff(FREIGHT_PERMS.overview.view) @ApiOperation({ summary: 'Aggregated dashboard summary for backoffice overview' }) @ApiOkResponse({ type: OverviewResponseDto }) async getDashboard( @Query() query: OverviewQueryDto, @CurrentUser() user: TCurrentUser, ): Promise { const allowed = await this.userTradeAccessService.resolveAllowedDirections(user); return this.overviewService.getDashboard( query.range ?? '30d', allowed ?? undefined, ); } @Get('bookings') @BookingStaff(FREIGHT_PERMS.overview.view) @ApiOperation({ summary: 'Bookings tab metrics and charts' }) @ApiOkResponse({ type: OverviewBookingsTabDto }) async getBookingsTab( @Query() query: OverviewQueryDto, @CurrentUser() user: TCurrentUser, ): Promise { const allowed = await this.userTradeAccessService.resolveAllowedDirections(user); return this.overviewService.getBookingsTab( query.range ?? '30d', allowed ?? undefined, ); } @Get('contracts') @BookingStaff(FREIGHT_PERMS.overview.view) @ApiOperation({ summary: 'Contracts tab metrics and charts' }) @ApiOkResponse({ type: OverviewContractsTabDto }) async getContractsTab( @Query() query: OverviewQueryDto, @CurrentUser() user: TCurrentUser, ): Promise { const allowed = await this.userTradeAccessService.resolveAllowedDirections(user); return this.overviewService.getContractsTab( query.range ?? '30d', allowed ?? undefined, ); } @Get('billing') @BookingStaff(FREIGHT_PERMS.overview.view) @ApiOperation({ summary: 'Billing tab metrics and charts' }) @ApiOkResponse({ type: OverviewBillingTabDto }) async getBillingTab( @Query() query: OverviewQueryDto, @CurrentUser() user: TCurrentUser, ): Promise { const allowed = await this.userTradeAccessService.resolveAllowedDirections(user); return this.overviewService.getBillingTab( query.range ?? '30d', allowed ?? undefined, ); } @Get('operations') @BookingStaff(FREIGHT_PERMS.overview.view) @ApiOperation({ summary: 'Operations tab metrics and charts' }) @ApiOkResponse({ type: OverviewOperationsTabDto }) getOperationsTab( @Query() query: OverviewQueryDto, ): Promise { return this.overviewService.getOperationsTab(query.range ?? '30d'); } @Get('fleet') @BookingStaff(FREIGHT_PERMS.overview.view) @ApiOperation({ summary: 'Wagon and locomotive fleet detail, plus turnaround' }) @ApiOkResponse({ type: OverviewFleetTabDto }) getFleetTab(@Query() query: OverviewQueryDto): Promise { return this.overviewService.getFleetTab(query.range ?? '30d'); } @Get('clearance') @BookingStaff(FREIGHT_PERMS.overview.view) @ApiOperation({ summary: 'Document review and invoice queues' }) @ApiOkResponse({ type: OverviewClearanceTabDto }) getClearanceTab(): Promise { return this.overviewService.getClearanceTab(); } @Get('customers') @BookingStaff(FREIGHT_PERMS.overview.view) @ApiOperation({ summary: 'Customers tab metrics and charts' }) @ApiOkResponse({ type: OverviewCustomersTabDto }) async getCustomersTab( @Query() query: OverviewQueryDto, @CurrentUser() user: TCurrentUser, ): Promise { const allowed = await this.userTradeAccessService.resolveAllowedDirections(user); return this.overviewService.getCustomersTab( query.range ?? '30d', allowed ?? undefined, ); } @Get('staff') @BookingStaff(FREIGHT_PERMS.overview.view) @ApiOperation({ summary: 'Staff tab metrics and charts' }) @ApiOkResponse({ type: OverviewStaffTabDto }) getStaffTab(@Query() query: OverviewQueryDto): Promise { return this.overviewService.getStaffTab(query.range ?? '30d'); } }