import { ForbiddenException, Inject, Injectable, NotFoundException, } from '@nestjs/common'; import { CreateNewOrganizationRequestDTO, UpdateOrganizationRequestDTO, } from './dtos'; import { PrismaService } from 'src/prisma/prisma.service'; import { ORG_ROLE } from 'prisma/generated/prisma/enums'; import { AuthorizationService } from 'src/authorization/authorization.service'; import { USER_ORGANIZATION_OPERATIONS } from 'src/authorization/operations'; import { CacheService } from 'src/cache/cache.service'; @Injectable() export class OrganizationService { constructor( private readonly prisma: PrismaService, // private readonly reqContext: RequestContextService, private readonly authorization: AuthorizationService, private readonly cacheService: CacheService, ) {} async createNewOrganization( userId: string, dto: CreateNewOrganizationRequestDTO, ) { return await this.prisma.$transaction(async (tx) => { const newOrganization = await tx.organization.create({ data: dto, }); await tx.organizationUserJoinTable.create({ data: { orgId: newOrganization.id, userId: userId, role: ORG_ROLE.owner, }, }); return newOrganization; }); } // NOTE: Pagination async getOrganizations() { return await this.prisma.organization.findMany(); } async getOrganizationById(orgId: string) { const orgExists = await this.findById(orgId); if (!orgExists) throw new NotFoundException('Organization'); return orgExists; } async updateAnOrganization( userId: string, orgId: string, dto: UpdateOrganizationRequestDTO, ) { const orgExists = await this.organizationExists(orgId); if (!orgExists) throw new NotFoundException('Organization'); const canUserUpdateOrganization = await this.authorization.canPerformOperation( userId, orgId, USER_ORGANIZATION_OPERATIONS.UPDATE_ORGANIZATION, ); if (!canUserUpdateOrganization) throw new ForbiddenException('Not enough permission'); return this.prisma.organization.update({ where: { id: orgId, }, data: dto, }); } // TODO: Either empty or choose someone to be owner async deleteAnOrganization(userId: string, orgId: string) { const orgExists = await this.organizationExists(orgId); if (!orgExists) throw new NotFoundException('Organization'); const canUserDeleteOrganization = await this.authorization.canPerformOperation( userId, orgId, USER_ORGANIZATION_OPERATIONS.DELETE_ORGANIZATION, ); if (!canUserDeleteOrganization) throw new ForbiddenException('Not enough permission'); return await this.prisma.$transaction(async (tx) => { const deletedOrganization = await tx.organization.delete({ where: { id: orgId, }, }); await tx.organizationUserJoinTable.delete({ where: { userId_orgId: { userId, orgId, }, }, }); await this.cacheService.deleteKey(orgId); return deletedOrganization; }); } async organizationExists(orgId: string) { return await this.prisma.organization.findUnique({ where: { id: orgId }, select: { id: true }, }); } async findById(orgId: string) { const organization = await this.cacheService.getOrSet( orgId, async () => await this.prisma.organization.findUnique({ where: { id: orgId }, }), ); return organization; } }