Versão: 1.0.0
Este README final descreve o projeto entregue: um esqueleto funcional com backend em Spring Boot, front-end Angular, containerização com Docker/Docker Compose, mensageria via Kafka (opcional) e cobertura de testes (JUnit + Testcontainers). Contém instruções detalhadas para rodar localmente, depurar, adaptar para produção e entregar no GitHub.
- Visão geral
- Tecnologias usadas
- Estrutura do projeto
- Scripts SQL (criação e seed)
- Como rodar (rápido)
- Rodando com Docker Compose (detalhado)
- Rodando sem Docker (desenvolvimento local)
- Endpoints da API (exemplos e cURL)
- Modelagem de dados
- Mensageria (Kafka / alternativa Azure Service Bus)
- Testes (unitários e integração)
- CI / GitHub Actions
- Troubleshooting — erros comuns e correções
- Segurança e produção
- Checklist de entrega
- Histórico de commits sugerido
- Licença
O sistema permite consultar créditos constituídos vinculados a uma NFS-e ou a um número de crédito. Ele expõe endpoints REST simples para consulta e inclui: um front-end em Angular para interação do usuário, producer Kafka que publica uma mensagem a cada consulta (opcional) e scripts para provisionar o banco de dados com dados de exemplo.
O objetivo desta entrega é apresentar um projeto que o candidato possa demonstrar rapidamente: arquitetura limpa, padrões, testes e containerização.
- Backend: Java 11/17, Spring Boot, Spring Data JPA, Hibernate, Lombok
- Banco: PostgreSQL (ou MariaDB como alternativa)
- Mensageria: Kafka (Bitnami/Confluent images usadas no
docker-compose
) — opcional; alternativa: Azure Service Bus - Frontend: Angular 15+ (esqueleto pronto para compilar)
- Containerização: Docker, Docker Compose
- Testes: JUnit 5, Mockito, Testcontainers (integração com PostgreSQL)
- CI: GitHub Actions (workflow básico incluído)
desafio_creditos_complete_all/
├─ backend/
│ ├─ pom.xml
│ ├─ src/main/java/com/example/desafiocreditos/...
│ ├─ src/test/...
│ └─ Dockerfile
├─ frontend/
│ ├─ package.json
│ ├─ angular.json
│ ├─ src/
│ └─ Dockerfile
├─ docker-compose.yml
├─ README-FINAL.md <-- ESTE ARQUIVO
├─ make_commits.sh
└─ .github/workflows/ci.yml
Os scripts estão em backend/sql/
:
create_table.sql
— cria a tabelacredito
.seed.sql
— insere registros de exemplo (já usados pelo frontend nas demos).
Exemplo (resumido)
CREATE TABLE credito (
id BIGSERIAL PRIMARY KEY,
numero_credito VARCHAR(50) NOT NULL,
numero_nfse VARCHAR(50) NOT NULL,
data_constituicao DATE NOT NULL,
valor_issqn DECIMAL(15,2) NOT NULL,
tipo_credito VARCHAR(50) NOT NULL,
simples_nacional BOOLEAN NOT NULL,
aliquota DECIMAL(5,2) NOT NULL,
valor_faturado DECIMAL(15,2) NOT NULL,
valor_deducao DECIMAL(15,2) NOT NULL,
base_calculo DECIMAL(15,2) NOT NULL
);
Seed: (ex.)
INSERT INTO credito (numero_credito, numero_nfse, data_constituicao, valor_issqn, tipo_credito, simples_nacional, aliquota, valor_faturado, valor_deducao, base_calculo)
VALUES
('123456','7891011','2024-02-25',1500.75,'ISSQN',true,5.0,30000.00,5000.00,25000.00);
Requisitos:
- Docker Engine / Docker Desktop (Linux containers) ou Docker + Compose
- Git
- Baixe/extrai o ZIP ou clone o repositório.
- Na raiz do projeto execute:
docker-compose up --build
- Acesse:
- Frontend:
http://localhost:4200
- API exemplo:
http://localhost:8080/api/creditos/7891011
Observação: caso o docker-compose
exiba um aviso sobre version
ser obsoleto, ignore — o Compose ainda funciona. Para limpar, remova a chave version:
do docker-compose.yml
.
postgres
— banco de dados (porta 5432)zookeeper
— coordenador para Kafka (somente se usar Kafka)kafka
— broker Kafka (porta 9092)backend
— Spring Boot (porta 8080)frontend
— servirá conteúdo estático via nginx (porta 4200)
- Abra o Docker Desktop e confirme que o daemon está rodando (
docker ps
deve retornar). Se der erro com pipedockerDesktopLinuxEngine
, reinicie o Docker Desktop. - Se tiver problemas ao puxar imagens da Bitnami, troque por imagens
confluentinc/cp-zookeeper
econfluentinc/cp-kafka
(exemplo abaixo).
zookeeper:
image: confluentinc/cp-zookeeper:7.5.0
environment:
ZOOKEEPER_CLIENT_PORT: 2181
ZOOKEEPER_TICK_TIME: 2000
kafka:
image: confluentinc/cp-kafka:7.5.0
depends_on:
- zookeeper
environment:
KAFKA_BROKER_ID: 1
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
KAFKA_LISTENERS: PLAINTEXT://0.0.0.0:9092
SPRING_DATASOURCE_URL
—jdbc:postgresql://postgres:5432/desafiocreditos
SPRING_DATASOURCE_USERNAME
—postgres
SPRING_DATASOURCE_PASSWORD
—postgres
SPRING_KAFKA_BOOTSTRAP_SERVERS
—kafka:9092
(ou vazio se não usar Kafka)
- Configure um PostgreSQL local ou use uma instância (p.ex.: Docker) e carregue os scripts
create_table.sql
eseed.sql
. - Defina as variáveis de ambiente (ou edite
src/main/resources/application.properties
):
spring.datasource.url=jdbc:postgresql://localhost:5432/desafiocreditos
spring.datasource.username=postgres
spring.datasource.password=postgres
spring.jpa.hibernate.ddl-auto=none
server.port=8080
- Rodar:
cd backend
mvn clean spring-boot:run
- Configure Node.js (v18+) e npm.
- Instale dependências:
cd frontend
npm install
- Rodar em dev:
npm start
- Build de produção:
npm run build
GET /api/creditos/{numeroNfse}
- Descrição: Retorna lista de créditos vinculados ao número da NFS-e.
- Exemplo:
curl http://localhost:8080/api/creditos/7891011
- Resposta (200): JSON array
[
{
"numeroCredito": "123456",
"numeroNfse": "7891011",
"dataConstituicao": "2024-02-25",
"valorIssqn": 1500.75,
"tipoCredito": "ISSQN",
"simplesNacional": "Sim",
"aliquota": 5.0,
"valorFaturado": 30000.00,
"valorDeducao": 5000.00,
"baseCalculo": 25000.00
}
]
GET /api/creditos/credito/{numeroCredito}
- Descrição: Retorna um crédito específico.
- Exemplo:
curl http://localhost:8080/api/creditos/credito/123456
- Resposta (200/404)
Entidade Credito
(atributos principais):
id
(BIGINT auto)numeroCredito
(String)numeroNfse
(String)dataConstituicao
(LocalDate)valorIssqn
(BigDecimal)tipoCredito
(String)simplesNacional
(boolean)aliquota
(BigDecimal)valorFaturado
(BigDecimal)valorDeducao
(BigDecimal)baseCalculo
(BigDecimal)
O DTO CreditoDTO
é usado na camada de apresentação para evitar expor entidades JPA diretamente.
- Producer simples:
ConsultaProducer
publica mensagens no tópicoconsultas-creditos
a cada consulta. - O producer é tolerante a falhas (captura exceptions e apenas loga); isto evita que a indisponibilidade do Kafka quebre a API.
Configuração (via application.properties
ou variáveis de ambiente):
spring.kafka.bootstrap-servers=localhost:9092
spring.kafka.producer.key-serializer=org.apache.kafka.common.serialization.StringSerializer
spring.kafka.producer.value-serializer=org.apache.kafka.common.serialization.StringSerializer
- Se preferir Azure, posso fornecer um
ConsultaPublisherAzure
com a bibliotecacom.azure:azure-messaging-servicebus
e exemplos para enviar mensagens a uma queue/topic do Service Bus.
src/test/java/...
contém testes JUnit e Mockito. Rodar com:
cd backend
mvn -DskipTests=false test
- Um teste de integração usa Testcontainers para levantar um PostgreSQL real durante o teste e garantir que o contexto do Spring inicializa.
- Requer Docker para executar Testcontainers localmente.
Pipeline incluído em .github/workflows/ci.yml
:
- Job
build-backend
: rodamvn test
no backend. - Job
build-frontend
: tenta instalar e buildar o frontend.
Você pode estender o workflow para rodar testes de integração com Testcontainers usando services: docker
ou dind
(mais avançado) ou criar jobs separados para integração.
Erro: failed to read dockerfile: open Dockerfile: no such file or directory
- Causa:
Dockerfile
ausente na pasta do serviço. - Solução: confirmar
backend/Dockerfile
efrontend/Dockerfile
existem. Conteúdos de exemplo estão no repositório final.
Erro (Windows): open //./pipe/dockerDesktopLinuxEngine: The system cannot find the file specified.
- Causa: Docker Desktop não está rodando, ou foi inicializado em modo Windows containers.
- Solução: abrir o Docker Desktop e ativar/reiniciar, garantir modo Linux containers. Em alguns casos reiniciar a máquina ajuda.
Erro: unable to get image 'bitnami/zookeeper:3'
ou falha no docker pull
da Bitnami
- Causa: rede / proxy / imagem removida/versão indefinida
- Solução: executar manualmente
docker pull bitnami/zookeeper:3
ou trocar por imagens Confluent (ver seção 6).
Erro de CORS (frontend -> backend)
- Habilite
@CrossOrigin
no controller ou configure CORS global no Spring Security/Config.
- Não exponha credenciais em
application.properties
em repositórios públicos. Usesecrets
do CI/CD e variáveis de ambiente. - Use senhas seguras e não padrão para o banco de dados em produção.
- Configure TLS para o broker Kafka (SASL) em ambientes reais.
- A API deve validar entradas (size, formato, SQL injection não é questão se usar JPA bem configurado, mas valide tudo) e autenticar/autorizar se for necessário (JWT/OAuth2).
- 1: Tive que colocar o DockerFile, um arquivo em Back-end e outro no Front-end, porque estava tendo problemas, eu sei que geralmente só coloca no Front-end, depois no raiz do projeto usar o comando " docker-compose up --build" no terminal que automáticamente o Front aparecerá.
- 2: Eu usei o Chatgpt prá criar esse Readme, assim ficar mais profissional e evitar possíveis erros, as IA foram feitas prá agilizar o tempo de trabalho.