Port para React — Fase 1: fundação, Login, Painel e Lotes

TLDR: portar o protótipo dc-runtime para um app React+Vite+TypeScript real, entregando a fundação (setup, design system, camada de serviços mockada, sessão) mais o primeiro fluxo vertical completo do gestor — Login, Painel e Lotes.

Contexto

Sistema de Cobrança.dc.html é um protótipo estático no formato “dc-runtime” (interpretado em runtime pelo support.js, que é apenas o motor genérico do formato — sc-if/sc-for/{{ }} — e não contém nenhuma lógica de negócio). Toda a lógica de negócio do app está embutida em um único <script type="text/x-dc" data-dc-script> dentro do próprio .dc.html, junto com ~1560 linhas de template HTML com estilos inline.

O objetivo é reescrever esse protótipo como um app React real, terminando com uma base que pode receber integração com um back-end de verdade no futuro (por enquanto os dados continuam mockados, mas isolados atrás de uma camada de serviços). O projeto ainda não existe como código React (a pasta só tem os .dc.html de referência) e ainda não é um repositório git.

O protótipo tem 14 telas ao todo (Login, Painel, Lotes, Detalhe do lote, Atendimento/Ficha Unificada, Negativação, Contratos, Pagamentos, Clientes, Detalhe do cliente, Jurídico, Bots, Colaboradores, Meu perfil). Dado o tamanho, a entrega é faseada. Esta spec cobre apenas a Fase 1: fundação do projeto + Login + Painel + Lotes + Detalhe do lote — o primeiro fluxo vertical completo do gestor, que serve para validar a arquitetura de componentes/hooks antes de portar o restante.

Decisões travadas com o usuário

Decisão Escolha Por quê
Linguagem TypeScript Não JavaScript puro
Acesso a dados Camada de serviço isolada (services/) Funções que hoje retornam mock, consumidas por hooks; quando o back-end existir, só a implementação dos serviços muda
Navegação React Router URLs reais por tela, em vez do tela state único do protótipo
Estilos CSS Modules (um .module.css por componente) Preserva os valores visuais do protótipo, com suporte nativo a :hover/:focus — o protótipo simulava isso via atributos style-hover/style-focus do dc-runtime

Objetivos

  • Criar o projeto Vite + React + TypeScript do zero, com estrutura de pastas organizada (pages/ separado de components/, componentes agrupados por domínio/generalidade).
  • Extrair toda lógica de estado/efeitos para hooks customizados — componentes ficam só com JSX + props.
  • Construir o design system compartilhado (Sidebar, PageHeader, PillGroup, StatusChip, DataTable + Pagination, SearchInput, InfoHint, NavItem) como componentes genéricos reutilizáveis, parametrizados via props.
  • Implementar sessão/login (mock) com roteamento protegido por papel (gestor vs atendente).
  • Portar as telas Painel, Lotes e Detalhe do lote com paridade funcional com o protótipo (mesmos cálculos, mesmos estados, mesmo comportamento de filtros/paginação).
  • Deixar a base pronta (roteador, layout, nav com badges, camada de serviços) para as próximas fases plugarem sem retrabalho estrutural.

Fora de escopo

  • Telas: Atendimento (Ficha Unificada), Negativação, Contratos, Pagamentos, Clientes, Detalhe do cliente, Jurídico, Bots, Colaboradores, Meu perfil.
  • Integração com back-end real (API real do Asaas, autenticação real) — fica tudo mockado nesta fase.
  • O bug já identificado na Ficha Unificada (vencBase não definida em emitir()) — só será corrigido quando essa tela for portada, mas fica documentado para não se perder.

Mudanças

Novo projeto React (na época em cobranca-web/app/; hoje modules/frontend/), estrutura alvo:

src/ main.tsx App.tsx # Router + providers pages/ LoginPage/ PainelPage/ LotesPage/ LoteDetalhePage/ components/ layout/ # Sidebar, PageHeader, NavItem, AppShell ui/ # PillGroup, StatusChip, DataTable, Pagination, # SearchInput, InfoHint, Bar (barra de progresso) painel/ # KpiCard, EvolucaoChart, AtendentesTable, ReguaDisparos lotes/ # LoteAtivoCard, ImportarLotePanel, LoteConfigPanel, # ImportStepList, LotesEncerradosTable hooks/ auth/ # useSession, useLogin nav/ # useNav (itens de menu por papel, badges) painel/ # usePainelFiltros, usePainelDados (kpis, gráfico, atendentes) lotes/ # useLotes, useImportarLote, useLoteConfig loteDetalhe/ # useLoteDetalhe (busca + paginação) shared/ # useToggleIndex (padrão kInfoOpen), usePagination services/ session.ts # login mockado lotes.ts # fetchLotes, fetchLoteDetalhe, importarLote (mock) painel.ts # fetchPainelDados (mock) mocks/ lotes.ts, painel.ts # dados estáticos determinísticos (equivalentes a # NOMES_LOTE/STATUS_LOTE/MESES do protótipo) types/ index.ts # tipos compartilhados (Lote, Aluno, Atendente, etc.) styles/ tokens.css # cores, fontes (IBM Plex Sans/Mono), var(--ac)

