Esconder o menu não é controlar acesso: como fiz módulos que cada cliente liga e desliga
O pedido
O Oficina Simples foi crescendo: ordens de serviço, orçamentos, agenda, quadro kanban, estoque de peças, cobranças, contas a pagar, comissões, notas fiscais, portal do cliente.
Para uma oficina com três pessoas, isso é menu demais. A resposta natural foi deixar cada oficina escolher o que usa, em Configurações → Menus e módulos.
A primeira versão que veio à cabeça foi esconder os itens do menu. Ela teria sido um erro.
Por que esconder o menu não basta
Um menu escondido continua com a URL funcionando. E, pior, continua com tudo o que acontece por trás da tela funcionando:
- A OS concluída continua baixando peça de um estoque que a oficina diz não controlar.
- O alerta diário de estoque baixo continua chegando.
- O cliente continua recebendo link para um portal que a oficina desligou.
Um módulo desligado precisa ser desligado de verdade. Isso mudou o desenho inteiro.
Três condições, um lugar só
Uma tela fica acessível, no menu e na URL, só quando três coisas são verdadeiras:
- O plano permite o recurso.
- A oficina ligou o módulo, e todas as dependências dele também estão ligadas.
- O papel do usuário pode ver aquela tela.
Uma única classe responde a essa pergunta, e todas as telas a chamam. Como o Filament usa o mesmo método tanto para montar o menu quanto para abrir a página, um módulo desligado responde 403 mesmo para quem digita o endereço. Não há como o menu dizer uma coisa e a URL fazer outra.
Os widgets do dashboard seguem a mesma regra por outro trait. Nada fica de fora porque "é só um card".
Uma fonte única de verdade
Cada módulo é um caso de um enum, que declara tudo sobre ele:
- rótulo, descrição e ícone;
- quais telas e widgets pertencem a ele;
- de quais outros módulos ele depende;
- qual recurso do plano ele exige;
- quais automações param quando ele é desligado;
- como contar os registros em aberto.
Criar um módulo novo é preencher esse enum e aplicar o trait nas telas. Ninguém precisa lembrar de atualizar uma lista em outro arquivo.
Desligar o módulo desliga o comportamento
Os efeitos colaterais checam o módulo explicitamente:
- Estoque desligado: a OS não baixa peças e o alerta de estoque baixo não é enviado.
- Manutenção preventiva desligada: os clientes não são notificados.
- Comissões desligadas: nada é calculado nas OS concluídas.
- Notas fiscais desligadas: o serviço de emissão recusa emitir.
- Portal do cliente desligado: a rota pública responde 404 e os links deixam de ser enviados.
Esse é o ponto que mais fácil se esquece: jobs, serviços e rotas públicas não passam pelo menu. Eles precisam perguntar por conta própria.
Dependências que se resolvem sozinhas
Alguns módulos não fazem sentido sem outros. A venda de balcão precisa do estoque. Então:
- Ligar a venda de balcão liga o estoque junto.
- Desligar o estoque derruba a venda de balcão.
A tela de configuração mantém isso coerente enquanto o usuário clica, em vez de deixar salvar um estado impossível.
Avisar antes de desligar
Antes de salvar, o sistema compara o que está ligado hoje com o que vai ficar ligado e mostra, para cada módulo que vai sair:
- os menus que vão sumir;
- as automações que vão parar;
- os módulos dependentes que caem junto;
- os registros em aberto, como "2 cobranças pendentes ou vencidas".
E uma garantia importante: nada é apagado. Religar o módulo devolve tudo como estava.
Detalhes que evitaram dor de cabeça
nullsignifica "nunca configurou" e vale como tudo ligado. Oficinas que já existiam antes do recurso não perderam nada no deploy.- Presets (Básico, Essencial, Completo) resolvem a escolha para quem não quer pensar nisso. O modo Personalizado fica para quem quer.
- Testes para os efeitos colaterais, não só para o menu. A suíte desliga módulos e confere que a baixa de estoque, os avisos e a emissão realmente param.
A lição
Feature flag por cliente parece um problema de interface. Na prática, é um problema de autorização e de efeitos colaterais. Se a regra mora no menu, ela vaza. Se mora num lugar só e todo mundo pergunta para ele, ela segura.
Posts relacionados
Webhook não é fonte de verdade: o que aprendi integrando nota fiscal eletrônica
Nota fiscal é processada em segundo plano: você emite, recebe 'processando' e a autorizaçã...
Meu segundo SaaS começou com o código do primeiro: o que deu para reaproveitar e o que precisei reescrever
O Oficina Simples nasceu de um fork do Estoque Simples. Login, planos, cobrança, LGPD e mu...
Você não ficou 4x mais rápido. Ficou 10x mais inseguro — e agora existem os dados
Quase metade do código gerado por IA nasce com uma falha do OWASP Top 10. Os commits saem...