Files
MultiTenantSaaS/src/organization/organization.service.ts
sauravdhakal12 024702dd26 wip: added cache
2026-02-27 21:26:36 +05:45

140 lines
3.5 KiB
TypeScript

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;
}
}