This commit is contained in:
phaichayon
2026-06-22 10:22:45 +07:00
parent 51d67ef7c2
commit b154a8de33
37 changed files with 5952 additions and 332 deletions

View File

@@ -6,12 +6,19 @@ export const BUSINESS_ROLES = [
'sales_support',
'sales_manager',
'department_manager',
'top_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 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 = (typeof BUSINESS_ROLES)[number];
export type BusinessRole = string;
export type CrmOwnershipScope = (typeof OWNERSHIP_SCOPES)[number];
export type CrmScopeMode = (typeof SCOPE_MODES)[number];
export type CrmApprovalAuthority = (typeof APPROVAL_AUTHORITIES)[number];
export const PERMISSIONS = {
productsRead: 'products:read',
@@ -52,6 +59,7 @@ export const PERMISSIONS = {
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',
@@ -77,106 +85,262 @@ export const PERMISSIONS = {
crmQuotationDocumentPreview: 'crm.quotation.document.preview',
crmQuotationPdfPreview: 'crm.quotation.pdf.preview',
crmQuotationPdfDownload: 'crm.quotation.pdf.download',
crmQuotationPdfGenerateApproved: 'crm.quotation.pdf.generate_approved'
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',
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];
const MANAGER_PERMISSIONS: Permission[] = [
PERMISSIONS.crmLeadRead,
PERMISSIONS.crmLeadCreate,
PERMISSIONS.crmLeadUpdate,
PERMISSIONS.crmLeadAssign,
PERMISSIONS.crmLeadDelete,
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.crmApprovalRead,
PERMISSIONS.crmApprovalSubmit,
PERMISSIONS.crmApprovalWorkflowRead,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDashboardExport,
PERMISSIONS.crmDocumentTemplateRead,
PERMISSIONS.crmDocumentSequenceRead,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmDocumentArtifactVoid,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload
];
export interface CrmRoleProfileDefinition {
code: string;
name: string;
description: string;
permissions: Permission[];
ownershipScope: CrmOwnershipScope;
branchScopeMode: CrmScopeMode;
productScopeMode: CrmScopeMode;
approvalAuthority: CrmApprovalAuthority;
isSystem: boolean;
}
function getMembershipBasePermissions(role: MembershipRole): Permission[] {
if (role === 'admin') {
return [
PERMISSIONS.productsRead,
PERMISSIONS.productsWrite,
PERMISSIONS.organizationManage,
PERMISSIONS.usersManage,
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.crmLeadDelete,
PERMISSIONS.crmCustomerRead,
PERMISSIONS.crmCustomerCreate,
PERMISSIONS.crmCustomerUpdate,
PERMISSIONS.crmCustomerDelete,
PERMISSIONS.crmContactRead,
PERMISSIONS.crmContactCreate,
PERMISSIONS.crmContactUpdate,
PERMISSIONS.crmContactDelete,
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.crmEnquiryDelete,
PERMISSIONS.crmEnquiryAssign,
PERMISSIONS.crmEnquiryReassign,
PERMISSIONS.crmEnquiryFollowupRead,
PERMISSIONS.crmEnquiryFollowupCreate,
PERMISSIONS.crmEnquiryFollowupUpdate,
PERMISSIONS.crmEnquiryFollowupDelete,
PERMISSIONS.crmQuotationRead,
PERMISSIONS.crmQuotationCreate,
PERMISSIONS.crmQuotationUpdate,
PERMISSIONS.crmQuotationDelete,
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.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.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.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.crmMasterOptionRead,
PERMISSIONS.crmMasterOptionCreate,
PERMISSIONS.crmMasterOptionUpdate,
PERMISSIONS.crmMasterOptionDelete,
PERMISSIONS.crmApprovalWorkflowRead,
PERMISSIONS.crmApprovalWorkflowCreate,
PERMISSIONS.crmApprovalWorkflowUpdate,
PERMISSIONS.crmApprovalWorkflowDelete,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDashboardExport,
PERMISSIONS.crmDocumentTemplateRead,
PERMISSIONS.crmDocumentTemplateCreate,
PERMISSIONS.crmDocumentTemplateUpdate,
@@ -192,116 +356,163 @@ function getMembershipBasePermissions(role: MembershipRole): Permission[] {
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.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[];
function getMembershipBasePermissions(role: MembershipRole): Permission[] {
if (role === 'admin') {
return [
PERMISSIONS.productsRead,
PERMISSIONS.productsWrite,
PERMISSIONS.organizationManage,
PERMISSIONS.usersManage
];
}
return [
PERMISSIONS.productsRead,
PERMISSIONS.crmLeadRead,
PERMISSIONS.crmCustomerRead,
PERMISSIONS.crmContactRead,
PERMISSIONS.crmEnquiryRead,
PERMISSIONS.crmEnquiryFollowupRead,
PERMISSIONS.crmQuotationRead,
PERMISSIONS.crmApprovalRead,
PERMISSIONS.crmApprovalWorkflowRead,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDocumentTemplateRead,
PERMISSIONS.crmDocumentSequenceRead,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload
];
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[] {
switch (role) {
case 'marketing':
return [
PERMISSIONS.crmLeadRead,
PERMISSIONS.crmLeadCreate,
PERMISSIONS.crmLeadUpdate,
PERMISSIONS.crmLeadAssign,
PERMISSIONS.crmLeadDelete,
PERMISSIONS.crmCustomerRead,
PERMISSIONS.crmContactRead,
PERMISSIONS.crmEnquiryRead,
PERMISSIONS.crmEnquiryCreate,
PERMISSIONS.crmEnquiryAssign,
PERMISSIONS.crmEnquiryFollowupRead,
PERMISSIONS.crmDashboardRead
];
case 'sales_manager':
return MANAGER_PERMISSIONS;
case 'sales':
return [
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.crmApprovalRead,
PERMISSIONS.crmApprovalSubmit,
PERMISSIONS.crmApprovalWorkflowRead,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDocumentTemplateRead,
PERMISSIONS.crmDocumentSequenceRead,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload
];
case 'sales_support':
return [
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.crmApprovalRead,
PERMISSIONS.crmApprovalWorkflowRead,
PERMISSIONS.crmDashboardRead,
PERMISSIONS.crmDocumentTemplateRead,
PERMISSIONS.crmDocumentSequenceRead,
PERMISSIONS.crmDocumentArtifactRead,
PERMISSIONS.crmDocumentArtifactDownload,
PERMISSIONS.crmQuotationDocumentPreview,
PERMISSIONS.crmQuotationPdfPreview,
PERMISSIONS.crmQuotationPdfDownload
];
case 'department_manager':
case 'top_manager':
return MANAGER_PERMISSIONS;
default:
return [];
}
return getRoleProfileDefinition(role)?.permissions ?? [];
}
export function getDefaultBusinessRole(role: MembershipRole): BusinessRole {
@@ -317,6 +528,27 @@ export function getDefaultPermissions(
];
}
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);
}
@@ -326,5 +558,17 @@ export function isMembershipRole(value: string): value is MembershipRole {
}
export function isBusinessRole(value: string): value is BusinessRole {
return BUSINESS_ROLES.includes(value as 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 isApprovalAuthority(value: string): value is CrmApprovalAuthority {
return APPROVAL_AUTHORITIES.includes(value as CrmApprovalAuthority);
}