Port para React — Fase 3: Jurídico, Bots e Colaboradores

TLDR: portar as telas Jurídico, Bots (simulador de chatbot) e Colaboradores, reaproveitando a arquitetura já estabelecida — services/mocks/hooks/pages, com Context compartilhado onde o badge da nav exigir.

Nota de status: a spec original ficou marcada como proposed. As três páginas (JuridicoPage, BotsPage, ColaboradoresPage) e os hooks correspondentes existem em modules/frontend/src/, então o status foi corrigido para done na migração da documentação.

Contexto

Fase 1 e Fase 2 estão completas e mergeadas em main (fundação, Login, Painel, Lotes, Clientes, Detalhe do cliente, Negativação, Contratos, Pagamentos). Esta fase porta 3 das 4 telas restantes do protótipo original, a pedido explícito do usuário — ficam de fora Atendimento/Ficha Unificada e Meu Perfil, que continuam como ComingSoonPage.

Sem repositório remoto configurado — como nas fases anteriores, o trabalho é commitado direto em main, sem branch nem PR.

Peça mais arriscada: o motor do simulador de Bots

A tela Bots inclui um simulador de conversa (fase nome→id→menu/outro→fim, com validação por regex de nome completo/e-mail/CPF, contador de tentativas com escalonamento em 3, bypass por “humano”, e round-robin de transferência). Esse motor é extraído como funções puras e testáveis (enviarMensagemTexto, selecionarOpcaoMenu, criarEstadoInicial), no mesmo padrão usado para computePainelDados — é a lógica mais complexa desta fase e a que mais precisa de testes antes de qualquer UI.

Objetivos

  • Portar Jurídico: lista de casos + detalhe do caso selecionado, máquina de estados de status (recebido → negociação → encerrado/direção → negociação), timeline de eventos, export TXT.
  • Portar Bots: 3 cards informativos estáticos + simulador de chat funcional (múltiplos cenários, validações, escalonamento, round-robin).
  • Portar Colaboradores: formulário de convite + tabela da equipe (ciclo de perfil por clique, ativar/desativar, cancelar convite pendente).
  • Atualizar hooks/nav para o badge de Jurídico (jurCases não encerrados) — mesmo padrão já usado para Negativação/Contratos (Context compartilhado + useNavBadges).
  • Registrar qualquer novo quirk do protótipo encontrado.

Fora de escopo

  • Atendimento / Ficha Unificada.
  • Meu perfil.
  • Qualquer alteração em Clientes/Pagamentos/Negativação/Contratos além de expor o novo badge.

Mudanças

``` types/juridico.ts, types/bots.ts, types/colaboradores.ts

mocks/juridico.ts → 3 casos (com contexto + eventos) mocks/bots.ts → mensagens seed por cenário, opções de menu, cenários mocks/colaboradores.ts → 4 usuários iniciais

services/juridico.ts, services/colaboradores.ts (Bots não tem service — não busca dados externos, só estado local do simulador)

hooks/juridico/ CasosJuridicosContext.tsx → casos compartilhados (para o badge da nav) juridico.constants.ts → labels/variantes de status e tipo acoesJuridicas.ts → puro: acoesDisponiveis(status), aplicarAcao(caso, acaoId) buildRegistroJuridicoTxt.ts → puro: export TXT useCasoJuridicoSelecionado.ts → seleção + wiring das ações

hooks/bots/ bots.constants.ts → BOT_CENARIOS, BOT_OPCOES_MENU, RR criarEstadoInicial.ts → puro (equivalente a botSeed) processarMensagem.ts → puro: enviarMensagemTexto(state, texto), selecionarOpcaoMenu(state, label) useBotSimulador.ts → hook fino: estado + ref de scroll + wiring das ações

hooks/colaboradores/ useColaboradores.ts → fetch + enviarConvite + mudarPerfil + acaoClick useConvite.ts → estado do formulário de convite

components/juridico/{CasoListItem,CasoDetalhe} components/bots/{InfoCard,ChatSimulador} components/colaboradores/{ConviteForm,ColaboradoresTable}

pages/JuridicoPage, pages/BotsPage, pages/ColaboradoresPage ```

Rotas em App.tsx: /juridico e /bots continuam gestor-only (RequireRole roles={['gestor']}, já é onde estão hoje como ComingSoonPage); /colaboradores também é gestor-only no protótipo original (não aparece no nav do atendente) — já está sob RequireRole corretamente, só troca o elemento.

Sequência de implementação

# Tipo Entrega
1 feat Tipos + mocks + services (Jurídico, Bots, Colaboradores)
2 test acoesJuridicas — ações por status, transições recebido→negociação→encerrado/direção→negociação, eventos anexados, desfecho preenchido só ao encerrar
3 feat Jurídico completo (Context compartilhado + página + componentes)
4 test criarEstadoInicial, enviarMensagemTexto, selecionarOpcaoMenu — bypass “humano”, validação de nome (sucesso / 3 tentativas), validação de e-mail/CPF por cenário, round-robin (incrementa exceto em com-rec), fluxo “Outro assunto”, cenário pos-novo
5 feat Bots completo (motor + simulador de chat + cards informativos)
6 test useColaboradores — enviarConvite valida @, mudarPerfil cicla os 4 perfis, acaoClick remove convite pendente mas só alterna ativo/desativado para os demais, usuário atual não é editável
7 feat Colaboradores completo
8 refactor Revisão de duplicação + hooks/nav/useNavBadges com o badge de Jurídico

Como verificar

  • npm run build, npm run lint, npm test sem erros.
  • Manual (npm run dev):
    • Jurídico: avançar um caso recebido→negociação→encerrado (com acordo e sem acordo) e recebido→negociação→direção→negociação; timeline cresce a cada ação; exportar TXT baixa o arquivo; badge da nav cai conforme casos são encerrados.
    • Bots: testar os 3 cenários; digitar “humano” a qualquer momento transfere; nome de uma palavra só falha 3x e transfere; e-mail/CPF inválido falha 3x e transfere; completar o fluxo chega ao menu; escolher “Outro assunto” pede contexto antes de transferir; “Reiniciar” reseta a conversa do cenário atual sem resetar o round-robin.
    • Colaboradores: convidar sem “@” não faz nada; convidar com e-mail válido cria linha “CONVITE PENDENTE”; cancelar convite remove a linha; clicar no perfil de outro usuário cicla ATENDENTE→GESTOR→JURÍDICO→DIREÇÃO→ATENDENTE; desativar/reativar alterna o status; a própria linha do usuário logado não é editável.

Documentação

  • Quirks do protótipo dc-runtime — quirk registrado nesta fase: jcDica é fixo por status, sem casos especiais por id, ao contrário do statusDica da Ficha Unificada. Não confundir os dois ao portar a Ficha Unificada.
  • Nenhuma mudança de arquitetura nova (reaproveita Context pattern + hooks puros já estabelecidos).