Help reps capture a customer's likely behavior style and get negotiation guidance, with the feature gated from super admin. Co-authored-by: Cursor <cursoragent@cursor.com>
40 lines
1.4 KiB
TypeScript
40 lines
1.4 KiB
TypeScript
import { ForbiddenException, Injectable } from '@nestjs/common';
|
|
import type { Actor } from '../common/record-scope';
|
|
import { BillingService } from '../billing/billing.service';
|
|
import { PrismaService } from '../prisma/prisma.service';
|
|
|
|
@Injectable()
|
|
export class BehaviorAccessService {
|
|
constructor(
|
|
private readonly prisma: PrismaService,
|
|
private readonly billing: BillingService,
|
|
) {}
|
|
|
|
async canView(actor: Actor): Promise<boolean> {
|
|
const org = await this.prisma.organization.findUnique({
|
|
where: { id: actor.organizationId },
|
|
select: { enabledModules: true },
|
|
});
|
|
if (!this.billing.normalizeModules(org?.enabledModules).includes('behavior')) {
|
|
return false;
|
|
}
|
|
if (actor.role === 'owner' || actor.role === 'admin') return true;
|
|
const membership = await this.prisma.membership.findFirst({
|
|
where: {
|
|
userId: actor.userId,
|
|
organizationId: actor.organizationId,
|
|
isActive: true,
|
|
},
|
|
select: { orgRole: { select: { permissions: true } } },
|
|
});
|
|
const permissions = membership?.orgRole?.permissions ?? [];
|
|
return permissions.includes('behavior') || permissions.includes('sales');
|
|
}
|
|
|
|
async assert(actor: Actor): Promise<void> {
|
|
if (!(await this.canView(actor))) {
|
|
throw new ForbiddenException('دسترسی به تحلیل رفتاری و دستیار فروش ندارید');
|
|
}
|
|
}
|
|
}
|