From bc96f62782f76bede7dc56e5651de716461e74d8 Mon Sep 17 00:00:00 2001 From: mahyargdz Date: Sat, 8 Feb 2025 16:24:54 +0330 Subject: [PATCH] fix: bug in repositry of subscriptions --- src/common/entities/base.entity.ts | 6 ++--- src/common/enums/message.enum.ts | 12 +++++++++ .../danak-services.controller.ts | 16 +++++------ .../providers/danak-services.service.ts | 16 +++++------ .../entities/notification.entity.ts | 10 +++---- .../notifications/notifications.controller.ts | 9 +++++-- .../DTO/create-subscription.dto.ts | 27 +++++++++++++++++++ .../entities/subscription.entity.ts | 11 +++++--- .../entities/user-subscription.entity.ts | 6 ++--- .../providers/subscriptions.service.ts | 11 +++++++- .../repositories/subscriptions.repository.ts | 2 +- .../user-subscriptions.repository.ts | 6 +++-- .../subscriptions/subscriptions.controller.ts | 18 ++++++++++++- .../subscriptions/subscriptions.module.ts | 4 +-- 14 files changed, 110 insertions(+), 44 deletions(-) create mode 100644 src/modules/subscriptions/DTO/create-subscription.dto.ts diff --git a/src/common/entities/base.entity.ts b/src/common/entities/base.entity.ts index b5cdca3..072a5ce 100644 --- a/src/common/entities/base.entity.ts +++ b/src/common/entities/base.entity.ts @@ -4,11 +4,9 @@ export abstract class BaseEntity { @PrimaryGeneratedColumn("uuid") id: string; - @CreateDateColumn({ - type: "timestamptz", - }) + @CreateDateColumn({ type: "timestamptz" }) createdAt: Date; - @UpdateDateColumn() + @UpdateDateColumn({ type: "timestamptz" }) updatedAt: Date; } diff --git a/src/common/enums/message.enum.ts b/src/common/enums/message.enum.ts index de2e532..cd16b4e 100644 --- a/src/common/enums/message.enum.ts +++ b/src/common/enums/message.enum.ts @@ -270,3 +270,15 @@ export const enum NotificationMessage { LOGIN_MESSAGE = "یک لاگین به حساب کاربری شما صورت گرفت", NOTIFICATION_NOT_FOUND_OR_ACCESS_DENIED = "اعلان یافت نشد یا دسترسی غیرمجاز است", } + +export const enum SubscriptionMessage { + DURATION_SHOULD_BE_INT = "مدت زمان باید یک عدد صحیح باشد", + DURATION_REQUIRED = "مدت زمان مورد نیاز است", + PRICE_REQUIRED = "قیمت مورد نیاز است", + PRICE_SHOULD_BE_INT = "قیمت باید یک عدد صحیح باشد", + NAME_REQUIRED = "نام مورد نیاز است", + NAME_SHOULD_BE_STRING = "نام باید یک رشته باشد", + NAME_LENGTH = "نام باید بین ۳ تا ۱۰۰ کاراکتر باشد", + IS_ACTIVE_REQUIRED = "وضعیت فعال بودن مورد نیاز است", + IS_ACTIVE_SHOULD_BE_BOOLEAN = "وضعیت فعال بودن باید یک بولین باشد", +} diff --git a/src/modules/danak-services/danak-services.controller.ts b/src/modules/danak-services/danak-services.controller.ts index 08e883a..38877fb 100644 --- a/src/modules/danak-services/danak-services.controller.ts +++ b/src/modules/danak-services/danak-services.controller.ts @@ -9,9 +9,7 @@ import { DanakServicesService } from "./providers/danak-services.service"; import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; import { Pagination } from "../../common/decorators/pagination.decorator"; import { Roles } from "../../common/decorators/roles.decorator"; -import { UserDec } from "../../common/decorators/user.decorator"; import { ParamDto } from "../../common/DTO/param.dto"; -import { User } from "../users/entities/user.entity"; import { RoleEnum } from "../users/enums/role.enum"; @Controller("services") @@ -79,11 +77,11 @@ export class DanakServicesController { return this.danakServicesService.toggleServiceStatus(paramDto); } - @AuthGuards() - @Roles(RoleEnum.USER) - @ApiOperation({ summary: "get all user purchased danak services" }) - @Get("user-services") - getUserServices(@UserDec() user: User) { - return this.danakServicesService.getUserServices(user.id); - } + // @AuthGuards() + // @Roles(RoleEnum.USER) + // @ApiOperation({ summary: "get all user purchased danak services" }) + // @Get("user-services") + // getUserServices(@UserDec() user: User) { + // return this.danakServicesService.getUserServices(user.id); + // } } diff --git a/src/modules/danak-services/providers/danak-services.service.ts b/src/modules/danak-services/providers/danak-services.service.ts index 230df4f..b3896d9 100644 --- a/src/modules/danak-services/providers/danak-services.service.ts +++ b/src/modules/danak-services/providers/danak-services.service.ts @@ -79,15 +79,15 @@ export class DanakServicesService { } /******************************************** */ - async getUserServices(userId: string) { - const userServices = await this.danakServicesRepository.find({ - where: { users: { id: userId } }, - }); + // async getUserServices(userId: string) { + // const userServices = await this.danakServicesRepository.find({ + // where: { users: { id: userId } }, + // }); - return { - userServices, - }; - } + // return { + // userServices, + // }; + // } /******************************************** */ async toggleCategoryStatus(paramDto: ParamDto) { diff --git a/src/modules/notifications/entities/notification.entity.ts b/src/modules/notifications/entities/notification.entity.ts index 053f166..e767c48 100644 --- a/src/modules/notifications/entities/notification.entity.ts +++ b/src/modules/notifications/entities/notification.entity.ts @@ -6,17 +6,13 @@ import { NotificationType } from "../enums/notification-type.enum"; @Entity() export class Notification extends BaseEntity { - @Column({ type: "varchar", length: 250 }) + @Column({ type: "varchar", length: 250, nullable: false }) title: string; - @Column({ type: "text" }) + @Column({ type: "text", nullable: false }) message: string; - @Column({ - type: "enum", - enum: NotificationType, - default: NotificationType.LOGIN, - }) + @Column({ type: "enum", enum: NotificationType, default: NotificationType.LOGIN }) type: NotificationType; @Column({ type: "boolean", default: false }) diff --git a/src/modules/notifications/notifications.controller.ts b/src/modules/notifications/notifications.controller.ts index 92ca9c5..db87f79 100644 --- a/src/modules/notifications/notifications.controller.ts +++ b/src/modules/notifications/notifications.controller.ts @@ -5,7 +5,10 @@ import { SearchNotificationQueryDto } from "./DTO/search-notification-query.dto" import { NotificationsService } from "./providers/notifications.service"; import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; import { Pagination } from "../../common/decorators/pagination.decorator"; +import { Roles } from "../../common/decorators/roles.decorator"; import { UserDec } from "../../common/decorators/user.decorator"; +import { ParamDto } from "../../common/DTO/param.dto"; +import { RoleEnum } from "../users/enums/role.enum"; @Controller("notifications") @ApiTags("Notifications") @@ -17,6 +20,7 @@ export class NotificationController { @ApiOperation({ summary: "all notifications by user" }) @Pagination() @AuthGuards() + @Roles(RoleEnum.USER) @Get() getAllNotifications(@UserDec("id") userId: string, @Query() queryDto: SearchNotificationQueryDto) { console.log(userId); @@ -27,9 +31,10 @@ export class NotificationController { @ApiOperation({ summary: "mark user notification as read" }) @AuthGuards() + @Roles(RoleEnum.USER) @Patch(":id/read") - markAsRead(@Param("id") id: string, @UserDec("id") userId: string) { - return this.notificationService.markAsRead(id, userId); + markAsRead(@Param() paramDto: ParamDto, @UserDec("id") userId: string) { + return this.notificationService.markAsRead(paramDto.id, userId); } //********************* */ diff --git a/src/modules/subscriptions/DTO/create-subscription.dto.ts b/src/modules/subscriptions/DTO/create-subscription.dto.ts new file mode 100644 index 0000000..3e5eaae --- /dev/null +++ b/src/modules/subscriptions/DTO/create-subscription.dto.ts @@ -0,0 +1,27 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { IsBoolean, IsInt, IsNotEmpty, IsString, Length } from "class-validator"; + +import { SubscriptionMessage } from "../../../common/enums/message.enum"; + +export class CreateSubscriptionPlanDto { + @IsNotEmpty({ message: SubscriptionMessage.NAME_REQUIRED }) + @IsString({ message: SubscriptionMessage.NAME_SHOULD_BE_STRING }) + @Length(3, 100, { message: SubscriptionMessage.NAME_LENGTH }) + @ApiProperty({ description: "the name of the subscription plan", example: "یک ماهه" }) + name: string; + + @IsNotEmpty({ message: SubscriptionMessage.DURATION_REQUIRED }) + @IsInt({ message: SubscriptionMessage.DURATION_SHOULD_BE_INT }) + @ApiProperty({ description: "the duration of the subscription plan in days", example: 30 }) + duration: number; + + @IsNotEmpty({ message: SubscriptionMessage.PRICE_REQUIRED }) + @IsInt({ message: SubscriptionMessage.PRICE_SHOULD_BE_INT }) + @ApiProperty({ description: "the price of the subscription plan", example: 10_000_000 }) + price: number; + + @IsNotEmpty({ message: SubscriptionMessage.IS_ACTIVE_REQUIRED }) + @IsBoolean({ message: SubscriptionMessage.IS_ACTIVE_SHOULD_BE_BOOLEAN }) + @ApiProperty({ description: "the status of the subscription plan", example: true }) + isActive: boolean; +} diff --git a/src/modules/subscriptions/entities/subscription.entity.ts b/src/modules/subscriptions/entities/subscription.entity.ts index f7e6e9e..c13cd33 100644 --- a/src/modules/subscriptions/entities/subscription.entity.ts +++ b/src/modules/subscriptions/entities/subscription.entity.ts @@ -1,19 +1,22 @@ +// eslint-disable-next-line import/no-named-as-default +import Decimal from "decimal.js"; import { Column, Entity, ManyToOne } from "typeorm"; import { BaseEntity } from "../../../common/entities/base.entity"; +import { DecimalTransformer } from "../../../common/transformers/decimal.transformer"; import { DanakService } from "../../danak-services/entities/danak-service.entity"; @Entity() export class SubscriptionPlan extends BaseEntity { - @Column({ type: "varchar", length: 100, nullable: false }) + @Column({ type: "varchar", length: 150, nullable: false }) name: string; @Column({ type: "int", nullable: false }) duration: number; - @Column({ type: "decimal", precision: 10, scale: 2, nullable: false }) - price: number; - + @Column({ type: "decimal", precision: 16, scale: 2, nullable: false, transformer: new DecimalTransformer() }) + price: Decimal; + // @Column({ type: "boolean", default: true }) isActive: boolean; diff --git a/src/modules/subscriptions/entities/user-subscription.entity.ts b/src/modules/subscriptions/entities/user-subscription.entity.ts index ec4228a..1f435e2 100644 --- a/src/modules/subscriptions/entities/user-subscription.entity.ts +++ b/src/modules/subscriptions/entities/user-subscription.entity.ts @@ -12,12 +12,12 @@ export class UserSubscription extends BaseEntity { @ManyToOne(() => SubscriptionPlan, { nullable: false, onDelete: "CASCADE" }) plan: SubscriptionPlan; - @Column({ type: "timestamp", nullable: false }) // When the subscription started + @Column({ type: "timestamp", nullable: false }) startDate: Date; - @Column({ type: "timestamp", nullable: false }) // When it expires + @Column({ type: "timestamp", nullable: false }) endDate: Date; - @Column({ type: "boolean", default: false }) // Whether the user canceled it + @Column({ type: "boolean", default: false }) isCanceled: boolean; } diff --git a/src/modules/subscriptions/providers/subscriptions.service.ts b/src/modules/subscriptions/providers/subscriptions.service.ts index 6851936..5aeda79 100644 --- a/src/modules/subscriptions/providers/subscriptions.service.ts +++ b/src/modules/subscriptions/providers/subscriptions.service.ts @@ -1,4 +1,13 @@ import { Injectable } from "@nestjs/common"; +import { CreateSubscriptionPlanDto } from "../DTO/create-subscription.dto"; +import { SubscriptionsPlanRepository } from "../repositories/subscriptions.repository"; + @Injectable() -export class SubscriptionsService {} +export class SubscriptionsService { + constructor(private readonly subscriptionsPlanRepository: SubscriptionsPlanRepository) {} + + async createSubscriptionsPlan(createDto: CreateSubscriptionPlanDto) { + console.log(this.subscriptionsPlanRepository, createDto); + } +} diff --git a/src/modules/subscriptions/repositories/subscriptions.repository.ts b/src/modules/subscriptions/repositories/subscriptions.repository.ts index f3480ac..5d69012 100644 --- a/src/modules/subscriptions/repositories/subscriptions.repository.ts +++ b/src/modules/subscriptions/repositories/subscriptions.repository.ts @@ -5,7 +5,7 @@ import { Repository } from "typeorm"; import { SubscriptionPlan } from "../entities/subscription.entity"; @Injectable() -export class SubscriptionsRepository extends Repository { +export class SubscriptionsPlanRepository extends Repository { constructor(@InjectRepository(SubscriptionPlan) subscriptionPlanRepository: Repository) { super(subscriptionPlanRepository.target, subscriptionPlanRepository.manager, subscriptionPlanRepository.queryRunner); } diff --git a/src/modules/subscriptions/repositories/user-subscriptions.repository.ts b/src/modules/subscriptions/repositories/user-subscriptions.repository.ts index d9708f8..bb4aa94 100644 --- a/src/modules/subscriptions/repositories/user-subscriptions.repository.ts +++ b/src/modules/subscriptions/repositories/user-subscriptions.repository.ts @@ -2,9 +2,11 @@ import { Injectable } from "@nestjs/common"; import { InjectRepository } from "@nestjs/typeorm"; import { Repository } from "typeorm"; +import { UserSubscription } from "../entities/user-subscription.entity"; + @Injectable() -export class UserSubscriptionsRepository extends Repository { - constructor(@InjectRepository(UserSubscriptionsRepository) userSubscriptionsRepository: Repository) { +export class UserSubscriptionsRepository extends Repository { + constructor(@InjectRepository(UserSubscription) userSubscriptionsRepository: Repository) { super(userSubscriptionsRepository.target, userSubscriptionsRepository.manager, userSubscriptionsRepository.queryRunner); } } diff --git a/src/modules/subscriptions/subscriptions.controller.ts b/src/modules/subscriptions/subscriptions.controller.ts index 6f7183f..43a3533 100644 --- a/src/modules/subscriptions/subscriptions.controller.ts +++ b/src/modules/subscriptions/subscriptions.controller.ts @@ -1,4 +1,20 @@ import { Controller } from "@nestjs/common"; +import { ApiOperation } from "@nestjs/swagger"; + +import { SubscriptionsService } from "./providers/subscriptions.service"; +import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; +import { Roles } from "../../common/decorators/roles.decorator"; +import { RoleEnum } from "../users/enums/role.enum"; @Controller("subscriptions") -export class SubscriptionsController {} +export class SubscriptionsController { + constructor(private readonly subscriptionService: SubscriptionsService) {} + + @ApiOperation({ summary: "Create a subscription plan" }) + @AuthGuards() + @Roles(RoleEnum.ADMIN) + createSubscription() { + console.log(this.subscriptionService); + // return this.subscriptionService.createSubscriptionsPlan(); + } +} diff --git a/src/modules/subscriptions/subscriptions.module.ts b/src/modules/subscriptions/subscriptions.module.ts index 56d9c7a..014d7a5 100644 --- a/src/modules/subscriptions/subscriptions.module.ts +++ b/src/modules/subscriptions/subscriptions.module.ts @@ -4,13 +4,13 @@ import { TypeOrmModule } from "@nestjs/typeorm"; import { SubscriptionPlan } from "./entities/subscription.entity"; import { UserSubscription } from "./entities/user-subscription.entity"; import { SubscriptionsService } from "./providers/subscriptions.service"; -import { SubscriptionsRepository } from "./repositories/subscriptions.repository"; +import { SubscriptionsPlanRepository } from "./repositories/subscriptions.repository"; import { UserSubscriptionsRepository } from "./repositories/user-subscriptions.repository"; import { SubscriptionsController } from "./subscriptions.controller"; @Module({ imports: [TypeOrmModule.forFeature([SubscriptionPlan, UserSubscription])], - providers: [SubscriptionsService, SubscriptionsRepository, UserSubscriptionsRepository], + providers: [SubscriptionsService, SubscriptionsPlanRepository, UserSubscriptionsRepository], controllers: [SubscriptionsController], exports: [SubscriptionsService], })