Files
alla-allaos-fullstack/src/lib/auth/rbac.ts
phaichayon 827fd13fa7 task-l.2
2026-06-22 11:39:41 +07:00

618 lines
24 KiB
TypeScript

export const SYSTEM_ROLES = ['super_admin', 'user'] as const;
export const MEMBERSHIP_ROLES = ['admin', 'user'] as const;
export const BUSINESS_ROLES = [
'marketing',
'sales',
'sales_support',
'sales_manager',
'department_manager',
'top_manager',
'crm_admin'
] as const;
export const OWNERSHIP_SCOPES = ['own', 'team', 'organization', 'monitor'] as const;
export const SCOPE_MODES = ['all', 'assigned'] as const;
export const ROLE_ASSIGNMENT_SCOPE_MODES = ['all', 'selected', 'none', 'inherit'] as const;
export const APPROVAL_AUTHORITIES = ['none', 'manager', 'department', 'final'] as const;
export type SystemRole = (typeof SYSTEM_ROLES)[number];
export type MembershipRole = (typeof MEMBERSHIP_ROLES)[number];
export type BusinessRole = string;
export type CrmOwnershipScope = (typeof OWNERSHIP_SCOPES)[number];
export type CrmScopeMode = (typeof SCOPE_MODES)[number];
export type CrmRoleAssignmentScopeMode = (typeof ROLE_ASSIGNMENT_SCOPE_MODES)[number];
export type CrmEffectiveScopeMode = 'all' | 'assigned' | 'none';
export type CrmApprovalAuthority = (typeof APPROVAL_AUTHORITIES)[number];
export const PERMISSIONS = {
productsRead: 'products:read',
productsWrite: 'products:write',
organizationManage: 'organization:manage',
usersManage: 'users:manage',
reportRead: 'report:read',
crmLeadRead: 'crm.lead.read',
crmLeadCreate: 'crm.lead.create',
crmLeadUpdate: 'crm.lead.update',
crmLeadAssign: 'crm.lead.assign',
crmLeadDelete: 'crm.lead.delete',
crmCustomerRead: 'crm.customer.read',
crmCustomerCreate: 'crm.customer.create',
crmCustomerUpdate: 'crm.customer.update',
crmCustomerDelete: 'crm.customer.delete',
crmContactRead: 'crm.contact.read',
crmContactCreate: 'crm.contact.create',
crmContactUpdate: 'crm.contact.update',
crmContactDelete: 'crm.contact.delete',
crmEnquiryRead: 'crm.enquiry.read',
crmEnquiryCreate: 'crm.enquiry.create',
crmEnquiryUpdate: 'crm.enquiry.update',
crmEnquiryDelete: 'crm.enquiry.delete',
crmEnquiryAssign: 'crm.enquiry.assign',
crmEnquiryReassign: 'crm.enquiry.reassign',
crmEnquiryFollowupRead: 'crm.enquiry.followup.read',
crmEnquiryFollowupCreate: 'crm.enquiry.followup.create',
crmEnquiryFollowupUpdate: 'crm.enquiry.followup.update',
crmEnquiryFollowupDelete: 'crm.enquiry.followup.delete',
crmQuotationRead: 'crm.quotation.read',
crmQuotationCreate: 'crm.quotation.create',
crmQuotationUpdate: 'crm.quotation.update',
crmQuotationDelete: 'crm.quotation.delete',
crmQuotationItemManage: 'crm.quotation.item.manage',
crmQuotationCustomerManage: 'crm.quotation.customer.manage',
crmQuotationTopicManage: 'crm.quotation.topic.manage',
crmQuotationFollowupManage: 'crm.quotation.followup.manage',
crmQuotationAttachmentManage: 'crm.quotation.attachment.manage',
crmQuotationRevisionCreate: 'crm.quotation.revision.create',
crmQuotationPricingRead: 'crm.quotation.pricing.read',
crmApprovalRead: 'crm.approval.read',
crmApprovalSubmit: 'crm.approval.submit',
crmApprovalApprove: 'crm.approval.approve',
crmApprovalReject: 'crm.approval.reject',
crmApprovalReturn: 'crm.approval.return',
crmApprovalWorkflowRead: 'crm.approval.workflow.read',
crmApprovalWorkflowCreate: 'crm.approval.workflow.create',
crmApprovalWorkflowUpdate: 'crm.approval.workflow.update',
crmApprovalWorkflowDelete: 'crm.approval.workflow.delete',
crmDashboardRead: 'crm.dashboard.read',
crmDashboardExport: 'crm.dashboard.export',
crmDocumentTemplateRead: 'crm.document_template.read',
crmDocumentTemplateCreate: 'crm.document_template.create',
crmDocumentTemplateUpdate: 'crm.document_template.update',
crmDocumentTemplateDelete: 'crm.document_template.delete',
crmDocumentSequenceRead: 'crm.document_sequence.read',
crmDocumentSequenceCreate: 'crm.document_sequence.create',
crmDocumentSequenceUpdate: 'crm.document_sequence.update',
crmDocumentSequenceReset: 'crm.document_sequence.reset',
crmDocumentArtifactRead: 'crm.document_artifact.read',
crmDocumentArtifactDownload: 'crm.document_artifact.download',
crmDocumentArtifactVoid: 'crm.document_artifact.void',
crmQuotationDocumentPreview: 'crm.quotation.document.preview',
crmQuotationPdfPreview: 'crm.quotation.pdf.preview',
crmQuotationPdfDownload: 'crm.quotation.pdf.download',
crmQuotationPdfGenerateApproved: 'crm.quotation.pdf.generate_approved',
crmRoleRead: 'crm.role.read',
crmRoleCreate: 'crm.role.create',
crmRoleUpdate: 'crm.role.update',
crmRoleDelete: 'crm.role.delete',
crmRoleAssign: 'crm.role.assign',
crmRoleAssignmentRead: 'crm.role.assignment.read',
crmRoleAssignmentCreate: 'crm.role.assignment.create',
crmRoleAssignmentUpdate: 'crm.role.assignment.update',
crmRoleAssignmentDelete: 'crm.role.assignment.delete',
crmRoleAssignmentManage: 'crm.role.assignment.manage',
crmUserRoleAssignmentRead: 'crm.user_role_assignment.read',
crmUserRoleAssignmentCreate: 'crm.user_role_assignment.create',
crmUserRoleAssignmentUpdate: 'crm.user_role_assignment.update',
crmUserRoleAssignmentDelete: 'crm.user_role_assignment.delete',
crmUserRoleAssignmentManage: 'crm.user_role_assignment.manage',
crmMasterOptionRead: 'crm.master_option.read',
crmMasterOptionCreate: 'crm.master_option.create',
crmMasterOptionUpdate: 'crm.master_option.update',
crmMasterOptionDelete: 'crm.master_option.delete'
} as const;
export type Permission = (typeof PERMISSIONS)[keyof typeof PERMISSIONS];
export interface CrmRoleProfileDefinition {
code: string;
name: string;
description: string;
permissions: Permission[];
ownershipScope: CrmOwnershipScope;
branchScopeMode: CrmScopeMode;
productScopeMode: CrmScopeMode;
approvalAuthority: CrmApprovalAuthority;
isSystem: boolean;
}
export interface PermissionGroup {
key: string;
label: string;
permissions: Array<{ key: Permission; label: string }>;
}
const DEFAULT_ROLE_DEFINITIONS: Record<string, Omit<CrmRoleProfileDefinition, 'code'>> = {
marketing: {
name: 'Marketing',
description: 'Lead creation, assignment, monitoring, and enquiry visibility without commercial authority.',
permissions: [
PERMISSIONS.crmLeadRead,
PERMISSIONS.crmLeadCreate,
PERMISSIONS.crmLeadUpdate,
PERMISSIONS.crmLeadAssign,
PERMISSIONS.crmCustomerRead,
PERMISSIONS.crmContactRead,
PERMISSIONS.crmEnquiryRead,
PERMISSIONS.crmEnquiryFollowupRead,
PERMISSIONS.crmDashboardRead
],
ownershipScope: 'monitor',
branchScopeMode: 'assigned',
productScopeMode: 'assigned',
approvalAuthority: 'none',
isSystem: true
},
sales: {
name: 'Sales',
description: 'Own enquiries, quotations, and follow-ups within assigned branch and product scope.',
permissions: [
PERMISSIONS.crmCustomerRead,
PERMISSIONS.crmContactRead,
PERMISSIONS.crmEnquiryRead,
PERMISSIONS.crmEnquiryCreate,
PERMISSIONS.crmEnquiryUpdate,
PERMISSIONS.crmEnquiryFollowupRead,
PERMISSIONS.crmEnquiryFollowupCreate,
PERMISSIONS.crmEnquiryFollowupUpdate,
PERMISSIONS.crmQuotationRead,
PERMISSIONS.crmQuotationCreate,
PERMISSIONS.crmQuotationUpdate,
PERMISSIONS.crmQuotationItemManage,
PERMISSIONS.crmQuotationCustomerManage,
PERMISSIONS.crmQuotationTopicManage,
PERMISSIONS.crmQuotationFollowupManage,
PERMISSIONS.crmQuotationAttachmentManage,
PERMISSIONS.crmQuotationRevisionCreate,
PERMISSIONS.crmQuotationPricingRead,
PERMISSIONS.crmApprovalRead,
PERMISSIONS.crmApprovalSubmit,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload
],
ownershipScope: 'own',
branchScopeMode: 'assigned',
productScopeMode: 'assigned',
approvalAuthority: 'none',
isSystem: true
},
sales_support: {
name: 'Sales Support',
description: 'Quotation drafting and operational support without approval authority.',
permissions: [
PERMISSIONS.crmCustomerRead,
PERMISSIONS.crmContactRead,
PERMISSIONS.crmEnquiryRead,
PERMISSIONS.crmEnquiryUpdate,
PERMISSIONS.crmEnquiryFollowupRead,
PERMISSIONS.crmEnquiryFollowupCreate,
PERMISSIONS.crmEnquiryFollowupUpdate,
PERMISSIONS.crmQuotationRead,
PERMISSIONS.crmQuotationCreate,
PERMISSIONS.crmQuotationUpdate,
PERMISSIONS.crmQuotationItemManage,
PERMISSIONS.crmQuotationCustomerManage,
PERMISSIONS.crmQuotationTopicManage,
PERMISSIONS.crmQuotationFollowupManage,
PERMISSIONS.crmQuotationAttachmentManage,
PERMISSIONS.crmQuotationRevisionCreate,
PERMISSIONS.crmQuotationPricingRead,
PERMISSIONS.crmApprovalRead,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload
],
ownershipScope: 'own',
branchScopeMode: 'assigned',
productScopeMode: 'assigned',
approvalAuthority: 'none',
isSystem: true
},
sales_manager: {
name: 'Sales Manager',
description: 'Team visibility, sales assignment, and quotation approval authority.',
permissions: [
PERMISSIONS.crmLeadRead,
PERMISSIONS.crmLeadCreate,
PERMISSIONS.crmLeadUpdate,
PERMISSIONS.crmLeadAssign,
PERMISSIONS.crmCustomerRead,
PERMISSIONS.crmCustomerCreate,
PERMISSIONS.crmCustomerUpdate,
PERMISSIONS.crmContactRead,
PERMISSIONS.crmContactCreate,
PERMISSIONS.crmContactUpdate,
PERMISSIONS.crmEnquiryRead,
PERMISSIONS.crmEnquiryCreate,
PERMISSIONS.crmEnquiryUpdate,
PERMISSIONS.crmEnquiryAssign,
PERMISSIONS.crmEnquiryReassign,
PERMISSIONS.crmEnquiryFollowupRead,
PERMISSIONS.crmEnquiryFollowupCreate,
PERMISSIONS.crmEnquiryFollowupUpdate,
PERMISSIONS.crmQuotationRead,
PERMISSIONS.crmQuotationCreate,
PERMISSIONS.crmQuotationUpdate,
PERMISSIONS.crmQuotationItemManage,
PERMISSIONS.crmQuotationCustomerManage,
PERMISSIONS.crmQuotationTopicManage,
PERMISSIONS.crmQuotationFollowupManage,
PERMISSIONS.crmQuotationAttachmentManage,
PERMISSIONS.crmQuotationRevisionCreate,
PERMISSIONS.crmQuotationPricingRead,
PERMISSIONS.crmApprovalRead,
PERMISSIONS.crmApprovalSubmit,
PERMISSIONS.crmApprovalApprove,
PERMISSIONS.crmApprovalReject,
PERMISSIONS.crmApprovalReturn,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDashboardExport,
PERMISSIONS.crmRoleAssignmentRead,
PERMISSIONS.crmUserRoleAssignmentRead,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload
],
ownershipScope: 'team',
branchScopeMode: 'assigned',
productScopeMode: 'assigned',
approvalAuthority: 'manager',
isSystem: true
},
department_manager: {
name: 'Department Manager',
description: 'Department analytics and higher-level approval authority.',
permissions: [
PERMISSIONS.crmLeadRead,
PERMISSIONS.crmCustomerRead,
PERMISSIONS.crmContactRead,
PERMISSIONS.crmEnquiryRead,
PERMISSIONS.crmEnquiryAssign,
PERMISSIONS.crmEnquiryReassign,
PERMISSIONS.crmEnquiryFollowupRead,
PERMISSIONS.crmQuotationRead,
PERMISSIONS.crmQuotationPricingRead,
PERMISSIONS.crmApprovalRead,
PERMISSIONS.crmApprovalApprove,
PERMISSIONS.crmApprovalReject,
PERMISSIONS.crmApprovalReturn,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDashboardExport,
PERMISSIONS.crmRoleAssignmentRead,
PERMISSIONS.crmUserRoleAssignmentRead,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload
],
ownershipScope: 'organization',
branchScopeMode: 'assigned',
productScopeMode: 'assigned',
approvalAuthority: 'department',
isSystem: true
},
top_manager: {
name: 'Top Manager',
description: 'Final approval authority with full CRM analytics visibility.',
permissions: [
PERMISSIONS.crmLeadRead,
PERMISSIONS.crmCustomerRead,
PERMISSIONS.crmContactRead,
PERMISSIONS.crmEnquiryRead,
PERMISSIONS.crmEnquiryAssign,
PERMISSIONS.crmEnquiryReassign,
PERMISSIONS.crmEnquiryFollowupRead,
PERMISSIONS.crmQuotationRead,
PERMISSIONS.crmQuotationPricingRead,
PERMISSIONS.crmApprovalRead,
PERMISSIONS.crmApprovalApprove,
PERMISSIONS.crmApprovalReject,
PERMISSIONS.crmApprovalReturn,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDashboardExport,
PERMISSIONS.crmRoleAssignmentRead,
PERMISSIONS.crmUserRoleAssignmentRead,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload
],
ownershipScope: 'organization',
branchScopeMode: 'all',
productScopeMode: 'all',
approvalAuthority: 'final',
isSystem: true
},
crm_admin: {
name: 'CRM Admin',
description: 'CRM configuration authority for templates, workflows, sequences, and permissions.',
permissions: [
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmRoleRead,
PERMISSIONS.crmRoleCreate,
PERMISSIONS.crmRoleUpdate,
PERMISSIONS.crmRoleDelete,
PERMISSIONS.crmRoleAssign,
PERMISSIONS.crmRoleAssignmentRead,
PERMISSIONS.crmRoleAssignmentCreate,
PERMISSIONS.crmRoleAssignmentUpdate,
PERMISSIONS.crmRoleAssignmentDelete,
PERMISSIONS.crmRoleAssignmentManage,
PERMISSIONS.crmUserRoleAssignmentRead,
PERMISSIONS.crmUserRoleAssignmentCreate,
PERMISSIONS.crmUserRoleAssignmentUpdate,
PERMISSIONS.crmUserRoleAssignmentDelete,
PERMISSIONS.crmUserRoleAssignmentManage,
PERMISSIONS.crmMasterOptionRead,
PERMISSIONS.crmMasterOptionCreate,
PERMISSIONS.crmMasterOptionUpdate,
PERMISSIONS.crmMasterOptionDelete,
PERMISSIONS.crmApprovalWorkflowRead,
PERMISSIONS.crmApprovalWorkflowCreate,
PERMISSIONS.crmApprovalWorkflowUpdate,
PERMISSIONS.crmApprovalWorkflowDelete,
PERMISSIONS.crmDocumentTemplateRead,
PERMISSIONS.crmDocumentTemplateCreate,
PERMISSIONS.crmDocumentTemplateUpdate,
PERMISSIONS.crmDocumentTemplateDelete,
PERMISSIONS.crmDocumentSequenceRead,
PERMISSIONS.crmDocumentSequenceCreate,
PERMISSIONS.crmDocumentSequenceUpdate,
PERMISSIONS.crmDocumentSequenceReset,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmDocumentArtifactVoid,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload,
PERMISSIONS.crmQuotationPdfGenerateApproved
],
ownershipScope: 'organization',
branchScopeMode: 'all',
productScopeMode: 'all',
approvalAuthority: 'none',
isSystem: true
}
};
export const CRM_PERMISSION_GROUPS: PermissionGroup[] = [
{
key: 'lead',
label: 'Leads',
permissions: [
{ key: PERMISSIONS.crmLeadRead, label: 'Read leads' },
{ key: PERMISSIONS.crmLeadCreate, label: 'Create leads' },
{ key: PERMISSIONS.crmLeadUpdate, label: 'Update leads' },
{ key: PERMISSIONS.crmLeadAssign, label: 'Assign leads' },
{ key: PERMISSIONS.crmLeadDelete, label: 'Delete leads' }
]
},
{
key: 'enquiry',
label: 'Enquiries',
permissions: [
{ key: PERMISSIONS.crmEnquiryRead, label: 'Read enquiries' },
{ key: PERMISSIONS.crmEnquiryCreate, label: 'Create enquiries' },
{ key: PERMISSIONS.crmEnquiryUpdate, label: 'Update enquiries' },
{ key: PERMISSIONS.crmEnquiryDelete, label: 'Delete enquiries' },
{ key: PERMISSIONS.crmEnquiryAssign, label: 'Assign enquiries' },
{ key: PERMISSIONS.crmEnquiryReassign, label: 'Reassign enquiries' },
{ key: PERMISSIONS.crmEnquiryFollowupRead, label: 'Read enquiry follow-ups' },
{ key: PERMISSIONS.crmEnquiryFollowupCreate, label: 'Create enquiry follow-ups' },
{ key: PERMISSIONS.crmEnquiryFollowupUpdate, label: 'Update enquiry follow-ups' },
{ key: PERMISSIONS.crmEnquiryFollowupDelete, label: 'Delete enquiry follow-ups' }
]
},
{
key: 'quotation',
label: 'Quotations',
permissions: [
{ key: PERMISSIONS.crmQuotationRead, label: 'Read quotations' },
{ key: PERMISSIONS.crmQuotationCreate, label: 'Create quotations' },
{ key: PERMISSIONS.crmQuotationUpdate, label: 'Update quotations' },
{ key: PERMISSIONS.crmQuotationDelete, label: 'Delete quotations' },
{ key: PERMISSIONS.crmQuotationPricingRead, label: 'Read quotation pricing' },
{ key: PERMISSIONS.crmQuotationItemManage, label: 'Manage quotation items' },
{ key: PERMISSIONS.crmQuotationCustomerManage, label: 'Manage quotation customers' },
{ key: PERMISSIONS.crmQuotationTopicManage, label: 'Manage quotation topics' },
{ key: PERMISSIONS.crmQuotationFollowupManage, label: 'Manage quotation follow-ups' },
{ key: PERMISSIONS.crmQuotationAttachmentManage, label: 'Manage quotation attachments' },
{ key: PERMISSIONS.crmQuotationRevisionCreate, label: 'Create quotation revisions' }
]
},
{
key: 'approval',
label: 'Approvals',
permissions: [
{ key: PERMISSIONS.crmApprovalRead, label: 'Read approvals' },
{ key: PERMISSIONS.crmApprovalSubmit, label: 'Submit approvals' },
{ key: PERMISSIONS.crmApprovalApprove, label: 'Approve quotations' },
{ key: PERMISSIONS.crmApprovalReject, label: 'Reject quotations' },
{ key: PERMISSIONS.crmApprovalReturn, label: 'Return quotations' }
]
},
{
key: 'dashboard',
label: 'Dashboard',
permissions: [
{ key: PERMISSIONS.crmDashboardRead, label: 'Read dashboard' },
{ key: PERMISSIONS.crmDashboardExport, label: 'Export dashboard' }
]
},
{
key: 'settings',
label: 'CRM Settings',
permissions: [
{ key: PERMISSIONS.crmRoleRead, label: 'Read roles' },
{ key: PERMISSIONS.crmRoleCreate, label: 'Create roles' },
{ key: PERMISSIONS.crmRoleUpdate, label: 'Update roles' },
{ key: PERMISSIONS.crmRoleDelete, label: 'Delete roles' },
{ key: PERMISSIONS.crmRoleAssign, label: 'Assign role scopes' },
{ key: PERMISSIONS.crmRoleAssignmentRead, label: 'Read user role assignments' },
{ key: PERMISSIONS.crmRoleAssignmentCreate, label: 'Create user role assignments' },
{ key: PERMISSIONS.crmRoleAssignmentUpdate, label: 'Update user role assignments' },
{ key: PERMISSIONS.crmRoleAssignmentDelete, label: 'Delete user role assignments' },
{ key: PERMISSIONS.crmRoleAssignmentManage, label: 'Manage user role assignments' },
{ key: PERMISSIONS.crmUserRoleAssignmentRead, label: 'Read user CRM role assignments' },
{ key: PERMISSIONS.crmUserRoleAssignmentCreate, label: 'Create user CRM role assignments' },
{ key: PERMISSIONS.crmUserRoleAssignmentUpdate, label: 'Update user CRM role assignments' },
{ key: PERMISSIONS.crmUserRoleAssignmentDelete, label: 'Delete user CRM role assignments' },
{ key: PERMISSIONS.crmUserRoleAssignmentManage, label: 'Manage user CRM role assignments' },
{ key: PERMISSIONS.crmMasterOptionRead, label: 'Read master options' },
{ key: PERMISSIONS.crmMasterOptionCreate, label: 'Create master options' },
{ key: PERMISSIONS.crmMasterOptionUpdate, label: 'Update master options' },
{ key: PERMISSIONS.crmMasterOptionDelete, label: 'Delete master options' },
{ key: PERMISSIONS.crmApprovalWorkflowRead, label: 'Read approval workflows' },
{ key: PERMISSIONS.crmApprovalWorkflowCreate, label: 'Create approval workflows' },
{ key: PERMISSIONS.crmApprovalWorkflowUpdate, label: 'Update approval workflows' },
{ key: PERMISSIONS.crmApprovalWorkflowDelete, label: 'Delete approval workflows' },
{ key: PERMISSIONS.crmDocumentTemplateRead, label: 'Read document templates' },
{ key: PERMISSIONS.crmDocumentTemplateCreate, label: 'Create document templates' },
{ key: PERMISSIONS.crmDocumentTemplateUpdate, label: 'Update document templates' },
{ key: PERMISSIONS.crmDocumentTemplateDelete, label: 'Delete document templates' },
{ key: PERMISSIONS.crmDocumentSequenceRead, label: 'Read document sequences' },
{ key: PERMISSIONS.crmDocumentSequenceCreate, label: 'Create document sequences' },
{ key: PERMISSIONS.crmDocumentSequenceUpdate, label: 'Update document sequences' },
{ key: PERMISSIONS.crmDocumentSequenceReset, label: 'Reset document sequences' }
]
},
{
key: 'documents',
label: 'Documents',
permissions: [
{ key: PERMISSIONS.crmDocumentArtifactRead, label: 'Read approved artifacts' },
{ key: PERMISSIONS.crmDocumentArtifactDownload, label: 'Download approved artifacts' },
{ key: PERMISSIONS.crmDocumentArtifactVoid, label: 'Void approved artifacts' },
{ key: PERMISSIONS.crmQuotationDocumentPreview, label: 'Preview quotation document' },
{ key: PERMISSIONS.crmQuotationPdfPreview, label: 'Preview quotation PDF' },
{ key: PERMISSIONS.crmQuotationPdfDownload, label: 'Download quotation PDF' },
{ key: PERMISSIONS.crmQuotationPdfGenerateApproved, label: 'Generate approved quotation PDF' }
]
}
];
export const ALL_PERMISSIONS = Object.values(PERMISSIONS) as Permission[];
export function getMembershipBasePermissions(role: MembershipRole): Permission[] {
if (role === 'admin') {
return [
PERMISSIONS.productsRead,
PERMISSIONS.productsWrite,
PERMISSIONS.organizationManage,
PERMISSIONS.usersManage
];
}
return [PERMISSIONS.productsRead];
}
export function getRoleProfileDefinition(roleCode: string): CrmRoleProfileDefinition | null {
const definition = DEFAULT_ROLE_DEFINITIONS[roleCode];
if (!definition) {
return null;
}
return {
code: roleCode,
...definition
};
}
export function getDefaultRoleProfiles(): CrmRoleProfileDefinition[] {
return BUSINESS_ROLES.map((roleCode) => {
const definition = getRoleProfileDefinition(roleCode);
if (!definition) {
throw new Error(`Missing default role definition for ${roleCode}`);
}
return definition;
});
}
export function getBusinessRolePermissions(role: BusinessRole): Permission[] {
return getRoleProfileDefinition(role)?.permissions ?? [];
}
export function getDefaultBusinessRole(role: MembershipRole): BusinessRole {
return role === 'admin' ? 'sales_manager' : 'sales_support';
}
export function getDefaultPermissions(
role: MembershipRole,
businessRole: BusinessRole = getDefaultBusinessRole(role)
): Permission[] {
return [
...new Set([...getMembershipBasePermissions(role), ...getBusinessRolePermissions(businessRole)])
];
}
export function resolveEffectivePermissions(input: {
systemRole: SystemRole;
membershipRole: MembershipRole;
businessRole: string;
rolePermissions?: string[] | null;
directPermissions?: string[] | null;
}) {
if (input.systemRole === 'super_admin') {
return ALL_PERMISSIONS;
}
return [
...new Set([
...getMembershipBasePermissions(input.membershipRole),
...getBusinessRolePermissions(input.businessRole),
...(input.rolePermissions?.filter((value): value is Permission => typeof value === 'string') ?? []),
...(input.directPermissions?.filter((value): value is Permission => typeof value === 'string') ?? [])
])
];
}
export function isSystemRole(value: string): value is SystemRole {
return SYSTEM_ROLES.includes(value as SystemRole);
}
export function isMembershipRole(value: string): value is MembershipRole {
return MEMBERSHIP_ROLES.includes(value as MembershipRole);
}
export function isBusinessRole(value: string): value is BusinessRole {
return value.trim().length > 0;
}
export function isOwnershipScope(value: string): value is CrmOwnershipScope {
return OWNERSHIP_SCOPES.includes(value as CrmOwnershipScope);
}
export function isScopeMode(value: string): value is CrmScopeMode {
return SCOPE_MODES.includes(value as CrmScopeMode);
}
export function isRoleAssignmentScopeMode(value: string): value is CrmRoleAssignmentScopeMode {
return ROLE_ASSIGNMENT_SCOPE_MODES.includes(value as CrmRoleAssignmentScopeMode);
}
export function isApprovalAuthority(value: string): value is CrmApprovalAuthority {
return APPROVAL_AUTHORITIES.includes(value as CrmApprovalAuthority);
}