From 47c9cd47e643c4b52b9697019d2e740840acfa2d Mon Sep 17 00:00:00 2001 From: mahyargdz Date: Mon, 5 May 2025 15:18:37 +0330 Subject: [PATCH] feat: Add support plans module with entities and repositories --- src/configs/typeorm.config.ts | 2 +- .../providers/support-plans.service.ts | 45 ++++++++++++++++--- .../support-plan-feature.repository.ts | 12 +++++ .../support-plans/support-plans.controller.ts | 15 ++++--- .../support-plans/support-plans.module.ts | 4 +- 5 files changed, 61 insertions(+), 17 deletions(-) create mode 100644 src/modules/support-plans/repositories/support-plan-feature.repository.ts diff --git a/src/configs/typeorm.config.ts b/src/configs/typeorm.config.ts index 9391ab2..8d8378f 100755 --- a/src/configs/typeorm.config.ts +++ b/src/configs/typeorm.config.ts @@ -13,7 +13,7 @@ export function databaseConfigs(): TypeOrmModuleAsyncOptions { username: configService.getOrThrow("DB_USER"), password: configService.getOrThrow("DB_PASS"), autoLoadEntities: true, - synchronize: configService.getOrThrow("NODE_ENV") == "production" ? false : false, + synchronize: configService.getOrThrow("NODE_ENV") == "production" ? false : true, logging: configService.getOrThrow("NODE_ENV") == "production" ? false : true, migrationsTableName: "typeorm_migrations", migrationsRun: false, diff --git a/src/modules/support-plans/providers/support-plans.service.ts b/src/modules/support-plans/providers/support-plans.service.ts index 5da97db..a66def6 100644 --- a/src/modules/support-plans/providers/support-plans.service.ts +++ b/src/modules/support-plans/providers/support-plans.service.ts @@ -1,15 +1,18 @@ import { BadRequestException, Injectable } from "@nestjs/common"; +import { DataSource } from "typeorm"; import { SupportPlanMessage } from "../../../common/enums/message.enum"; import { CreateSupportPlanDto } from "../DTO/create-support-plan.dto"; import { GetSupportPlanListQueryDto } from "../DTO/get-support-plan-list-query.dto"; import { UpdateSupportPlanDto } from "../DTO/update-support-plan-feature.dto"; +import { SupportPlanFeatureRepository } from "../repositories/support-plan-feature.repository"; import { SupportPlanRepository } from "../repositories/support-plan.repository"; @Injectable() export class SupportPlansService { constructor( private readonly supportPlanRepo: SupportPlanRepository, - // private readonly userSupportPlanRepo: UserSupportPlanRepository, + private readonly supportPlanFeatureRepo: SupportPlanFeatureRepository, + private readonly dataSource: DataSource, ) {} async createSupportPlan(createSupportPlanDto: CreateSupportPlanDto) { @@ -50,13 +53,41 @@ export class SupportPlansService { } //***************************************** */ async updateSupportPlanById(id: string, updateSupportPlanDto: UpdateSupportPlanDto) { - const supportPlan = await this.supportPlanRepo.getSupportPlanById(id); - if (!supportPlan) throw new BadRequestException(SupportPlanMessage.SUPPORT_PLAN_NOT_FOUND); + const queryRunner = this.dataSource.createQueryRunner(); - await this.supportPlanRepo.save({ ...supportPlan, ...updateSupportPlanDto }); + try { + await queryRunner.connect(); + await queryRunner.startTransaction(); - return { - message: SupportPlanMessage.SUPPORT_PLAN_UPDATED, - }; + const supportPlan = await queryRunner.manager.findOne(this.supportPlanRepo.target, { where: { id }, relations: { features: true } }); + if (!supportPlan) throw new BadRequestException(SupportPlanMessage.SUPPORT_PLAN_NOT_FOUND); + + // If updating features: + if (updateSupportPlanDto.features) { + // Remove old features (optional, if replacing) + await queryRunner.manager.delete(this.supportPlanFeatureRepo.target, { supportPlan: { id } }); + + // Add new features, making sure to set the relation + const features = updateSupportPlanDto.features.map((f) => ({ + ...f, + supportPlan, // or supportPlan: { id } + })); + await queryRunner.manager.save(this.supportPlanFeatureRepo.target, features); + } + + // Update the plan itself + await queryRunner.manager.save(this.supportPlanRepo.target, { ...supportPlan, ...updateSupportPlanDto, features: undefined }); + + await queryRunner.commitTransaction(); + + return { + message: SupportPlanMessage.SUPPORT_PLAN_UPDATED, + }; + } catch (error) { + await queryRunner.rollbackTransaction(); + throw error; + } finally { + await queryRunner.release(); + } } } diff --git a/src/modules/support-plans/repositories/support-plan-feature.repository.ts b/src/modules/support-plans/repositories/support-plan-feature.repository.ts new file mode 100644 index 0000000..1da23e6 --- /dev/null +++ b/src/modules/support-plans/repositories/support-plan-feature.repository.ts @@ -0,0 +1,12 @@ +import { Injectable } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; + +import { SupportPlanFeature } from "../entities/support-plan-feature.entity"; + +@Injectable() +export class SupportPlanFeatureRepository extends Repository { + constructor(@InjectRepository(SupportPlanFeature) repository: Repository) { + super(repository.target, repository.manager, repository.queryRunner); + } +} diff --git a/src/modules/support-plans/support-plans.controller.ts b/src/modules/support-plans/support-plans.controller.ts index 85fed19..a0ac9c8 100644 --- a/src/modules/support-plans/support-plans.controller.ts +++ b/src/modules/support-plans/support-plans.controller.ts @@ -1,8 +1,9 @@ -import { Body, Controller, Delete, Get, Param, Post, Query } from "@nestjs/common"; +import { Body, Controller, Delete, Get, Param, Patch, Post, Query } from "@nestjs/common"; import { ApiOperation } from "@nestjs/swagger"; import { CreateSupportPlanDto } from "./DTO/create-support-plan.dto"; import { GetSupportPlanListQueryDto } from "./DTO/get-support-plan-list-query.dto"; +import { UpdateSupportPlanDto } from "./DTO/update-support-plan-feature.dto"; import { SupportPlansService } from "./providers/support-plans.service"; import { AdminRoute } from "../../common/decorators/admin.decorator"; import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; @@ -45,11 +46,11 @@ export class SupportPlansController { return this.supportPlansService.deleteSupportPlanById(paramDto.id); } - // @AdminRoute() + @AdminRoute() // @PermissionsDec(PermissionEnum.SUPPORT_PLAN) - // @ApiOperation({ summary: "Update a support plan by id (admin)" }) - // @Patch(":id") - // updateSupportPlanById(@Param() paramDto: ParamDto, @Body() updateSupportPlanDto: UpdateSupportPlanDto) { - // return this.supportPlansService.updateSupportPlanById(paramDto.id, updateSupportPlanDto); - // } + @ApiOperation({ summary: "Update a support plan by id (admin)" }) + @Patch(":id") + updateSupportPlanById(@Param() paramDto: ParamDto, @Body() updateSupportPlanDto: UpdateSupportPlanDto) { + return this.supportPlansService.updateSupportPlanById(paramDto.id, updateSupportPlanDto); + } } diff --git a/src/modules/support-plans/support-plans.module.ts b/src/modules/support-plans/support-plans.module.ts index 49d9e17..fc211f7 100644 --- a/src/modules/support-plans/support-plans.module.ts +++ b/src/modules/support-plans/support-plans.module.ts @@ -5,14 +5,14 @@ import { SupportPlanFeature } from "./entities/support-plan-feature.entity"; import { SupportPlan } from "./entities/support-plan.entity"; import { UserSupportPlan } from "./entities/user-support-plan.entity"; import { SupportPlansService } from "./providers/support-plans.service"; +import { SupportPlanFeatureRepository } from "./repositories/support-plan-feature.repository"; import { SupportPlanRepository } from "./repositories/support-plan.repository"; import { UserSupportPlanRepository } from "./repositories/user-support-plan.repository"; import { SupportPlansController } from "./support-plans.controller"; - @Module({ imports: [TypeOrmModule.forFeature([SupportPlan, SupportPlanFeature, UserSupportPlan])], controllers: [SupportPlansController], - providers: [SupportPlansService, SupportPlanRepository, UserSupportPlanRepository], + providers: [SupportPlansService, SupportPlanRepository, UserSupportPlanRepository, SupportPlanFeatureRepository], exports: [SupportPlansService], }) export class SupportPlansModule {}