import { internalMutation, query } from "./_generated/server"; import { v } from "convex/values"; /** * Listar todos os perfis (roles) do sistema */ export const listarTodosRoles = query({ args: {}, returns: v.array( v.object({ _id: v.id("roles"), nome: v.string(), descricao: v.string(), nivel: v.number(), setor: v.optional(v.string()), customizado: v.boolean(), editavel: v.optional(v.boolean()), _creationTime: v.number(), }) ), handler: async (ctx) => { const roles = await ctx.db.query("roles").collect(); return roles.map((role) => ({ _id: role._id, nome: role.nome, descricao: role.descricao, nivel: role.nivel, setor: role.setor, customizado: role.customizado, editavel: role.editavel, _creationTime: role._creationTime, })); }, }); /** * Limpar perfis antigos/duplicados * * CRITÉRIOS: * - Manter apenas: ti_master (nível 0), admin (nível 2), ti_usuario (nível 2) * - Remover: admin antigo (nível 0), ti genérico (nível 1), outros duplicados */ export const limparPerfisAntigos = internalMutation({ args: {}, returns: v.object({ removidos: v.array( v.object({ nome: v.string(), descricao: v.string(), nivel: v.number(), motivo: v.string(), }) ), mantidos: v.array( v.object({ nome: v.string(), descricao: v.string(), nivel: v.number(), }) ), }), handler: async (ctx) => { const roles = await ctx.db.query("roles").collect(); const removidos: Array<{ nome: string; descricao: string; nivel: number; motivo: string; }> = []; const mantidos: Array<{ nome: string; descricao: string; nivel: number; }> = []; // Perfis que devem ser mantidos (apenas 1 de cada) const perfisCorretos = new Map(); perfisCorretos.set("ti_master", false); perfisCorretos.set("admin", false); perfisCorretos.set("ti_usuario", false); for (const role of roles) { let deveManter = false; let motivo = ""; // TI_MASTER - Manter apenas o de nível 0 if (role.nome === "ti_master") { if (role.nivel === 0 && !perfisCorretos.get("ti_master")) { deveManter = true; perfisCorretos.set("ti_master", true); } else { motivo = role.nivel !== 0 ? "TI_MASTER deve ser nível 0, este é nível " + role.nivel : "TI_MASTER duplicado"; } } // ADMIN - Manter apenas o de nível 2 else if (role.nome === "admin") { if (role.nivel === 2 && !perfisCorretos.get("admin")) { deveManter = true; perfisCorretos.set("admin", true); } else { motivo = role.nivel !== 2 ? "ADMIN deve ser nível 2, este é nível " + role.nivel : "ADMIN duplicado"; } } // TI_USUARIO - Manter apenas o de nível 2 else if (role.nome === "ti_usuario") { if (role.nivel === 2 && !perfisCorretos.get("ti_usuario")) { deveManter = true; perfisCorretos.set("ti_usuario", true); } else { motivo = role.nivel !== 2 ? "TI_USUARIO deve ser nível 2, este é nível " + role.nivel : "TI_USUARIO duplicado"; } } // Perfis genéricos antigos (remover) else if (role.nome === "ti") { motivo = "Perfil genérico 'ti' obsoleto - usar 'ti_master' ou 'ti_usuario'"; } // Outros perfis específicos de setores (manter se forem nível >= 2) else if ( role.nome === "rh" || role.nome === "financeiro" || role.nome === "controladoria" || role.nome === "licitacoes" || role.nome === "compras" || role.nome === "juridico" || role.nome === "comunicacao" || role.nome === "programas_esportivos" || role.nome === "secretaria_executiva" || role.nome === "gestao_pessoas" || role.nome === "usuario" ) { if (role.nivel >= 2) { deveManter = true; } else { motivo = `Perfil de setor com nível incorreto (${role.nivel}), deveria ser >= 2`; } } // Perfis customizados (manter sempre) else if (role.customizado) { deveManter = true; } // Outros perfis desconhecidos else { motivo = "Perfil desconhecido ou obsoleto"; } if (deveManter) { mantidos.push({ nome: role.nome, descricao: role.descricao, nivel: role.nivel, }); console.log(`✅ MANTIDO: ${role.nome} (${role.descricao}) - Nível ${role.nivel}`); } else { // Verificar se há usuários usando este perfil const usuariosComRole = await ctx.db .query("usuarios") .withIndex("by_role", (q) => q.eq("roleId", role._id)) .collect(); if (usuariosComRole.length > 0) { console.log( `⚠️ AVISO: Não é possível remover "${role.nome}" porque ${usuariosComRole.length} usuário(s) ainda usa(m) este perfil` ); mantidos.push({ nome: role.nome, descricao: role.descricao, nivel: role.nivel, }); } else { // Remover permissões associadas const permissoes = await ctx.db .query("rolePermissoes") .withIndex("by_role", (q) => q.eq("roleId", role._id)) .collect(); for (const perm of permissoes) { await ctx.db.delete(perm._id); } // Remover menu permissões associadas const menuPerms = await ctx.db .query("menuPermissoes") .withIndex("by_role", (q) => q.eq("roleId", role._id)) .collect(); for (const menuPerm of menuPerms) { await ctx.db.delete(menuPerm._id); } // Remover o role await ctx.db.delete(role._id); removidos.push({ nome: role.nome, descricao: role.descricao, nivel: role.nivel, motivo: motivo || "Não especificado", }); console.log( `🗑️ REMOVIDO: ${role.nome} (${role.descricao}) - Nível ${role.nivel} - Motivo: ${motivo}` ); } } } return { removidos, mantidos }; }, }); /** * Verificar se existem perfis com níveis incorretos */ export const verificarNiveisIncorretos = query({ args: {}, returns: v.array( v.object({ nome: v.string(), descricao: v.string(), nivelAtual: v.number(), nivelCorreto: v.number(), problema: v.string(), }) ), handler: async (ctx) => { const roles = await ctx.db.query("roles").collect(); const problemas: Array<{ nome: string; descricao: string; nivelAtual: number; nivelCorreto: number; problema: string; }> = []; for (const role of roles) { // TI_MASTER deve ser nível 0 if (role.nome === "ti_master" && role.nivel !== 0) { problemas.push({ nome: role.nome, descricao: role.descricao, nivelAtual: role.nivel, nivelCorreto: 0, problema: "TI_MASTER deve ter acesso total (nível 0)", }); } // ADMIN deve ser nível 2 if (role.nome === "admin" && role.nivel !== 2) { problemas.push({ nome: role.nome, descricao: role.descricao, nivelAtual: role.nivel, nivelCorreto: 2, problema: "ADMIN deve ser editável (nível 2)", }); } // TI_USUARIO deve ser nível 2 if (role.nome === "ti_usuario" && role.nivel !== 2) { problemas.push({ nome: role.nome, descricao: role.descricao, nivelAtual: role.nivel, nivelCorreto: 2, problema: "TI_USUARIO deve ser editável (nível 2)", }); } // Perfil genérico "ti" não deveria existir if (role.nome === "ti") { problemas.push({ nome: role.nome, descricao: role.descricao, nivelAtual: role.nivel, nivelCorreto: -1, // Indica que deve ser removido problema: "Perfil genérico obsoleto - usar ti_master ou ti_usuario", }); } } return problemas; }, });