/** * 权限点常量骨架(A0-SH-01) * 命名规范:<模块>:<动作>,模块取后端八模块语义(identity / client / catalog / industry / * script / media / delivery / platform),全小写;动作使用动词或名词短语。 * A1/A2 接入真实角色-权限表后,这里只增不改;删除/改名需评审(AGENTS §10)。 */ export const Permission = { // 脚本 SCRIPT_READ: 'script:read', SCRIPT_WRITE: 'script:write', SCRIPT_REVIEW: 'script:review', // 素材 MATERIAL_READ: 'material:read', MATERIAL_WRITE: 'material:write', MATERIAL_RENDER: 'material:render', MATERIAL_REVIEW: 'material:review', // 资产 ASSET_READ: 'asset:read', ASSET_WRITE: 'asset:write', // 导出交付 DELIVERY_READ: 'delivery:read', DELIVERY_EXPORT: 'delivery:export', // 客户 CUSTOMER_READ: 'customer:read', CUSTOMER_MANAGE: 'customer:manage', CUSTOMER_FIELD_APPROVE: 'customer_field:approve', // 组织与角色 USER_MANAGE: 'user:manage', ROLE_MANAGE: 'role:manage', // 平台配置 INDUSTRY_MANAGE: 'industry:manage', INDUSTRY_PUBLISH: 'industry:publish', DICT_MANAGE: 'dict:manage', FORM_DESIGN: 'form:design', AI_CONFIGURE: 'ai:configure', SYSTEM_CONFIGURE: 'system:configure', // 审计 AUDIT_READ: 'audit:read', AUDIT_EXPORT: 'audit:export', } as const; export type PermissionCode = (typeof Permission)[keyof typeof Permission]; export const PERMISSION_CODES: readonly PermissionCode[] = Object.values(Permission); /** 需要额外单独校验的特殊权限(技术架构 §6.2「关键特殊权限」) */ export const SPECIAL_PERMISSIONS: readonly PermissionCode[] = [ Permission.DELIVERY_EXPORT, Permission.AI_CONFIGURE, Permission.AUDIT_EXPORT, Permission.INDUSTRY_PUBLISH, Permission.CUSTOMER_FIELD_APPROVE, ]; const PERMISSION_CODE_SET: ReadonlySet = new Set(PERMISSION_CODES); export function isPermissionCode(value: string): value is PermissionCode { return PERMISSION_CODE_SET.has(value); } export interface ParsedPermission { module: string; action: string; } /** 拆分权限点为 { module, action };格式不合法返回 null */ export function parsePermission(code: string): ParsedPermission | null { const separator = code.indexOf(':'); if (separator <= 0 || separator === code.length - 1) { return null; } const module = code.slice(0, separator); const action = code.slice(separator + 1); if (module.includes(':') || action.includes(':')) { return null; } return { module, action }; }