{"id":49573730,"url":"https://github.com/pitercoding/intuitivecare-desafio","last_synced_at":"2026-05-03T15:39:38.131Z","repository":{"id":335325965,"uuid":"1144434876","full_name":"pitercoding/intuitivecare-desafio","owner":"pitercoding","description":"[PT-BR] Projeto de ETL e análise de dados da ANS com MySQL, Java/Spring Boot, Python e Angular. [EN] ANS data ETL and analytics project using MySQL, Java/Spring Boot, Python, and Angular.","archived":false,"fork":false,"pushed_at":"2026-02-03T11:37:52.000Z","size":23930,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-03T15:39:09.696Z","etag":null,"topics":["analitycs","angular","ans","api","backend","csv","dados","dashboard","etl","frontend","java","mysql","python","saude","spring"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pitercoding.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-01-28T17:26:21.000Z","updated_at":"2026-02-03T11:51:46.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pitercoding/intuitivecare-desafio","commit_stats":null,"previous_names":["pitercoding/intuitivecare-desafio"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pitercoding/intuitivecare-desafio","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitercoding%2Fintuitivecare-desafio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitercoding%2Fintuitivecare-desafio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitercoding%2Fintuitivecare-desafio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitercoding%2Fintuitivecare-desafio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pitercoding","download_url":"https://codeload.github.com/pitercoding/intuitivecare-desafio/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pitercoding%2Fintuitivecare-desafio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32575114,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["analitycs","angular","ans","api","backend","csv","dados","dashboard","etl","frontend","java","mysql","python","saude","spring"],"created_at":"2026-05-03T15:39:37.497Z","updated_at":"2026-05-03T15:39:38.095Z","avatar_url":"https://github.com/pitercoding.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Desafio Técnico – Intuitive Care\n\n## Objetivo\n\nEste projeto importa, normaliza, consolida e analisa dados financeiros públicos da ANS (Agência Nacional de Saúde Suplementar), permitindo consultas analíticas sobre despesas das operadoras de planos de saúde.\n\nO foco é entregar uma solução funcional, com decisões técnicas justificadas e documentação clara de trade-offs e desvios em relação ao enunciado.\n\n## Tecnologias Utilizadas\n\n- MySQL 8.0+\n- Java 17+ / Spring Boot (backend)\n- Python 3.8+ (agregação via script)\n- Angular (frontend)\n- CSV / ZIP (dados públicos ANS)\n\n## Estrutura do Projeto\n\n```bash\nintuitivecare-desafio/\n├── backend/\n│   ├── sql/\n│   │   ├── extracted/                # CSVs processados por trimestre (ex.: 1T2025, 2T2025, 3T2025)\n│   │   ├── raw/                      # ZIPs originais e CSV de operadoras\n│   │   ├── scripts/\n│   │   │   └── gerar_despesas_agregadas.py\n│   │   ├── ddl.sql                   # Criação das tabelas\n│   │   ├── import.sql                # Importação dos CSVs para MySQL\n│   │   └── queries_3_4.sql           # Queries analíticas\n│   ├── src/\n│   │   ├── main/java/com/pitercoding/backend/\n│   │   │   ├── config/               # Configurações (RestTemplate)\n│   │   │   ├── controller/           # Rotas da API\n│   │   │   ├── domain/               # Entidades JPA\n│   │   │   ├── dto/                  # DTOs de resposta\n│   │   │   ├── repository/           # Repositórios JPA\n│   │   │   └── service/              # Regras de negócio e processamento\n│   │   └── main/resources/\n│   │       └── application.properties\n│   └── pom.xml                       # Dependências Maven\n├── frontend/\n│   ├── src/\n│   │   ├── app/\n│   │   │   ├── layout/               # Header e layout base\n│   │   │   ├── models/               # Modelos de dados\n│   │   │   ├── pages/                # Páginas (lista, detalhe, estatísticas)\n│   │   │   └── services/             # Serviços HTTP\n│   │   └── styles.scss\n│   └── angular.json\n├── postman/                          # Coleção Postman (JSON)\n├── docs/\n│   └── images/                       # Imagens do README (opcional)\n├── .gitignore\n└── README.md               # Documentação principal\n```\n\n## Como Executar\n\n### Pré-requisitos\n\n- Java 17+\n- Maven\n- Node.js 18+ (ou compatível com Angular 20)\n- MySQL 8.0+\n\n### Banco de Dados e Scripts\n\n```bash\n# 1. Criar banco e tabelas\nmysql -u root -p\nCREATE DATABASE intuitivecare_db;\nUSE intuitivecare_db;\nsource backend/sql/ddl.sql;\n\n# 2. Importar dados brutos\nsource backend/sql/import.sql;\n\n# 3. Executar agregação Python\npython backend/sql/scripts/gerar_despesas_agregadas.py\n\n# 4. Executar queries analíticas\nsource backend/sql/queries_3_4.sql\n```\n\n### Backend (Spring Boot)\n\n```bash\ncd backend\n./mvnw spring-boot:run\n```\n\nAPI: `http://localhost:8080`\n\n### Frontend (Angular)\n\n```bash\ncd frontend\nnpm install\nnpm start\n```\n\nFrontend: `http://localhost:4200`\n\n### Postman (variável baseUrl)\n\n- `baseUrl`: `http://localhost:8080`\n\n## Processamento de Dados (Implementado)\n\n1. **Coleta e leitura dos arquivos**\n   - Download de arquivos ZIP por trimestre e extração automática.\n   - Leitura de CSV e XLSX.\n   - Processamento em memória (lista), visando simplicidade e velocidade de desenvolvimento.\n\n2. **Consolidação**\n   - Geração de `consolidado_despesas.csv` com as colunas:\n     - RegistroANS, CNPJ, RazaoSocial, Ano, Trimestre, Valor, UF, NomeFantasia, Modalidade.\n\n3. **Validação**\n   - CNPJ válido (formato e dígitos).\n   - Valor positivo.\n   - Razão Social não vazia.\n\n4. **Enriquecimento**\n   - Join com cadastro de operadoras ativas.\n   - Enriquecimento por Registro ANS (UF, Modalidade, Nome Fantasia).\n   - Registros sem match são exportados separadamente.\n\n5. **Agregação**\n   - Cálculo de total, média e desvio padrão por operadora/UF.\n   - Geração de `despesas_agregadas.csv` e compactação em `despesas_agregadas.zip`.\n\n## Banco de Dados (MySQL)\n\nForam criadas tabelas normalizadas:\n\n- `operadora`: dados cadastrais das operadoras ativas\n- `despesas_consolidadas`: despesas por operadora, trimestre e ano\n- `despesas_agregadas`: métricas calculadas (total, média e desvio padrão)\n\n### Trade-off Técnico – Normalização\n\n**Opção escolhida:** tabelas normalizadas\n\nJustificativa:\n\n- Evita duplicação de dados cadastrais\n- Facilita manutenção e atualização\n- Queries analíticas continuam simples com JOINs\n- Escala melhor para crescimento futuro do volume\n\n### Tipos de Dados\n\n- **DECIMAL(15,2):** valores monetários com precisão\n- **DATE:** datas com melhor indexação e comparação\n\n### Importação dos Dados\n\nRealizada via `LOAD DATA INFILE` com:\n\n- Encoding UTF-8\n- Ignorar headers\n- Conversão automática de valores\n- Normalização de CNPJ (apenas números)\n\nTratamento de inconsistências:\n\n| Problema encontrado              | Estratégia adotada              |\n| -------------------------------- | ------------------------------- |\n| Valores NULL em campos críticos  | Registro rejeitado              |\n| Strings em campos numéricos      | Conversão implícita ou rejeição |\n| Datas inconsistentes             | Padronização no processamento   |\n\n## API REST (Java / Spring Boot)\n\nRotas principais:\n\n- `GET /health`\n- `GET /api/operadoras?page=0\u0026size=10`\n- `GET /api/operadoras/{registroAns}`\n- `GET /api/operadoras/{registroAns}/despesas`\n- `GET /api/operadoras/estatisticas`\n\n### Paginação e formato de resposta\n\nFoi utilizada paginação offset-based via `Page` do Spring Data.  \nO retorno inclui metadados (total, página, tamanho, primeira/última página), facilitando o consumo no frontend.\n\n## Coleção Postman\n\nArquivo JSON salvo em: `postman/`.\n\n## Decisões e Trade-offs (Desvios do Enunciado)\n\n1. **Frontend em Angular (em vez de Vue)**\n   - Decisão baseada em experiência prévia e velocidade de entrega.\n2. **Backend em Java (em vez de Python)**\n   - Maior domínio pessoal e robustez para integrações.\n3. **Uso de Registro ANS como chave principal**\n   - As tabelas originais não traziam CNPJ de forma consistente em todos os arquivos.\n   - O Registro ANS é a chave mais estável no conjunto da ANS.\n   - CNPJ foi normalizado para 14 dígitos quando disponível.\n4. **Processamento em memória**\n   - Preferido por simplicidade e tempo de entrega.\n   - Volume de dados aceitável para execução local sem streaming.\n5. **Zip final**\n   - O enunciado pede `consolidado_despesas.zip` ou `Teste_{seu_nome}.zip`.\n   - Por simplificação, o ZIP gerado no fluxo é `despesas_agregadas.zip`.\n   - Esse ponto foi mantido para evitar refatorações de fluxo.\n\n## Mapeamento do Enunciado x Implementação\n\n| Item do teste | Status | Observação |\n| --- | --- | --- |\n| 1.1 / 1.2 | Adaptado | Download e leitura implementados em Java; varredura completa do FTP e TXT não foi incluída. |\n| 1.3 | Adaptado | CSV consolidado gerado com colunas extras além do exigido. |\n| 2.1 | Atendido | Validação de CNPJ, valores positivos e razão social não vazia. |\n| 2.2 | Adaptado | Join feito por Registro ANS em vez de CNPJ. |\n| 2.3 | Adaptado | Agregação por operadora/UF com métricas; ordenação priorizada no consumo. |\n| 3.2 / 3.3 | Atendido | DDL e importação via `LOAD DATA INFILE` com tratamento básico. |\n| 3.4 | Parcial | Queries presentes; algumas não seguem exatamente o enunciado. |\n| 4.2 | Adaptado | API REST em Java/Spring, não em Python. |\n| 4.3 | Adaptado | Frontend em Angular, não Vue. |\n| 4.4 | Atendido | Coleção Postman criada em JSON. |\n\n## Imagens\n\n- Tela da lista de operadoras com paginação.  \n  ![Tela de operadoras](docs/images/tela-operadoras.png)\n- Tela de detalhe com histórico de despesas.  \n  ![Detalhe da operadora](docs/images/tela-operadora-detalhe.png)\n- Gráfico de despesas por UF.  \n  ![Gráfico por UF](docs/images/tela-estatisticas-uf.png)\n- Print do Postman com as rotas principais.  \n  ![Postman rotas](docs/images/postman-rotas.png)\n\n## Autor\n\n**Piter Gomes** — Aluno de Ciências da Computação (6º Semestre) e Desenvolvedor Full-Stack\n\n[Email](mailto:piterg.bio@gmail.com) | [LinkedIn](https://www.linkedin.com/in/piter-gomes-4a39281a1/) | [GitHub](https://github.com/pitercoding) | [Portfolio](https://portfolio-pitergomes.vercel.app/) |\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpitercoding%2Fintuitivecare-desafio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpitercoding%2Fintuitivecare-desafio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpitercoding%2Fintuitivecare-desafio/lists"}