/** Catálogo de permisos CRUD IAM v2 ({modulo}.{verbo}). */ export type PermissionDef = { code: string; label: string; module: string; verb: "view" | "create" | "update" | "delete"; group?: string; }; export const IAM_SENSITIVE_PREFIXES = ["users.", "settings."] as const; export const RESERVED_ROLE_CODES = new Set([ "tenant_admin", "platform_admin", "user", ]); export const PERMISSION_CATALOG: PermissionDef[] = [ { code: "workers.view", label: "Consultar padrón", module: "workers", verb: "view" }, { code: "workers.create", label: "Alta de personal", module: "workers", verb: "create" }, { code: "workers.update", label: "Editar personal", module: "workers", verb: "update" }, { code: "workers.delete", label: "Baja de personal", module: "workers", verb: "delete" }, { code: "kanban.view", label: "Tablero kanban", module: "kanban", verb: "view" }, { code: "projects.view", label: "Consultar obras", module: "projects", verb: "view" }, { code: "projects.create", label: "Alta de obras", module: "projects", verb: "create" }, { code: "projects.update", label: "Editar obras", module: "projects", verb: "update" }, { code: "companies.view", label: "Consultar empresas", module: "companies", verb: "view" }, { code: "companies.create", label: "Alta de empresas", module: "companies", verb: "create" }, { code: "companies.update", label: "Editar empresas", module: "companies", verb: "update" }, { code: "budget.view", label: "Ver presupuesto", module: "budget", verb: "view" }, { code: "budget.create", label: "Alta partidas presupuesto", module: "budget", verb: "create" }, { code: "budget.update", label: "Editar presupuesto", module: "budget", verb: "update" }, { code: "budget.delete", label: "Eliminar partidas", module: "budget", verb: "delete" }, { code: "work_program.view", label: "Ver programa de obra", module: "work_program", verb: "view" }, { code: "work_program.create", label: "Importar/generar programa", module: "work_program", verb: "create" }, { code: "work_program.update", label: "Capturar avances", module: "work_program", verb: "update" }, { code: "cost_control.view", label: "Control de costos", module: "cost_control", verb: "view" }, { code: "expenses.view", label: "Ver gastos", module: "expenses", verb: "view" }, { code: "expenses.create", label: "Capturar gastos", module: "expenses", verb: "create" }, { code: "expenses.update", label: "Editar gastos", module: "expenses", verb: "update" }, { code: "expenses.delete", label: "Eliminar gastos", module: "expenses", verb: "delete" }, { code: "warehouse.view", label: "Ver almacén", module: "warehouse", verb: "view" }, { code: "warehouse.create", label: "Entradas almacén", module: "warehouse", verb: "create" }, { code: "warehouse.update", label: "Salidas/transferencias", module: "warehouse", verb: "update" }, { code: "payroll.view", label: "Ver nómina", module: "payroll", verb: "view" }, { code: "payroll.create", label: "Alta nómina/préstamos", module: "payroll", verb: "create" }, { code: "payroll.update", label: "Armar/pagar nómina", module: "payroll", verb: "update" }, { code: "payroll.delete", label: "Eliminar líneas nómina", module: "payroll", verb: "delete" }, { code: "documents.view", label: "Ver documentos/gafetes", module: "documents", verb: "view" }, { code: "documents.create", label: "Subir documentos/gafetes", module: "documents", verb: "create" }, { code: "project_docs.tecnico.view", label: "Planos y docs técnicos", module: "project_docs", verb: "view", group: "tecnico" }, { code: "project_docs.tecnico.create", label: "Subir docs técnicos", module: "project_docs", verb: "create", group: "tecnico" }, { code: "project_docs.contrato.view", label: "Docs contrato", module: "project_docs", verb: "view", group: "contrato" }, { code: "project_docs.contrato.create", label: "Subir docs contrato", module: "project_docs", verb: "create", group: "contrato" }, { code: "project_docs.permisos.view", label: "Docs permisos", module: "project_docs", verb: "view", group: "permisos" }, { code: "project_docs.permisos.create", label: "Subir docs permisos", module: "project_docs", verb: "create", group: "permisos" }, { code: "project_docs.ambiental.view", label: "Docs ambientales", module: "project_docs", verb: "view", group: "ambiental" }, { code: "project_docs.ambiental.create", label: "Subir docs ambientales", module: "project_docs", verb: "create", group: "ambiental" }, { code: "project_docs.imss.view", label: "Docs IMSS", module: "project_docs", verb: "view", group: "imss" }, { code: "project_docs.imss.create", label: "Subir docs IMSS", module: "project_docs", verb: "create", group: "imss" }, { code: "project_docs.sst.view", label: "Docs SST", module: "project_docs", verb: "view", group: "sst" }, { code: "project_docs.sst.create", label: "Subir docs SST", module: "project_docs", verb: "create", group: "sst" }, { code: "project_docs.otro.view", label: "Otros docs obra", module: "project_docs", verb: "view", group: "otro" }, { code: "project_docs.otro.create", label: "Subir otros docs", module: "project_docs", verb: "create", group: "otro" }, { code: "users.view", label: "Listar usuarios IAM", module: "users", verb: "view" }, { code: "users.create", label: "Alta usuarios IAM", module: "users", verb: "create" }, { code: "users.update", label: "Editar usuarios IAM", module: "users", verb: "update" }, { code: "users.delete", label: "Baja usuarios IAM", module: "users", verb: "delete" }, { code: "settings.view", label: "Ver configuración", module: "settings", verb: "view" }, { code: "settings.update", label: "Guardar configuración", module: "settings", verb: "update" }, { code: "reports.view", label: "Reportes e inicio", module: "reports", verb: "view" }, ]; export const ALL_PERMISSION_CODES = PERMISSION_CATALOG.map((p) => p.code); /** Mapeo legacy → v2 para backfill y transición. */ export const LEGACY_TO_V2: Record = { manage_workers: ["workers.view", "workers.create", "workers.update", "workers.delete", "kanban.view"], manage_projects: ["projects.view", "projects.create", "projects.update"], manage_companies: ["companies.view", "companies.create", "companies.update"], manage_budget: ["budget.view", "budget.create", "budget.update", "budget.delete", "work_program.view", "work_program.create", "work_program.update"], manage_expenses: ["expenses.view", "expenses.create", "expenses.update", "expenses.delete", "cost_control.view"], view_expenses: ["expenses.view", "cost_control.view"], manage_payroll: ["payroll.view", "payroll.create", "payroll.update", "payroll.delete"], manage_documents: ["documents.view", "documents.create", "project_docs.tecnico.view", "project_docs.tecnico.create", "project_docs.contrato.view", "project_docs.contrato.create", "project_docs.permisos.view", "project_docs.permisos.create"], manage_users: ["users.view", "users.create", "users.update", "users.delete"], manage_settings: ["settings.view", "settings.update"], view_reports: ["reports.view"], view_warehouse: ["warehouse.view"], manage_warehouse: ["warehouse.view", "warehouse.create", "warehouse.update"], close_warehouse: ["warehouse.update"], manage_cost_settings: ["settings.update", "cost_control.view"], }; export const PROJECT_DOC_CATEGORIES = [ "tecnico", "contrato", "permisos", "ambiental", "imss", "sst", "otro", ] as const; export type ProjectDocCategory = typeof PROJECT_DOC_CATEGORIES[number]; export function projectDocPerm(category: string, verb: "view" | "create"): string { return `project_docs.${category}.${verb}`; } export const ROLE_TEMPLATES: Record = { admin_operativo: { label: "Administrador operativo", permissions: ALL_PERMISSION_CODES.filter( (c) => !IAM_SENSITIVE_PREFIXES.some((p) => c.startsWith(p)), ), }, supervisor_obra: { label: "Supervisor de obra", permissions: [ "projects.view", "work_program.view", "work_program.update", "project_docs.tecnico.view", "reports.view", ], }, contador: { label: "Contador", permissions: [ "expenses.view", "expenses.create", "expenses.update", "expenses.delete", "cost_control.view", "reports.view", "payroll.view", ], }, operativo: { label: "Operativo", permissions: [ "workers.view", "workers.create", "workers.update", "documents.view", "documents.create", "reports.view", "kanban.view", ], }, };