Files
dyolink/backend/src/common/membership-permissions.ts

97 lines
2.8 KiB
TypeScript

import {
ownerPermissionsForOrgType,
type OrganizationTypeName,
} from './organization-type';
import { normalizeTabPermissions } from './permissions';
export const CLINIC_PARTICIPATION_PERMISSIONS = [
'TAB_TREATMENT_READ',
'TAB_TREATMENT_EDIT',
] as const;
export const LAB_PARTICIPATION_PERMISSIONS = [
'TAB_TASKS_READ',
'TAB_TASKS_EDIT',
] as const;
const CLINIC_PARTICIPATION_SET = new Set<string>(CLINIC_PARTICIPATION_PERMISSIONS);
const LAB_PARTICIPATION_SET = new Set<string>(LAB_PARTICIPATION_PERMISSIONS);
export type MembershipWithPermissions = {
isOwner: boolean;
organization: {
plan?: { name: string; maxUsers?: number; price?: number } | null;
planId?: string | null;
type?: { name: string };
};
permissions?: Array<{ permission: { name: string } }>;
};
export function getOrgTypeFromMembership(
membership: MembershipWithPermissions,
): OrganizationTypeName {
return membership.organization.type?.name === 'LAB' ? 'LAB' : 'CLINIC';
}
export function hasActivePlan(membership: MembershipWithPermissions): boolean {
if (membership.organization.plan != null) {
return true;
}
return Boolean(membership.organization.planId);
}
export function getStoredPermissionNames(
membership: MembershipWithPermissions,
): string[] {
return membership.permissions?.map((p) => p.permission.name) ?? [];
}
export function getEffectivePermissionNames(
membership: MembershipWithPermissions,
): string[] {
const stored = getStoredPermissionNames(membership);
if (!membership.isOwner) {
return normalizeTabPermissions(stored);
}
const orgType = getOrgTypeFromMembership(membership);
const base = ownerPermissionsForOrgType(orgType, hasActivePlan(membership));
return normalizeTabPermissions([...base, ...stored]);
}
export function hasEffectivePermission(
membership: MembershipWithPermissions,
permission: string,
): boolean {
return getEffectivePermissionNames(membership).includes(permission);
}
export function participationPermissionsForOrgType(
orgType: OrganizationTypeName,
): readonly string[] {
return orgType === 'LAB'
? LAB_PARTICIPATION_PERMISSIONS
: CLINIC_PARTICIPATION_PERMISSIONS;
}
export function participatesInTreatments(
membership: MembershipWithPermissions,
): boolean {
if (getOrgTypeFromMembership(membership) !== 'CLINIC') {
return false;
}
return getStoredPermissionNames(membership).includes('TAB_TREATMENT_EDIT');
}
export function participatesInTasks(membership: MembershipWithPermissions): boolean {
if (getOrgTypeFromMembership(membership) !== 'LAB') {
return false;
}
return getStoredPermissionNames(membership).includes('TAB_TASKS_EDIT');
}
export function isParticipationPermission(name: string): boolean {
return CLINIC_PARTICIPATION_SET.has(name) || LAB_PARTICIPATION_SET.has(name);
}