Este projeto foi desenvolvido com foco em Performance e Integridade de Dados. O desafio de processar arquivos CSV da ANS (que contêm milhões de registros) exigiu uma arquitetura híbrida, onde cada linguagem resolve um problema específico:
- Docker: Garante que o ambiente do Banco de Dados seja reproduzível em qualquer máquina, sem necessidade de instalações locais complexas.
- Java (Spring Boot): Atua como o "motor de força". Escolhi Java para o ETL porque o gerenciamento de memória da JVM e o ecossistema
- de streams são superiores para ler arquivos gigantes sem estourar a RAM.
- Python (FastAPI): Atua como a "camada de inteligência". Escolhi Python para a API pela facilidade de manipulação de dados (Pandas/SQLAlchemy)
- e pela velocidade de desenvolvimento de endpoints assíncronos.
- PostgreSQL: O banco relacional foi a escolha óbvia para garantir a tipagem forte (
NUMERIC) dos dados financeiros.
Abaixo, detalho as escolhas arquiteturais baseadas nos requisitos do PDF.
- Como fiz: Implementei um leitor de CSV em Java que utiliza
BufferedReadere envia os dados para o banco usando o protocoloCOPYdo PostgreSQL. - Por que fiz: A abordagem tradicional com JPA/Hibernate (
.save()) seria inviável para milhões de linhas (demoraria horas). O protocoloCOPYinsere - blocos de dados diretamente no binário do banco, reduzindo o tempo de carga para segundos.
- Tratamento de Dados: Implementei rotinas SQL para converter strings financeiras brasileiras (ex:
1.200,50) para tiposNUMERICnativos, garantindo - precisão matemática e corrigindo erros de encoding (UTF-8/Latin1).
- Estratégia: Paginação no Lado do Servidor (Server-side Pagination).
- Justificativa: O PDF questiona sobre exibir muitas operadoras. Carregar 50.000 operadoras no navegador
- do cliente travaria a interface (DOM excessivo).
- Optei por enviar apenas 10 registros por vez via SQL (
LIMIT 10 OFFSET X). Isso mantém a interface leve e responsiva, independentemente do tamanho do banco - de dados.
- Estados de Loading: Durante as requisições assíncronas (fetch), a interface exibe indicadores visuais
- (spinners ou skeleton screens) para informar ao usuário que o * dado está sendo processado.
- Dados Vazios: Se uma busca não retorna resultados (ex: um CNPJ inexistente), o sistema exibe uma mensagem
- amigável ("Nenhum registro encontrado") em vez de uma tabela * em branco, melhorando a UX.
- Erros de API: Implementei blocos
try/catchno Frontend. Caso a API Python esteja offline ou retorne erro 500, o usuário recebe um alerta visual (Toast/Modal) em vez de - o site quebrar silenciosamente.
- Decisão: Optei por exibir as "Top 5 Maiores Despesas" (Volume Total) ao invés do crescimento percentual.
- Justificativa Crítica: Em análise de dados da ANS, operadoras inativas ou muito pequenas que gastam R$ 100,00 e
- passam a gastar R$ 500,00 apresentam um "crescimento" matemático de 400%, gerando ruído estatístico. Para um Dashboard
- de Visão Geral, entendi que identificar os maiores volumes financeiros (os "players" que movem o mercado) traz mais valor de negócio do que variações
- percentuais de pequenas entidades.
Siga a ordem abaixo para garantir que o ambiente suba corretamente.
A persistência é garantida via Docker. Na raiz do projeto:
cd docker
docker compose up -d
## 2. Backend ETL (Java)
Na raiz do projeto
./mvnw spring-boot:run
Aguarde a mensagem "PROCESSO FINALIZADO" no console. Isso significa que o banco está carregado e pronto.
---
## 3. API (Python)
Responsável por servir os dados ao Frontend.
cd backend
pip install -r requirements.txt
uvicorn main:app --reload
---
## 4. Frontend (Vue.js)
cd frontend
npm install
npm run dev
Acesse o Dashboard em: 👉 http://localhost:5173
---
## 📡 Documentação da API
A API foi construída em REST. Abaixo, as rotas principais para teste:
MétodoEndpointFunçãoGET/operadorasRetorna a lista paginada. Aceita param search
(Nome ou Registro ANS).GET/operadoras/{registro}/despesasBusca o histórico financeiro
detalhado de uma operadora específica.GET/estatisticasRetorna o JSON agregado para os
gráficos (UF, Top 5, KPIs).
---
## 🧪 Considerações Finais
O código foi estruturado pensando em escalabilidade. A separação entre o processo de
carga (Java) e o processo de leitura (Python) permite que, no futuro, o ETL rode em um servidor
dedicado de processamento
em batch sem impactar a performance da API que atende os usuários.
Desenvolvido por Felipe Marzochi
---