MMHL.dev

SaaS · Multi-tenant

AdvBoard

SaaS multi-tenant para escritórios de advocacia trabalhista: fluxo processual em kanban, agenda derivada dos processos e intimações do Diário de Justiça buscadas sozinhas, todo dia útil.

Ano
2026
Papel
Projeto solo — produto, arquitetura, back-end, front-end e deploy
Situação
No ar
Acessar projeto
advboard.app.br
Kanban do AdvBoard com as oito etapas do processo trabalhista e processos distribuídos entre elas

O contexto

Escritório trabalhista pequeno controla processo em planilha e WhatsApp. O fluxo existe na cabeça das pessoas — triagem, cálculo, petição, audiência, acordo — mas ninguém enxerga onde cada processo está, e intimação só aparece quando alguém lembra de olhar o diário. O AdvBoard põe esse fluxo numa tela e vai buscar as intimações sem ninguém pedir.

Etapas do fluxo
8
Rotas de API
9
Fontes oficiais do CNJ
2
Linhas de Security Rules
154

01

O isolamento está no caminho, não num campo

Cada escritório é um tenant em /orgs/{orgId}/... — clientes, processos, agenda, publicações, setores e usuários, todos dentro do caminho do escritório. A alternativa comum seria um campo orgId em cada documento e um filtro em toda consulta; bastaria esquecer o filtro uma vez para vazar dado de um escritório para outro.

A claim orgId é gravada pelo Admin SDK no servidor, nunca pelo cliente, e as Security Rules comparam essa claim com o {orgId} do caminho. Um id errado no cliente resulta em permissão negada — nunca em dado de outro escritório. O isolamento não depende de nenhuma tela se comportar bem.

02

Suspender precisa valer na hora

O escritório tem um status: trial, ativo, suspenso ou cancelado. A tentação é colocar isso numa custom claim junto com o resto — é mais rápido de ler. O problema é que claim vive dentro de um token já emitido: suspender um escritório só valeria quando cada pessoa renovasse o token, o que pode levar horas.

Então as rules leem o status do documento do escritório, pagando uma leitura a mais por requisição. Suspender vale no próximo request de todo mundo. E suspenso é somente leitura, não bloqueio: o escritório não perde o histórico por estar devendo, só para de trabalhar até regularizar.

03

Sessão que expira sem atrapalhar

O login é e-mail/senha no Firebase Auth, mas o ID token não fica no cliente: ele é trocado por um cookie de sessão httpOnly emitido pelo Admin SDK. O proxy.ts faz o guard rápido pela presença do cookie, e getCurrentUser() valida de verdade no servidor — assinatura, revogação e claims.

A sessão morre depois de uma hora sem interação. Isso é requisito de um sistema que abre dados de processo, mas derrubar alguém no meio de um cadastro é inaceitável, então o cookie desliza enquanto a pessoa usa o sistema e aparece um aviso com contagem regressiva cinco minutos antes do fim. A atividade é compartilhada entre abas via localStorage: trabalhar numa aba não derruba a outra.

04

As intimações chegam sozinhas

Duas fontes públicas do CNJ, com papéis diferentes. O DJEN é consultado pelas OABs cadastradas e traz as intimações dirigidas a elas — inclusive de processos que ninguém cadastrou ainda, que é justamente como o escritório descobre que saiu algo em seu nome. O DataJud é consultado pelo número e traz o andamento dos processos já cadastrados.

Um cron roda todo dia útil pela manhã. O botão de sincronizar existe para quem quiser conferir na hora, não para o sistema funcionar. Prazo e audiência vêm marcados como urgentes, e a agenda deriva as audiências dos próprios processos — ninguém lança a mesma audiência duas vezes.

05

Permissão que o servidor cumpre

Papel e permissões vivem em custom claims e são a base das Security Rules. A interface apenas reflete o que o servidor já garante: Atendimento cadastra cliente mas não mexe em processo, Calculista move o fluxo mas não exclui nada.

O detalhe que dá trabalho: ao mudar as permissões de um setor, as claims de todos os membros são reaplicadas. Sem isso, os tokens já emitidos manteriam o acesso antigo até expirarem — a permissão teria sido revogada na tela e continuaria valendo no banco.

06

O que eu testaria de novo

As Security Rules têm teste rodando no emulador do Firestore, separado dos testes unitários. Foi a decisão que mais economizou tempo: regra de permissão é o tipo de código em que um erro não aparece na tela, aparece num vazamento. Testar por inspeção visual não funciona — ou passa no emulador, ou não se sabe.

O que eu faria diferente é ter começado multi-tenant. O sistema nasceu com os dados na raiz e precisou de um script de migração (migrate:orgs) para mover tudo para dentro de um escritório. Migrar estrutura de dados com gente usando é sempre mais caro do que ter nascido certo.

Telas

Fluxo processual — as oito etapas, com prioridade e arraste entre colunas
Fluxo processual — as oito etapas, com prioridade e arraste entre colunas
Dashboard — KPIs, ações urgentes e audiências da semana
Dashboard — KPIs, ações urgentes e audiências da semana
Processos — busca, filtro por etapa e responsável
Processos — busca, filtro por etapa e responsável
Administração — usuários e setores, base das permissões
Administração — usuários e setores, base das permissões
Página pública do produto
Página pública do produto

Contato

Tem um projeto parecido?

Precisa de um sistema do zero, de uma API pra um app que já existe ou de alguém pra tocar o produto de ponta a ponta? Me chama — respondo rápido.

Vamos trabalhar juntos

Outros projetos