Files
adaptador-planilhas/docs/spreadsheet-adapter/25-rollback-local.md
T
Ferraz Fagundes 4779d6b2a3
ci / lint, typecheck, testes e build (push) Has been cancelled
ci / Postgres e Redis reais (push) Has been cancelled
ci / imagem Docker Linux (push) Has been cancelled
test(rollback): documenta ensaio isolado de recuperacao
2026-10-17 01:04:30 -03:00

7.8 KiB

Ensaio local de rollback de imagem

Ensaio descartável feito em 17 de outubro de 2026, nesta máquina, no projeto Docker adaptador-rollback-ensaio. Não é o rollback da homologação nem o da produção da Elo Pro.

O gate F11 do checklist continua pendente. Ele exige duas imagens publicadas e o ambiente hml-ada.elopro.app. O procedimento de lá está na seção 10 de 20-homologacao-runbook.md. Este documento não o aprova.

O que foi comparado

Atual Anterior
Commit bd0ecabf41330d8e48dbe070cb090b25fd6eb64c 2be97ea9694eb3fe44e125fbd2ab3e13d8cc488a
Tag da imagem adaptador-planilhas:bd0ecab adaptador-planilhas:2be97ea
Id da imagem sha256:bc06e875c96b2a1f28b406fd0512e40b37399550355f204d32d77ae766db9eed sha256:edc36b8532b172ea940ed6dd252e2f965a91694366adb5828e87f7c72dc520d9

git diff 2be97ea bd0ecab -- src migrations Dockerfile docker docker-compose.yml não tem diferença. O commit atual só acrescenta o smoke local, o package.json, o tsconfig.json e a documentação. As quatro migrations (0001 a 0004) são as mesmas. Por isso a imagem anterior convive com o schema aplicado pela imagem atual. Não houve downgrade de migration.

A tag adaptador-planilhas:local do compose principal não foi reescrita. Antes e depois do ensaio ela continuou sha256:1efe0dfab0a80518563bd8ac2905466eca5692c05a26818a397551fffc05f1fa, com web, worker, Postgres e Redis principais saudáveis. O banco adaptador seguiu com 1 modelo e as flags spreadsheet_adapter Alpha ligada e Beta desligada. O comando flag não foi executado.

Isolamento

Arquivo: docker-compose.rollback-local.yml.

Recurso Nome Publicado no host
Projeto adaptador-rollback-ensaio não
Rede adaptador-rollback-ensaio não
Volume Postgres adaptador-rollback-ensaio-postgres não
Volume storage adaptador-rollback-ensaio-storage não
Banco adaptador_rollback não
Redis interno não
Web 127.0.0.1:3310 só loopback

Não há build: nesse compose. Sem ADAPTER_IMAGE ele recusa subir, para não cair na tag :local. Postgres e Redis não têm porta no host. A sonda scripts/rollback-local-probe.ts só aceita http://127.0.0.1:3310.

Os volumes adaptador-planilhas-local-postgres e adaptador-planilhas-local-storage não entraram no ensaio. Não houve docker compose down -v no projeto principal, nem git reset.

Comandos executados

Conferência de compatibilidade, sem trocar de branch:

git diff --stat 2be97ea bd0ecab -- src migrations Dockerfile docker docker-compose.yml
git worktree add --detach "$TEMP/adaptador-2be97ea-src" 2be97ea

Imagens, sem mover a tag :local:

docker build -t adaptador-planilhas:bd0ecab --build-arg SENTRY_RELEASE=bd0ecabf41330d8e48dbe070cb090b25fd6eb64c --target runner .
docker build -t adaptador-planilhas:2be97ea --build-arg SENTRY_RELEASE=2be97eaf --target runner "$TEMP/adaptador-2be97ea-src"

Subida do ensaio e migration única, com a imagem atual:

export ADAPTER_IMAGE=adaptador-planilhas:bd0ecab
docker compose -p adaptador-rollback-ensaio -f docker-compose.rollback-local.yml up -d postgres redis storage-init
docker compose -p adaptador-rollback-ensaio -f docker-compose.rollback-local.yml run --rm --no-deps web migrate
docker compose -p adaptador-rollback-ensaio -f docker-compose.rollback-local.yml up -d web worker

A migration só rodou depois do Postgres saudável. Aplicou 0001_platform_shim.sql, 0002_spreadsheet_adapter.sql, 0003_rls.sql e 0004_audit_append_only.sql. Não existe passo de down. 0003 e 0004 continuam sem caminho de volta, como no runbook.

Jornada fictícia:

