Visão geral
Motor de cálculo financeiro escrito em Java puro, sem framework. A escolha foi deliberada: quando a camada de segurança é o requisito principal, esconder TLS, JWT e criptografia atrás de um framework tira justamente o controle que interessa.
O sistema recebe propostas comerciais, aplica a regra de taxa do plano contratado e devolve o valor líquido — tudo com o payload cifrado nas duas pontas.
Como a requisição atravessa o sistema
Cliente HTTP (mTLS)
| POST /api/calcular-secure (Bearer JWT + AES)
v
HTTPS Server (TLS)
|-- valida Authorization
|-- descriptografa payload AES-GCM
|-- valida JWT (assinatura, exp, iss, aud)
|-- motor financeiro (assíncrono, pool dedicado)
|-- persistência (JDBC ou memória)
|-- cifra a resposta AES-GCM
v
JSON criptografado
Decisões técnicas que sustentam o projeto
- API HTTP nativa (
HttpServerda JDK) com handlers isolados por responsabilidade. - Processamento assíncrono em pool dedicado, para que cálculo pesado não trave as threads que aceitam conexão.
- JWT HS256 com validação de assinatura,
expe claims opcionaisiss/aud— não basta o token existir, ele precisa ser desta emissão e ainda estar válido. - Criptografia ponta a ponta: TLS na conexão, mTLS para autenticar o cliente, e AES-GCM no corpo. Mesmo quem terminasse o TLS no meio do caminho não leria a proposta.
- Domínio forte:
Planoé enum com a taxa embutida e validação centralizada, então não existe plano inválido circulando como string solta. - Persistência trocável: repositório JDBC configurável por variável de ambiente, com implementação em memória para teste. A regra de negócio não conhece o banco.
- Erro padronizado com
requestIde timestamp em toda resposta, que é o que torna um incidente rastreável depois. - Limites configuráveis de tamanho de payload, timeout de processamento e rate limit.
Endpoints
| Rota | O que faz |
|---|---|
POST /api/calcular-secure | Cálculo com payload cifrado (AES-GCM) |
POST /api/calcular | Versão em texto puro, recusada em modo seguro salvo opt-in explícito |
GET /health | Health check |
O endpoint em texto puro falha fechado: em modo seguro ele recusa, e só responde se alguém
ligar JAVATITAN_ALLOW_PLAIN=true de propósito. O caminho inseguro precisa de uma decisão
consciente, não de um esquecimento.