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— tipoTIMESTAMP,sistema=TRUE. Sinal monotônico de reset, consumido pelo cliente Flutter (contrato preservado da etapa 05).slow_query_timeout_ms— tipoINT, valor10000,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. Rowssistema=TRUE(ex.:ultimo_nuke) aparecem read-only; POST manual via curl numa chave de sistema retorna 403. Chave nova pela UI nascesistema=FALSE; chave de sistema só nasce via migration ou repo. - Sinal de reset: o reset (etapa 05) faz UPSERT em
ultimo_nuke = NOW()::TEXTnoFINALIZAR; o cliente compara com o valor que guardou e disparadisconnectAndClearquando 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_configuracaosem GRANT aopowersync_role→ não sincroniza (42501); consolidado em V13 (decisão 0013).