Os arquivos de referência do protótipo (product_architecture.dc.html, unified_record.dc.html, collection_system.dc.html, support.js, ibft_guide.txt) permaneceram como material de consulta, fora do build — hoje em features/assets/prototype/.

Sequência de implementação

Este é um trabalho de portar UI/comportamento de um protótipo, não uma mudança em lógica de negócio testável isoladamente. O ciclo TDD tradicional foi adaptado: os “testes” de UI aqui são verificação manual no navegador (ver Como verificar), e os testes automatizados ficaram reservados para a lógica pura extraída aos hooks (cálculos do painel, paginação, filtros).

# Tipo Entrega Arquivos
1 feat Scaffold Vite react-ts, ESLint/Prettier, React Router, tokens.css app/ (setup)
2 feat Layout genérico: AppShell, Sidebar, NavItem, PageHeader src/components/layout/*
3 feat UI genérica: PillGroup, StatusChip, DataTable, Pagination, SearchInput, InfoHint, Bar src/components/ui/*
4 test usePagination, useToggleIndex — bordas (página 0, última página, índice repetido) src/hooks/shared/*.test.ts
5 feat usePagination/useToggleIndex até os testes passarem src/hooks/shared/*.ts
6 feat Sessão/login mockado + roteamento protegido por papel src/pages/LoginPage/*, src/hooks/auth/*, src/services/session.ts
7 feat useNav (itens por papel + badges) integrado ao Sidebar src/hooks/nav/*
8 test usePainelDados — kpis, gráfico com meses dentro/fora do filtro, agregação por atendente src/hooks/painel/*.test.ts
9 feat PainelPage completa src/pages/PainelPage/*, src/hooks/painel/*, src/components/painel/*, src/services/painel.ts, src/mocks/painel.ts
10 test useLotes/useImportarLote — avanço de steps, criação de lote, stepper 7–56 dias src/hooks/lotes/*.test.ts
11 feat LotesPage completa src/pages/LotesPage/*, src/hooks/lotes/*, src/components/lotes/*, src/services/lotes.ts, src/mocks/lotes.ts
12 test useLoteDetalhe — busca por nome/CPF, paginação 10/página src/hooks/loteDetalhe/*.test.ts
13 feat LoteDetalhePage completa src/pages/LoteDetalhePage/*, src/hooks/loteDetalhe/*
14 refactor Revisão de duplicação entre as três páginas —

Como verificar

  • npm run build e npm run lint passam sem erros.
  • Testes unitários dos hooks (npm test) verdes.
  • Rodar npm run dev e conferir manualmente, comparando lado a lado com o protótipo (collection_system.dc.html aberto localmente):
    • Login com e-mail contendo “aretha” entra como atendente (nav reduzida); qualquer outro e-mail entra como gestor (nav completa).
    • Painel: trocar filtros de período/atendente atualiza KPIs, gráfico e tabela; abrir/fechar cada popover de info; baixar CSV.
    • Lotes: abrir configurações do lote, alternar duração/automático, avançar os 5 passos de importação até criar um novo lote ativo; abrir “Ver detalhes” de um lote encerrado.
    • Detalhe do lote: busca filtra por nome/CPF; paginação anterior/próxima funciona nos limites.
    • Navegar entre todas as telas da Fase 1 via sidebar sem erros no console.

Documentação

  • Camadas do app React — decisão da camada de serviços mockada + hooks, para orientar as próximas fases e a futura integração com back-end real.
  • Quirks do protótipo dc-runtime — inconsistências que não devem ser replicadas literalmente: dado duplicado/hardcoded do “Cléber Santana Farias” em Negativação, valores literais não computados (Reincidência 47,7%, “893 (29,6%)” nas respostas da régua), e o bug de vencBase indefinido em unified_record.dc.html.