feat: Implement dynamic sidebar menu in the frontend, filtered by new backend user permissions.

This commit is contained in:
2025-12-04 16:05:26 -03:00
parent 2cdf66375c
commit 68475f549a
4 changed files with 527 additions and 269 deletions

View File

@@ -0,0 +1,59 @@
import { query } from './_generated/server';
import { getCurrentUserFunction } from './auth';
/**
* Retorna as permissões do usuário atual para o frontend filtrar o menu localmente
* Retorna:
* - isMaster: true se o usuário é TI Master ou Admin (nível <= 1)
* - permissions: Set de strings no formato "recurso.acao" (ex: "funcionarios.listar")
*/
export const getUserPermissions = query({
args: {},
handler: async (ctx) => {
const usuario = await getCurrentUserFunction(ctx);
if (!usuario) {
return { isMaster: false, permissions: [] };
}
const role = await ctx.db.get(usuario.roleId);
if (!role) {
return { isMaster: false, permissions: [] };
}
// Se for TI Master ou Admin (nivel <= 1), retorna flag de master
if (role.nivel <= 1) {
return { isMaster: true, permissions: [] };
}
// Buscar permissões do usuário
const rolePermissoes = await ctx.db
.query('rolePermissoes')
.withIndex('by_role', (q) => q.eq('roleId', role._id))
.collect();
const permissoesIds = rolePermissoes.map((rp) => rp.permissaoId);
// Carregar os documentos de permissão para saber recurso/ação
const permissoesDocs = await Promise.all(permissoesIds.map((id) => ctx.db.get(id)));
// Criar array de "recurso.acao" para o frontend
const permissions: string[] = [];
for (const p of permissoesDocs) {
if (p) {
permissions.push(`${p.recurso}.${p.acao}`);
}
}
return { isMaster: false, permissions };
}
});
// Manter a query antiga por compatibilidade (deprecada)
// TODO: Remover após migração completa do frontend
export const getSidebarMenu = query({
args: {},
handler: async () => {
// Retorna array vazio - o frontend agora define o menu
return [];
}
});