diff --git a/src/app.module.ts b/src/app.module.ts index 4a0ab3b..588ab9b 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -21,6 +21,7 @@ import { EmailModule } from "./modules/email/email.module"; import { MailServerModule } from "./modules/mail-server/mail-server.module"; import { MailboxModule } from "./modules/mailbox/mailbox.module"; import { QuotaSyncModule } from "./modules/quota-sync/quota-sync.module"; +import { EmailSignaturesModule } from "./modules/signatures/email-signatures.module"; import { UsersModule } from "./modules/users/users.module"; import { UtilsModule } from "./modules/utils/utils.module"; @@ -42,6 +43,7 @@ import { UtilsModule } from "./modules/utils/utils.module"; MailboxModule, MailServerModule, QuotaSyncModule, + EmailSignaturesModule, ], }) export class AppModule implements NestModule { diff --git a/src/modules/businesses/entities/business.entity.ts b/src/modules/businesses/entities/business.entity.ts index d821f0b..7225cd1 100644 --- a/src/modules/businesses/entities/business.entity.ts +++ b/src/modules/businesses/entities/business.entity.ts @@ -3,6 +3,7 @@ import { Cascade, Collection, Entity, EntityRepositoryType, OneToMany, OneToOne, import { BusinessStaff } from "./business-staff.entity"; import { BaseEntity } from "../../../common/entities/base.entity"; import { Domain } from "../../domains/entities/domain.entity"; +import { EmailSignature } from "../../signatures/entities/email-signature.entity"; import { BusinessRepository } from "../repositories/business.repository"; @Entity({ repository: () => BusinessRepository }) @@ -36,6 +37,10 @@ export class Business extends BaseEntity { //========================= + @OneToOne(() => EmailSignature, (signature) => signature.business, { nullable: true, deleteRule: "cascade" }) + emailSignature?: EmailSignature; + //========================= + // @OneToMany(() => User, (user) => user.business) // users = new Collection(this); diff --git a/src/modules/signatures/email-signatures.controller.ts b/src/modules/signatures/email-signatures.controller.ts index 1992e22..7bc9c07 100644 --- a/src/modules/signatures/email-signatures.controller.ts +++ b/src/modules/signatures/email-signatures.controller.ts @@ -1,63 +1,58 @@ -import { Body, Controller, Delete, Get, Param, Patch, Post, Put } from "@nestjs/common"; +import { Body, Controller, Delete, Get, Param, Patch, Post } from "@nestjs/common"; +import { UseInterceptors } from "@nestjs/common"; import { ApiOperation, ApiResponse } from "@nestjs/swagger"; import { CreateEmailSignatureDto } from "./DTO/create-email-signature.dto"; import { UpdateEmailSignatureDto } from "./DTO/update-email-signature.dto"; -import { EmailSignature } from "./entities/email-signature.entity"; import { EmailSignaturesService } from "./services/email-signatures.service"; import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; -import { UserDec } from "../../common/decorators/user.decorator"; -import { User } from "../users/entities/user.entity"; +import { BusinessDec } from "../../common/decorators/business.decorator"; +import { BusinessInterceptor } from "../../core/interceptors/business.interceptor"; +import { Business } from "../businesses/entities/business.entity"; @Controller("email-signatures") +@UseInterceptors(BusinessInterceptor) @AuthGuards() export class EmailSignaturesController { constructor(private readonly emailSignaturesService: EmailSignaturesService) {} @Post() @ApiOperation({ summary: "Create a new email signature" }) - @ApiResponse({ status: 201, description: "Email signature created successfully", type: EmailSignature }) + @ApiResponse({ status: 201, description: "Email signature created successfully" }) @ApiResponse({ status: 400, description: "Bad request" }) - create(@UserDec() user: User, @Body() createEmailSignatureDto: CreateEmailSignatureDto) { - return this.emailSignaturesService.create(user.id, createEmailSignatureDto); + create(@BusinessDec() business: Business, @Body() createEmailSignatureDto: CreateEmailSignatureDto) { + return this.emailSignaturesService.create(business, createEmailSignatureDto); } - @Get("active") - @ApiOperation({ summary: "Get all active email signatures for the user" }) - @ApiResponse({ status: 200, description: "Active email signatures retrieved successfully", type: [EmailSignature] }) - findActive(@UserDec() user: User) { - return this.emailSignaturesService.findActive(user.id); - } - - @Get(":id") + @Get() @ApiOperation({ summary: "Get a specific email signature" }) - @ApiResponse({ status: 200, description: "Email signature retrieved successfully", type: EmailSignature }) + @ApiResponse({ status: 200, description: "Email signature retrieved successfully" }) @ApiResponse({ status: 404, description: "Email signature not found" }) - findOne(@Param("id") id: string, @UserDec() user: User) { - return this.emailSignaturesService.findOne(id, user.id); + findOne(@BusinessDec() business: Business) { + return this.emailSignaturesService.getBusinessSignature(business); } @Patch(":id") @ApiOperation({ summary: "Update an email signature" }) - @ApiResponse({ status: 200, description: "Email signature updated successfully", type: EmailSignature }) + @ApiResponse({ status: 200, description: "Email signature updated successfully" }) @ApiResponse({ status: 404, description: "Email signature not found" }) - update(@Param("id") id: string, @UserDec() user: User, @Body() updateEmailSignatureDto: UpdateEmailSignatureDto) { - return this.emailSignaturesService.update(id, user.id, updateEmailSignatureDto); + update(@Param("id") id: string, @BusinessDec() business: Business, @Body() updateEmailSignatureDto: UpdateEmailSignatureDto) { + return this.emailSignaturesService.update(id, business, updateEmailSignatureDto); } - @Put(":id/toggle-active") + @Patch(":id/toggle-active") @ApiOperation({ summary: "Activate an email signature" }) - @ApiResponse({ status: 200, description: "Email signature activated successfully", type: EmailSignature }) + @ApiResponse({ status: 200, description: "Email signature activated successfully" }) @ApiResponse({ status: 404, description: "Email signature not found" }) - toggleActive(@Param("id") id: string, @UserDec() user: User) { - return this.emailSignaturesService.toggleActive(id, user.id); + toggleActive(@Param("id") id: string, @BusinessDec() business: Business) { + return this.emailSignaturesService.toggleActive(id, business); } @Delete(":id") @ApiOperation({ summary: "Delete an email signature" }) @ApiResponse({ status: 200, description: "Email signature deleted successfully" }) @ApiResponse({ status: 404, description: "Email signature not found" }) - remove(@Param("id") id: string, @UserDec() user: User) { - return this.emailSignaturesService.remove(id, user.id); + remove(@Param("id") id: string, @BusinessDec() business: Business) { + return this.emailSignaturesService.remove(id, business); } } diff --git a/src/modules/signatures/email-signatures.module.ts b/src/modules/signatures/email-signatures.module.ts index 25fa469..e0bce38 100644 --- a/src/modules/signatures/email-signatures.module.ts +++ b/src/modules/signatures/email-signatures.module.ts @@ -3,13 +3,13 @@ import { Module } from "@nestjs/common"; import { EmailSignaturesController } from "./email-signatures.controller"; import { EmailSignature } from "./entities/email-signature.entity"; -import { EmailSignatureRepository } from "./repositories/email-signature.repository"; import { EmailSignaturesService } from "./services/email-signatures.service"; +import { BusinessesModule } from "../businesses/businesses.module"; @Module({ - imports: [MikroOrmModule.forFeature([EmailSignature])], + imports: [MikroOrmModule.forFeature([EmailSignature]), BusinessesModule], controllers: [EmailSignaturesController], - providers: [EmailSignaturesService, EmailSignatureRepository], + providers: [EmailSignaturesService], exports: [EmailSignaturesService], }) export class EmailSignaturesModule {} diff --git a/src/modules/signatures/entities/email-signature.entity.ts b/src/modules/signatures/entities/email-signature.entity.ts index ad204a3..0346739 100644 --- a/src/modules/signatures/entities/email-signature.entity.ts +++ b/src/modules/signatures/entities/email-signature.entity.ts @@ -1,14 +1,14 @@ import { Entity, EntityRepositoryType, Index, OneToOne, Opt, Property } from "@mikro-orm/core"; import { BaseEntity } from "../../../common/entities/base.entity"; -import { User } from "../../users/entities/user.entity"; +import { Business } from "../../businesses/entities/business.entity"; import { EmailSignatureRepository } from "../repositories/email-signature.repository"; @Entity({ repository: () => EmailSignatureRepository }) -@Index({ properties: ["user", "isActive"] }) +@Index({ properties: ["business", "isActive"] }) export class EmailSignature extends BaseEntity { - @OneToOne(() => User, (user) => user.emailSignature, { owner: true, deleteRule: "cascade" }) - user!: User; + @OneToOne(() => Business, (business) => business.emailSignature, { owner: true, deleteRule: "cascade" }) + business!: Business; @Property({ type: "varchar", length: 100 }) name!: string; @@ -16,9 +16,6 @@ export class EmailSignature extends BaseEntity { @Property({ type: "text", nullable: true }) textContent?: string; - // @Property({ type: "text", nullable: true }) - // htmlContent?: string; - @Property({ type: "boolean", default: true }) isActive!: boolean & Opt; diff --git a/src/modules/signatures/repositories/email-signature.repository.ts b/src/modules/signatures/repositories/email-signature.repository.ts index 7308673..f17b757 100644 --- a/src/modules/signatures/repositories/email-signature.repository.ts +++ b/src/modules/signatures/repositories/email-signature.repository.ts @@ -3,15 +3,15 @@ import { EntityRepository } from "@mikro-orm/postgresql"; import { EmailSignature } from "../entities/email-signature.entity"; export class EmailSignatureRepository extends EntityRepository { - async findByUserId(userId: string): Promise { - return this.find({ user: userId }, { orderBy: { createdAt: "DESC" } }); + async findByBusinessId(businessId: string): Promise { + return this.findOne({ business: { id: businessId } }, { orderBy: { createdAt: "DESC" } }); } - async findActiveByUserId(userId: string): Promise { - return this.find({ user: userId, isActive: true }, { orderBy: { createdAt: "DESC" } }); + async findActiveByBusinessId(businessId: string): Promise { + return this.find({ business: { id: businessId }, isActive: true }, { orderBy: { createdAt: "DESC" } }); } - async findByIdAndUserId(id: string, userId: string): Promise { - return this.findOne({ id, user: userId }); + async findByIdAndBusinessId(id: string, businessId: string): Promise { + return this.findOne({ id, business: { id: businessId } }); } } diff --git a/src/modules/signatures/services/email-signatures.service.ts b/src/modules/signatures/services/email-signatures.service.ts index b2997f6..94fb53c 100644 --- a/src/modules/signatures/services/email-signatures.service.ts +++ b/src/modules/signatures/services/email-signatures.service.ts @@ -1,8 +1,8 @@ -import { EntityManager } from "@mikro-orm/core"; -import { BadRequestException, Injectable, NotFoundException } from "@nestjs/common"; +import { EntityManager } from "@mikro-orm/postgresql"; +import { BadRequestException, Injectable } from "@nestjs/common"; -import { SignatureMessage, UserMessage } from "../../../common/enums/message.enum"; -import { User } from "../../users/entities/user.entity"; +import { SignatureMessage } from "../../../common/enums/message.enum"; +import { Business } from "../../businesses/entities/business.entity"; import { CreateEmailSignatureDto } from "../DTO/create-email-signature.dto"; import { UpdateEmailSignatureDto } from "../DTO/update-email-signature.dto"; import { EmailSignatureRepository } from "../repositories/email-signature.repository"; @@ -14,13 +14,10 @@ export class EmailSignaturesService { private readonly em: EntityManager, ) {} //######################### - async create(userId: string, createDto: CreateEmailSignatureDto) { - const user = await this.em.findOne(User, { id: userId, deletedAt: null }); - if (!user) throw new NotFoundException(UserMessage.USER_NOT_FOUND); - + async create(business: Business, createDto: CreateEmailSignatureDto) { const signature = this.emailSignatureRepository.create({ ...createDto, - user, + business, }); await this.em.persistAndFlush(signature); @@ -29,19 +26,11 @@ export class EmailSignaturesService { signature, }; } - //######################### - - async findActive(userId: string) { - const signatures = await this.emailSignatureRepository.findActiveByUserId(userId); - return { - signatures, - }; - } //######################### - async update(id: string, userId: string, updateDto: UpdateEmailSignatureDto) { - const { signature } = await this.findOne(id, userId); + async update(id: string, business: Business, updateDto: UpdateEmailSignatureDto) { + const { signature } = await this.findOne(id, business); this.emailSignatureRepository.assign(signature, updateDto); await this.em.flush(); @@ -49,15 +38,15 @@ export class EmailSignaturesService { } //######################### - async remove(id: string, userId: string) { - const { signature } = await this.findOne(id, userId); + async remove(id: string, business: Business) { + const { signature } = await this.findOne(id, business); await this.em.removeAndFlush(signature); return { message: SignatureMessage.DELETED }; } //######################### - async toggleActive(id: string, userId: string) { - const { signature } = await this.findOne(id, userId); + async toggleActive(id: string, business: Business) { + const { signature } = await this.findOne(id, business); signature.isActive = !signature.isActive; await this.em.flush(); @@ -69,8 +58,13 @@ export class EmailSignaturesService { } //######################### - async findOne(id: string, userId: string) { - const signature = await this.emailSignatureRepository.findByIdAndUserId(id, userId); + async getBusinessSignature(business: Business) { + const signature = await this.emailSignatureRepository.findByBusinessId(business.id); + return { signature }; + } + + async findOne(id: string, business: Business) { + const signature = await this.emailSignatureRepository.findByIdAndBusinessId(id, business.id); if (!signature) throw new BadRequestException(SignatureMessage.NOT_FOUND); return { signature }; diff --git a/src/modules/users/entities/user.entity.ts b/src/modules/users/entities/user.entity.ts index fd26fd3..7313a26 100644 --- a/src/modules/users/entities/user.entity.ts +++ b/src/modules/users/entities/user.entity.ts @@ -1,11 +1,10 @@ -import { Collection, Entity, EntityRepositoryType, ManyToOne, OneToMany, OneToOne, Opt, Property, Unique } from "@mikro-orm/core"; +import { Collection, Entity, EntityRepositoryType, ManyToOne, OneToMany, Opt, Property, Unique } from "@mikro-orm/core"; import { RefreshToken } from "./refresh-token.entity"; import { Role } from "./role.entity"; import { BaseEntity } from "../../../common/entities/base.entity"; import { Business } from "../../businesses/entities/business.entity"; import { Domain } from "../../domains/entities/domain.entity"; -import { EmailSignature } from "../../signatures/entities/email-signature.entity"; import { UserRepository } from "../repositories/user.repository"; @Entity({ repository: () => UserRepository }) @@ -47,11 +46,6 @@ export class User extends BaseEntity { //========================= - @OneToOne(() => EmailSignature, (signature) => signature.user, { nullable: true, deleteRule: "cascade" }) - emailSignature?: EmailSignature; - - //========================= - @OneToMany(() => RefreshToken, (token) => token.user) refreshTokens = new Collection(this);