Pular para conteúdo

0005 — Object storage Garage com 3 modos

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-08-11 · Decidido em: 2026-05-21

Contexto

O binário do .xlsx recebido era guardado em BYTEA (arquivo_bytes) no Postgres, o que infla o banco a cada upload. Quer-se mover para object storage S3-compatível (Garage) sem perder a rede de segurança durante a transição.

Decisão

Um seam storage/ArquivoXlsStorage (impl S3ArquivoXlsStorage, AWS SDK v2; factory S3ClientFactory; coordenador service/ArmazenamentoArquivoService) com 3 modos (app.storage.modo / env S3_FILE_STORAGE, MAIÚSCULAS):

  • PSQL — só Postgres (arquivo_bytes).
  • PSQL_GARAGE (default) — grava nos dois, lê do Garage. Rede de segurança.
  • GARAGE — só Garage; o BYTEA fica NULL.

Chave content-addressed: {aaaa}/{mm}/{checksum_sha256}.xlsx. A partição usa periodoInicial quando já disponível; senão, recebidoEm.toLocalDate() (no receber() ainda não há período — só após o parse async). O StorageBackfillService é opt-in (app.storage.backfill.enabled=true), roda no startup com @Order(-100), é idempotente e isola falhas por linha.

Consequências

  • Migração reversível: a coluna arquivo_bytes não é dropada — o "cleanup" do modo GARAGE é zerar os bytes em runtime, não um DROP.
  • Falha de I/O no upload → StorageIndisponivelException → HTTP 503 (sem linha persistida; o cliente reenvia).
  • Bucket de produção onpetro, endpoint compartilhado arquivo-api.xadm.biz.

Atualização (ADR 0019 — bi-commons): o seam + impl deixaram de ser cópia local. ArquivoXlsStorage, S3ArquivoXlsStorage, S3ClientFactory, ArmazenamentoModo (+ os records de config S3Config/ArmazenamentoConfig) vêm da lib br.com.xadm:xadm-comum-storage:0.1.0 (br.com.xadm.comum.armazenamento); os checksums WHEN_REQUIRED para o Garage e os prefixos de config s3.*/app.storage.* são idênticos. Local fica só o coordenador service/ArmazenamentoArquivoService (domínio). Utilitários correlatos (ChecksumSha256, DataConverter) idem, via xadm-comum-util:0.1.0. A decisão dos 3 modos abaixo segue valendo.

Alternativas consideradas

  • Só Postgres BYTEA: o banco infla com o volume de uploads. Descartado.
  • Migrar direto para GARAGE sem o modo dual: sem rede de segurança se o storage falhar durante a transição. Descartado em favor do PSQL_GARAGE default.