Fase 3 — UUID v7 (PostgreSQL 18+)¶
Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-09-15 · Decidido em: 2026-07-06
Objetivo: migrar identificadores de UUID v4 (gen_random_uuid() no id) para UUID v7 (ordenável no tempo, RFC 9562), com baixo risco e janelas de migração controladas.
Por que esta ordem (recomendada)¶
- Flyway (este repositório) adiciona
id_v7 UUIDnullable em todas as tabelas com PKid UUID, sem alterarid, PKs nem FKs. - Job / ferramenta banco → banco (fora deste JAR) preenche
id_v7com a estratégia de negócio (ex.: derivar timestamp de colunas existentes, mapeamento 1:1 doidantigo para um v7 gerado de forma reproduzível, etc.). - Migração Flyway V15 (passo 3): após dados estáveis e backfill, renomear a coluna
id(v4) paraold_id(deixa de ser PK; mantém índiceidx_*_old_id), renomearid_v7→id(nova PK comDEFAULT uuidv7()). O UUID legado permanece consultável emold_id(ex.: PowerSync resolve poridouold_id). - Migração Flyway V16 (passo 4): a V15 deixa
old_idNOT NULL (herdado da antiga PK); a V16 fazALTER COLUMN old_id DROP NOT NULLnas tabelas de domínio, para permitir novos inserts apenas comidv7 (sem UUID legado emold_id).
Assim o schema permanece válido entre os passos; rollback é mais simples (colunas extras vs. troca de PK no meio do caminho).
Escopo das tabelas (id UUID)¶
| Tabela | Notas |
|---|---|
contratos, estoque, itens, itenslote, itensped, itenspedamx, itpedamxdi, loteest, municipio, notacompl, propriedades, tbpcoest, veiculos |
PK id UUID desde V1+ |
Fora deste passo: request e push_enviada usam BIGINT identity; pabast_* usam VARCHAR como PK — não recebem id_v7 nesta fase.
Migração Flyway¶
V14__uuid_v7_add_id_v7_columns.sql(emdb/migration):ALTER TABLE ... ADD COLUMN IF NOT EXISTS id_v7 UUID+ comentários.V15__uuid_v7_id_old_id_swap.sql(emdb/migration): troca de PK conforme acima; cópia de referência em docs/dev/sql/V15__uuid_v7_swap_id_rename_to_id.sql.V16__old_id_nullable.sql(emdb/migration):old_idpassa a aceitar NULL; cópia em docs/dev/sql/V16__old_id_nullable.sql.
Ordem operacional e deploy: runbook-migration-uuid-v7.md.
Não define DEFAULT uuidv7() na V14: enquanto o backfill não estiver completo, defaults automáticos poderiam gerar v7 “novos” por linha de forma indesejada; a V15 fixa DEFAULT uuidv7() após o rename.
Runbook (operacional)¶
Passo a passo: backup, V14, sincronização de dados, V15, deploy — runbook-migration-uuid-v7.md.
PostgreSQL 18 e uuidv7()¶
A função uuidv7() está disponível no PostgreSQL 18+. Use essa versão (ou superior) no servidor e nos testes de integração que validam uuidv7().
Migrações que apenas adicionam coluna UUID sem chamar uuidv7() no SQL rodam em versões anteriores; qualquer migration futura que use uuidv7() no DDL exige PG 18+.
Testes¶
O projeto inclui teste de integração com Testcontainers (postgres:18) que aplica todo o histórico Flyway e verifica:
- com Flyway até V14: presença de
id_v7nas tabelas listadas; com histórico completo (V15–V16): colunasideold_idem tabelas de domínio, semid_v7, eold_idanulável (V16); SELECT uuidv7()executa com sucesso.
Requisito: Docker disponível na máquina / CI ao rodar esses testes.
Para ignorar o teste Testcontainers (ex.: ambiente sem daemon Docker): variável de ambiente SKIP_DOCKER_TESTS=true.
Correção 2026-09-15: o
SKIP_DOCKER_TESTSnão é lido por nenhum teste. O teste da linha do tempo de migration (Postgres18UuidV7FlywayIntegrationTest) sobe um container dedicado e leva o@IntegracaoDockerdaxadm-comum-teste: roda por padrão e só pula com o Docker ausente, com o motivo emERRORno log e no relatório do JUnit (micronaut-profiles).
Referências¶
- Plano de migração “integrador v2” (workspace).
- Fases anteriores: migration-phase2-cors-jwt.md, pabast-removal-phase1.md.
- Deploy (Coolify, subdomínios, porta 8080): migration-phase4-coolify.md.
- PowerSync (compose, volumes, restart seguro): migration-phase5-powersync-runbook.md.
- Segurança API / roadmap (Fases 6–9): migration-roadmap-phases-6-9.md.