0008 — Object storage Garage com 3 modos¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-08-11 · Decidido em: 2026-05-21
Nota 2026-08-11: esta decisão é o design (3 modos, seam, chave content-addressed). A implementação (
ArquivoXlsStorage/S3ArquivoXlsStorage/ArmazenamentoModo/S3Config/...) foi extraída para a libbr.com.xadm:xadm-comum-storagee o app adotou-a — ver decisão 0025. Prefixos de config e comportamento inalterados; as classes vivem agora embr.com.xadm.comum.armazenamento.
Contexto¶
O binário do .xlsx recebido era guardado em BYTEA no Postgres, o que infla o
banco. 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 ArquivoXlsStorage (impl S3ArquivoXlsStorage, AWS SDK v2) com 3
modos (app.storage.modo / env S3_FILE_STORAGE):
PSQL— só Postgres (arquivo_bytes).PSQL_GARAGE(default) — grava nos dois, lê do Garage. Rede de segurança.GARAGE— só Garage; oBYTEAficaNULL.
Chave content-addressed: {aaaa}/{mm}/{checksum_sha256}.xlsx. O backfill
(StorageBackfillService, @Order(-100), idempotente) roda no startup em todo
modo; é no-op no modo PSQL.
Correção 2026-06-12: o texto dizia "backfill opt-in (
app.storage.backfill.enabled)"; essa property não existe — o backfill roda sempre no startup. Fato incidental — a decisão (3 modos) segue (§1.4).
Consequências¶
- Migração reversível: a coluna
arquivo_bytesnão é dropada — o "cleanup" do modoGARAGEé zerar bytes em runtime. - Falha de I/O no upload →
StorageIndisponivelException→ HTTP 503 (sem linha persistida; o cliente reenvia).
Alternativas consideradas¶
- Só Postgres BYTEA: o banco infla com o volume de uploads. Descartado.
- Migrar direto para
GARAGEsem o modo dual: sem rede de segurança se o storage falhar durante a transição. Descartado em favor doPSQL_GARAGE.