node --import=tsx scripts/rollback-local-probe.ts seed

Troca só de web e worker, volumes intactos:

docker compose -p adaptador-rollback-ensaio -f docker-compose.rollback-local.yml stop -t 30 web worker
export ADAPTER_IMAGE=adaptador-planilhas:2be97ea
docker compose -p adaptador-rollback-ensaio -f docker-compose.rollback-local.yml up -d --no-deps --force-recreate web worker

Volta para a imagem atual, do mesmo jeito, com ADAPTER_IMAGE=adaptador-planilhas:bd0ecab.

Depois das evidências, só o projeto do ensaio foi removido:

docker compose -p adaptador-rollback-ensaio -f docker-compose.rollback-local.yml down -v
git worktree remove --force "$TEMP/adaptador-2be97ea-src"

Antes do down -v, os nomes listados eram apenas adaptador-rollback-ensaio, adaptador-rollback-ensaio-postgres e adaptador-rollback-ensaio-storage. As imagens :bd0ecab e :2be97ea foram mantidas. A tag :local não.

Resultado

Prontidão da imagem atual, antes da troca: HTTP 200, status=ready, environment=development, e config, database, migrations, redis, storage e job_mode em ok.

Dados fictícios gravados:

Campo Valor
Modelo 52add4ba-88b5-4611-b8d7-4ffe33273d3e
Operação ee5fb92f-57ba-4414-a7ab-b9635e243aea
Fonte eabec970-e86d-4b39-8c76-c2b5d10b4674
SHA-256 do XLSX original 74a4130f7712f94727c6bbf8708b9e77fd34e61c7504da8b84be309cbd6d9559
SHA-256 do XLSX exportado 89abbca277ea2569bf63ac5cffcd581181b5b6e97d22a285cf21786e175608dc
SHA-256 do CSV exportado 199e83c30d6fbae7174a4ecd563d32e9ece19a677209e79e88bb56116a6b8977

O mesmo SHA-256 do original foi lido no volume pela imagem atual e, depois da troca, pela imagem 2be97ea. O content_sha256 no banco isolado coincidiu. schema_migrations permaneceu nas quatro migrations. As flags do banco isolado nasceram do login local de desenvolvimento (Alpha ligada, Beta desligada) e não mudaram na troca de imagem.

Na imagem anterior e de novo na atual:

  • GET /api/health/ready voltou ready.
  • O modelo foi encontrado pelo id e pelo nome.
  • A operação permaneceu completed.
  • Os bytes armazenados de XLSX e CSV repetiram o SHA-256.
  • O PDF voltou HTTP 200. O SHA-256 do PDF não se repete: ele é gerado no download, não fica gravado. Isso ocorreu nas duas imagens, não é incompatibilidade de rollback.
  • O worker da imagem anterior registrou [worker] pronto. Depois da restauração, o healthcheck do worker ficou healthy.

Tempo observado da troca, do stop até o ready, no ensaio local: cerca de 3 s na ida para 2be97ea e 2,8 s na volta para bd0ecab. Esse número não descreve pull de registry, Nginx nem a flag do piloto.

Nenhuma incompatibilidade de schema apareceu. O rollback não foi interrompido.

Como repetir a recuperação

  1. Anote a imagem que está no ar. No ensaio, o retorno é adaptador-planilhas:bd0ecab.
  2. Pare só web e worker do projeto isolado, com stop -t 30.
  3. Aponte ADAPTER_IMAGE para a tag do commit desejado.
  4. Suba de novo com up -d --no-deps --force-recreate web worker.
  5. Não rode migration de down. Se migrations não ficar ok, ou se o processo não subir, interrompa e volte para a tag atual pelo mesmo caminho. Schema incompatível é operação planejada, com backup, não rollback às pressas.
  6. Confira /api/health/ready, o modelo, o SHA-256 do original no volume e o download do XLSX e do CSV.

Na homologação real o equivalente está no runbook: tag staging-<sha>, up -d --no-deps web worker, e a flag do módulo é outro passo, feito com flag, antes da troca e só religada depois da saúde. Este ensaio não fez isso e não deve ser copiado para o servidor compartilhado.

Limitações

  • As duas imagens executam o mesmo código de aplicação. O ensaio prova a troca de imagem com volume e schema preservados. Não prova um rollback atravessando uma migration nova.
  • Não usa Supabase, SSO, Sentry nem bucket da Elo Pro.
  • A flag do piloto não foi ligada nem desligada.
  • O PDF não serve como hash de integridade entre downloads.
  • O tempo de 3 s é só o recreate local das duas imagens já presentes no Docker.