import { Body, Controller, Delete, HttpCode, Param, ParseUUIDPipe, Patch, Post, UseGuards, } from '@nestjs/common'; import { ApiBearerAuth, ApiCreatedResponse, ApiForbiddenResponse, ApiNoContentResponse, ApiNotFoundResponse, ApiOkResponse, ApiOperation, ApiTags, ApiUnauthorizedResponse, } from '@nestjs/swagger'; import type { AuthUser } from '../../../common/auth/auth-user'; import { CurrentUser } from '../../../common/decorators/current-user.decorator'; import { BEARER_AUTH_NAME } from '../../../common/swagger/setup-swagger'; import { RequireFieldPrivilege } from '../shared/field-privilege.decorator'; import { FieldPrivilegeGuard } from '../shared/field-privilege.guard'; import { AddPlanDestinationDto, BulkIdsDto, BulkStatusDto, CreatePlanDto, GeneratePlansDto, PlanDto, UpdatePlanDto, UpdatePlanStatusDto, } from './dto/plan.dto'; import { PlansService } from './plans.service'; @ApiTags('plans') @ApiBearerAuth(BEARER_AUTH_NAME) @UseGuards(FieldPrivilegeGuard) @Controller('plans') export class PlansWriteController { constructor(private readonly plansService: PlansService) {} @Post('generate') @RequireFieldPrivilege('plan', 'create') @ApiOperation({ summary: 'Generate plans from cycles for a date range' }) @ApiOkResponse({ schema: { properties: { created: { type: 'number' }, skipped: { type: 'number' }, }, }, }) @ApiUnauthorizedResponse() @ApiForbiddenResponse() generate( @Body() dto: GeneratePlansDto, @CurrentUser('id') userId: string, ): Promise<{ created: number; skipped: number }> { return this.plansService.generate({ ...dto, userId }); } @Post('bulk-delete') @HttpCode(200) @RequireFieldPrivilege('plan', 'delete') @ApiOperation({ summary: 'Bulk archive plans' }) @ApiOkResponse({ schema: { properties: { deleted: { type: 'number' } } } }) bulkDelete( @Body() dto: BulkIdsDto, @CurrentUser() user: AuthUser, ): Promise<{ deleted: number }> { return this.plansService.bulkDelete(dto.ids, user); } @Post('bulk-status') @HttpCode(200) @RequireFieldPrivilege('plan', 'update') @ApiOperation({ summary: 'Bulk update plan status' }) @ApiOkResponse({ schema: { properties: { updated: { type: 'number' } } } }) bulkStatus( @Body() dto: BulkStatusDto, @CurrentUser() user: AuthUser, ): Promise<{ updated: number }> { return this.plansService.bulkUpdateStatus( dto.ids, dto.status, user.id, user, ); } @Post() @RequireFieldPrivilege('plan', 'create') @ApiOperation({ summary: 'Create plan' }) @ApiCreatedResponse({ type: PlanDto }) create( @Body() dto: CreatePlanDto, @CurrentUser('id') userId: string, ): Promise { return this.plansService.create({ ...dto, userId }); } @Post(':id/destinations') @RequireFieldPrivilege('plan', 'update') @ApiOperation({ summary: 'Add a destination to a plan' }) @ApiOkResponse({ type: PlanDto }) addDestination( @Param('id', ParseUUIDPipe) id: string, @Body() dto: AddPlanDestinationDto, @CurrentUser() user: AuthUser, ): Promise { return this.plansService.addDestination( id, dto.customerId, dto.afterDestinationId, user, ); } @Delete(':id/destinations/:destinationId') @RequireFieldPrivilege('plan', 'update') @ApiOperation({ summary: 'Remove a destination from a plan' }) @ApiOkResponse({ type: PlanDto }) removeDestination( @Param('id', ParseUUIDPipe) id: string, @Param('destinationId', ParseUUIDPipe) destinationId: string, @CurrentUser() user: AuthUser, ): Promise { return this.plansService.removeDestination(id, destinationId, user); } @Patch(':id/status') @RequireFieldPrivilege('plan', 'update') @ApiOperation({ summary: 'Update plan status' }) @ApiOkResponse({ type: PlanDto }) updateStatus( @Param('id', ParseUUIDPipe) id: string, @Body() dto: UpdatePlanStatusDto, @CurrentUser() user: AuthUser, ): Promise { return this.plansService.updateStatus(id, dto.status, user.id, user); } @Patch(':id') @RequireFieldPrivilege('plan', 'update') @ApiOperation({ summary: 'Update plan (not status)' }) @ApiOkResponse({ type: PlanDto }) @ApiNotFoundResponse() update( @Param('id', ParseUUIDPipe) id: string, @Body() dto: UpdatePlanDto, @CurrentUser() user: AuthUser, ): Promise { return this.plansService.update(id, { ...dto, userId: user.id }, user); } @Delete(':id') @HttpCode(204) @RequireFieldPrivilege('plan', 'delete') @ApiOperation({ summary: 'Archive plan' }) @ApiNoContentResponse() @ApiUnauthorizedResponse() @ApiForbiddenResponse() async delete( @Param('id', ParseUUIDPipe) id: string, @CurrentUser() user: AuthUser, ): Promise { await this.plansService.delete(id, user); } }