Pular para conteúdo

0008 — UUID v7 como PK nas tabelas bi_*

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

Contexto

As tabelas bi_* deste projeto (cliente, filial, vendedor, produto, movimento, meta, posto, trr, custo_inventario) sincronizam com clientes móveis via PowerSync. O PowerSync exige PK single-column TEXT/UUID — BIGSERIAL e PKs compostas não replicam. Ao mesmo tempo, os fatos têm chave natural (NF+produto+ cliente+filial, código do ERP, CNPJ) que precisa continuar valendo para o upsert idempotente.

Decisão

Toda tabela bi_* de domínio usa id UUID NOT NULL DEFAULT uuidv7() PRIMARY KEY (migration V7). A chave natural vira UNIQUE (uq_<tabela>_<sufixo>); FKs apontam para ela (Postgres aceita FK referenciando coluna UNIQUE). O upsert faz ON CONFLICT (chave_natural) DO UPDATE, o que preserva o id (e o xmin) das linhas inalteradas — estabilidade essencial para o PowerSync não gerar checkpoints à toa.

Exceção intencional: bi_configuracao usa id TEXT como chave semântica (KV) — PowerSync aceita TEXT single-column PK, e a KV fica mais legível assim (ver 0014).

Consequências

  • Sync PowerSync viável; id estável cross-sync mesmo em reupload (upsert diff-aware não recria a linha).
  • Exige PostgreSQL 18+ (função uuidv7() nativa) — restrição já registrada na stack.
  • Diverge do irmão bi-transporte-xls, que usa BIGSERIAL (não sincroniza via PowerSync). Ambas as formas são aceitas pela regra cross-project; a escolha aqui é ditada pelo sync ativo.

Alternativas consideradas

  • BIGSERIAL (como no Transporte): mais simples, mas não replica no PowerSync (PK precisa ser TEXT/UUID single-column). Descartado por bloquear o requisito de sync.
  • gen_random_uuid() (v4): funciona no PowerSync, mas UUID v7 é time-ordered — melhor localidade de índice e ordenação natural por criação. Descartado em favor do v7.