Pular para conteúdo

Fase 7 — Flyway V15 + integrador legado → integrador novo (sincronização)

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-07-06 · Decidido em: 2026-07-06

Objetivo: durante a transição, manter dois integradores alinhados: o legado continua a ser o ponto de entrada do ERP; o novo (este repositório / stack alvo) recebe uma réplica das mesmas operações via HTTP.

1. Base de dados (integrador novo)

1.1 Migração V15 (V15__uuid_v7_id_old_id_swap.sql)

Após V14 (coluna id_v7) e backfill completo de id_v7 (NOT NULL, único por linha), a V15:

  • Renomeia id (UUID v4, antiga PK) → old_id (não é PK; o índice secundário idx_*_id passa a idx_*_old_id).
  • Renomeia id_v7 → id (nova PK com DEFAULT uuidv7()).

Assim não se perde o identificador v4: permanece em old_id, indexado. A V15 deixa old_id ainda NOT NULL (herdado da antiga PK); a V16 (V16__old_id_nullable.sql) faz ALTER COLUMN old_id DROP NOT NULL nas 13 tabelas, para que novas linhas criadas após a migração possam ter old_id NULL.

Documentação operacional: runbook-migration-uuid-v7.md · SQL de referência: sql/V15__uuid_v7_swap_id_rename_to_id.sql · sql/V16__old_id_nullable.sql.

1.2 PowerSync — resolução do UUID no PATCH

O endpoint POST /api/v1/powersync recebe no JSON o campo id (UUID). O servidor procura a linha em propriedades, estoque ou veiculos por:

  1. id (PK v7), ou se não existir,
  2. old_id (UUID v4 legado).

Implementação: findById(id).or(() -> findByOldId(id)) nos repositórios correspondentes.

A decisão 0013 estendeu esse PATCH para o write-back de venda (Chave*/CodRetorno/MsgRetorno) também em contratos, itensped e fones — fones resolve só por id (tabela nova, sem old_id).

1.3 Health — tabela request

Cada GET /api/health bem-sucedido (após o filtro Bearer) grava uma linha na tabela request com origem = API_HEALTH, tipo GET, JSON com metadados do pedido (path, method, query opcional, timestamp), alinhado ao padrão de registos de outras APIs (ex.: PowerSync, XADM).

2. Integrador antigo (projeto original)

  • Continua a receber as chamadas do ERP como hoje.
  • Para os fluxos acordados pelo time, após processar localmente (ou em paralelo), o legado deve chamar o integrador novo:
  • Método e path: alinhados ao contrato REST do novo (ex.: mesmo path relativo que o ERP usaria no novo, ou tabela de mapeamento 1:1).
  • Corpo: exactamente o mesmo JSON (e restantes dados) recebidos do ERP — reencaminhamento fiel.
  • Headers: incluir Authorization: Bearer com o token estático partilhado (o mesmo configurado no novo integrador — ver Fase 6).

3. Resultado esperado

  • ERP → legado → novo: os dois backends aplicam a mesma carga de dados/API, mantendo-se sincronizados até se desligar o legado ou remover o encaminhamento.
  • Falhas na chamada ao novo devem ter estratégia definida (retry, log, alerta, fila — fora do âmbito mínimo deste documento, mas obrigatório no desenho de deploy).
  • Paridade com o legado (ordem + deadlock): o ERP especifica pares DELETE → PUT que precisam ser aplicados na ordem de chegada. O novo integrador serializa o trecho de persistência do /api/v1/xadm com um ReentrantLock(fair=true) global — só um request XADM por vez. Isso preserva ordering FIFO e elimina deadlocks 40P01 em itenspedamx entre transações XADM concorrentes (incidente de 2026-04-24). Ver xadm-error-handling.md.

Fora de âmbito desta fase

  • Login de browser / auth.xadm.biz nas telas — Fase 8.
  • Auditoria e remoção de guards de prod — Fase 9.

Referências