mirror of
https://origin.cursor.com/mrdevmx/panels.git
synced 2026-10-09 16:13:17 +00:00
- Add IAM v2 auth with role_id, is_owner, status checks, and API key without tenant_admin bypass - Enforce CRUD permissions and project/warehouse scope across API routes - Rewrite usuarios.vue with ribbon, tree, user/role management, and permission matrix - Add dynamic menu, route guards, usePermissions/useScope composables - Apply role templates on create; filter project docs by category; hide cost tab without permission - Add iam_test unit tests; update bootstrap and SaaS tenant admin to use role_id Co-authored-by: alberto.martinez <alberto.martinez@mrdev.mx>
135 lines
8.4 KiB
TypeScript
135 lines
8.4 KiB
TypeScript
/** 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<string, string[]> = {
|
|
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<string, { label: string; permissions: string[] }> = {
|
|
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",
|
|
],
|
|
},
|
|
};
|