798aa7b5799e0bd06c56e49870ddf31ac7a8ff74
getUserPermissionKeys(userId, tenantId?) (novo, packages/auth) devolve todas as permission keys do usuário no contexto atual, mesma query de userHasPermission só que retornando o conjunto inteiro. GET /auth/me agora inclui permissionKeys — leitura adicional só pra UX, nunca decisão de autorização (isso continua sendo o PermissionGuard em cada endpoint). NavLeaf/NavSection ganham campo opcional permission; todos os ~35 itens de menu (tenant e platform) anotados com a permission key mínima que o endpoint GET correspondente já exige. filterNavByPermissions() (novo, nav-types.ts) esconde o item, ou a seção inteira se nenhum filho sobrar. TenantSidebar/PlatformSidebar/*Topbar são client components que importam TENANT_NAV/PLATFORM_NAV direto (não recebem como prop do server) porque os ícones (LucideIcon, funções) não são serializáveis através da fronteira RSC — restrição já documentada desde a PHASE 23. O filtro roda dentro desses wrappers, client-side, recebendo só permissionKeys: string[] (serializável) como prop. Testado ponta a ponta com um supervisor de teste de verdade (convidado, senha trocada, logado via UI): menu perde Telefonia > Dialplan e a seção Administração inteira (nenhum permission bate). Confirmado que a autorização real continua valendo sem o item no menu: acesso direto a /app/administracao/usuarios continua batendo 403 no backend. Regressão: tenant_admin e platform_super_admin continuam vendo todo item do próprio menu. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BFaBaBSQGhyXGEgtTYZGV8
Description
Languages
TypeScript
98.3%
Dockerfile
1.3%
CSS
0.3%
Shell
0.1%