import { Get, Post, Put, Delete, Param, Query, Body, HttpCode, ParseUUIDPipe, } from "@nestjs/common"; import { ApiOperation, ApiOkResponse, ApiNotFoundResponse, ApiBadRequestResponse, } from "@nestjs/swagger"; import { BaseService } from "./base.service"; import { PaginationDto } from "../dto/pagination.dto"; import { ApiResponse, createSuccessResponse, createPaginatedResponse, } from "../types/api-response.type"; /** * Generic base controller with common CRUD endpoints * Extend this class for entity-specific controllers * * Note: Use decorators like @Controller() on the child class */ export abstract class BaseController { constructor( protected readonly service: BaseService, protected readonly entityName: string, ) {} @Get() @HttpCode(200) @ApiOperation({ summary: "Get all records with pagination" }) @ApiOkResponse({ description: "Records retrieved successfully" }) async findAll( @Query() pagination: PaginationDto, ): Promise> { const result = await this.service.findAll(pagination); return createPaginatedResponse( result.items, result.meta.total, result.meta.page, result.meta.limit, `${this.entityName} list retrieved successfully`, ); } @Get(":id") @HttpCode(200) @ApiOperation({ summary: "Get a record by ID" }) @ApiOkResponse({ description: "Record retrieved successfully" }) @ApiNotFoundResponse({ description: "Record not found" }) async findOne( @Param("id", ParseUUIDPipe) id: string, ): Promise> { const result = await this.service.findOne(id); return createSuccessResponse( result, `${this.entityName} retrieved successfully`, ); } @Post() @HttpCode(200) @ApiOperation({ summary: "Create a new record" }) @ApiOkResponse({ description: "Record created successfully" }) @ApiBadRequestResponse({ description: "Validation failed" }) async create(@Body() createDto: CreateDto): Promise> { const result = await this.service.create(createDto); return createSuccessResponse( result, `${this.entityName} created successfully`, 201, ); } @Put(":id") @HttpCode(200) @ApiOperation({ summary: "Update an existing record" }) @ApiOkResponse({ description: "Record updated successfully" }) @ApiNotFoundResponse({ description: "Record not found" }) async update( @Param("id", ParseUUIDPipe) id: string, @Body() updateDto: UpdateDto, ): Promise> { const result = await this.service.update(id, updateDto); return createSuccessResponse( result, `${this.entityName} updated successfully`, ); } @Delete(":id") @HttpCode(200) @ApiOperation({ summary: "Delete a record (soft delete)" }) @ApiOkResponse({ description: "Record deleted successfully" }) @ApiNotFoundResponse({ description: "Record not found" }) async delete( @Param("id", ParseUUIDPipe) id: string, ): Promise> { const result = await this.service.delete(id); return createSuccessResponse( result, `${this.entityName} deleted successfully`, ); } @Post(":id/restore") @HttpCode(200) @ApiOperation({ summary: "Restore a soft-deleted record" }) @ApiOkResponse({ description: "Record restored successfully" }) async restore( @Param("id", ParseUUIDPipe) id: string, ): Promise> { const result = await this.service.restore(id); return createSuccessResponse( result, `${this.entityName} restored successfully`, ); } }