Skip to content

Charge lifecycle: transições de status, GET, idempotência, webhooks e confiabilidade do outbox - #12

Merged
lmoraesdev merged 15 commits into
developfrom
feature/charge-lifecycle-webhooks
Jul 23, 2026
Merged

Charge lifecycle: transições de status, GET, idempotência, webhooks e confiabilidade do outbox#12
lmoraesdev merged 15 commits into
developfrom
feature/charge-lifecycle-webhooks

Conversation

@lmoraesdev

Copy link
Copy Markdown
Owner

Summary

Fecha o ciclo de vida da cobrança (transições de status, expiração automática), adiciona endpoints faltantes (GET, webhook do provedor), idempotência em POST /charges, e reforça a confiabilidade/observabilidade do outbox pattern.

Domínio e API

  • Charge.transitionTo() com máquina de estados explícita (ACTIVE → PAID/EXPIRED/CANCELLED) + expiresAt persistido de verdade (era derivado em runtime antes)
  • GET /charges/{id} com ChargeNotFoundException → 404
  • Idempotência em POST /charges via header Idempotency-Key (hash do corpo, conflito → 422)
  • POST /webhooks/provider — processa notificações do provedor Pix de forma idempotente (dedup por eventId), transiciona a charge e grava evento no outbox
  • Job agendado (ChargeExpirationJob) expira cobranças vencidas automaticamente

Confiabilidade do outbox

  • OutboxRelay migrado pra SELECT ... FOR UPDATE SKIP LOCKED — evita duas instâncias publicando o mesmo evento em paralelo, sem segurar transação durante a chamada de rede pro Kafka
  • Logging do outbox migrado pra Logger5w1hBuilder (era SLF4J puro)
  • Propagação do correlationId do request original pro log de falha de publish, mesmo rodando dentro de um @Scheduled desacoplado

Observabilidade

  • Métricas Micrometer: charges_created_total, webhooks_processed_total, outbox_events_published_total/outbox_events_failed_total/outbox_publish_lag
  • Fix no Logger5w1h: mensagem real no log (.log() sem argumento gravava null — SLF4J fluent API não deriva a mensagem de addKeyValue() sozinho)
  • Ruído de SQL/DDL/framework suprimido nos testes; stack trace enxuto (%wEx{0}) via logback-test.xml

Persistência

  • Migração de ddl-auto: update pra Flyway (schema versionado, ddl-auto: validate) — elimina o eco de DDL no console como efeito colateral

Arquitetura

  • ArchUnit trava a pureza do domínio hexagonal (nenhuma classe em domain/** pode depender de Spring ou jakarta.persistence)

Test plan

  • ./mvnw clean verify com Docker real: 40 testes unitários + 16 de integração, tudo verde
  • Flyway aplica as 3 migrations (V1 schema inicial, V2 IN_FLIGHT, V3 correlation_id) e Hibernate valida contra elas (ddl-auto: validate)
  • spotless:check / checkstyle:check sem violações
  • TDD em todo o trabalho: cada mudança de comportamento tem teste que falhou antes da implementação e passou depois

@lmoraesdev
lmoraesdev merged commit 0709fed into develop Jul 23, 2026
2 checks passed
@lmoraesdev
lmoraesdev deleted the feature/charge-lifecycle-webhooks branch July 23, 2026 01:36
@lmoraesdev lmoraesdev mentioned this pull request Jul 23, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant