Pular para conteúdo

Etapa 06 — Configuração global sincronizada

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

Fornece a tabela KV sincronizada que os clientes e o backend leem em runtime — e o canal do sinal de reset disparado pela etapa 05.

1. Contexto e escopo

Algumas configurações precisam ser compartilhadas entre o backend e os clientes móveis em runtime — e o sinal de reset do Powersync precisa chegar aos celulares. A solução é uma tabela KV (bi_configuracao) sincronizada via PowerSync, consumida pelos dois lados.

Dentro do escopo: a tabela KV; o consumo no backend (cache + TTL); as telas de administração; o sinal de reset (ultimo_nuke); a separação chaves de sistema vs editáveis.

Fora do escopo: o serviço de reset em si → etapa 05.

2. Modelo de dados

bi_configuracao (V12__bi_configuracao.sql) é bi_* (sincroniza via PowerSync, stream recent_data, priority 0; GRANT ao powersync_role garantido em V13). A chave é o próprio id (TEXT) — não há surrogate.

erDiagram
    bi_configuracao {
        text id PK "a chave É o id semântico"
        text valor "NOT NULL"
        varchar tipo "CHECK: STRING|INT|BOOL|TIMESTAMP|JSON"
        text descricao
        boolean sistema "NOT NULL default FALSE; TRUE = read-only na UI"
        timestamptz atualizado_em "NOT NULL default NOW()"
    }
  • CHECK chk_bi_configuracao_tipo: tipo ∈ {STRING, INT, BOOL, TIMESTAMP, JSON}.
  • Seed (V12, ON CONFLICT (id) DO NOTHING):
  • ultimo_nuke — tipo TIMESTAMP, sistema=TRUE. Sinal monotônico de reset, consumido pelo cliente Flutter (contrato preservado da etapa 05).
  • slow_query_timeout_ms — tipo INT, valor 10000, sistema=FALSE (editável).

Renomear o id = delete + insert (é a chave semântica, não surrogate).

3. Fluxos principais

  • Backend (service/ConfigService): lê com cache in-memory + TTL 30 s (getString/getInt/getBool/getDuration(key, default)). Janela máxima de staleness após edição pela UI = 30 s.
  • Cliente Flutter: lê via PowerSync sync (stream recent_data).
  • Telas admin (ConfiguracaoAdminViewController, sob login Google — etapa 07): listam, editam e criam chaves. Rows sistema=TRUE (ex.: ultimo_nuke) aparecem read-only; POST manual via curl numa chave de sistema retorna 403. Chave nova pela UI nasce sistema=FALSE; chave de sistema só nasce via migration ou repo.
  • Sinal de reset: o reset (etapa 05) faz UPSERT em ultimo_nuke = NOW()::TEXT no FINALIZAR; o cliente compara com o valor que guardou e dispara disconnectAndClear quando muda.

4. Decisões

Nº Decisão
0010 Sinal de reset via bi_configuracao

5. Riscos

  • Edição de chave de sistema corromper o sinal → bloqueado na UI (read-only) e no POST (403).
  • Staleness de até 30 s no backend após edição → aceitável por design (TTL do cache); documentado.
  • bi_configuracao sem GRANT ao powersync_role → não sincroniza (42501); consolidado em V13 (decisão 0013).