ADR 3 — Operação offline como requisito de arquitetura
O problema
Terminal de apontamento no chão de fábrica, usado pelo operador durante o turno para registrar parada, motivo e produção. A rede de fábrica cai como rotina, não como incidente: interferência, cobertura irregular entre galpões, equipamento competindo pelo mesmo espectro.
O que eu já sabia antes de levantar requisito
Trabalhei oito anos e oito meses nessa operação antes de programar, e isso encurtou a decisão. Eu sabia o que acontece quando o sistema não aceita o apontamento: o operador anota num papel e alguém digita depois, ou ninguém digita. Nos dois casos o dado que chega ao indicador é ficção.
Essa é a parte que o comportamento padrão — exigir conexão e mostrar erro — não enxerga. Ele transforma indisponibilidade de rede em indisponibilidade do processo, e um sistema contornado é pior que sistema nenhum, porque o indicador passa a existir e a estar errado. Indicador errado dá confiança falsa a quem decide com ele.
Por que fila de envio não bastava
O reflexo natural é guardar o que não conseguiu enviar e reenviar depois. Isso resolve metade do problema, e por um tempo eu achei que fosse o suficiente.
Trata a escrita e ignora a leitura. O operador não só registra: ele consulta o estado atual da máquina, o motivo da última parada e o que já foi produzido no turno. Sem rede, uma fila de envio deixa a tela vazia, e tela vazia é tão inutilizável quanto erro de conexão. O operador que abre o terminal e não vê nada volta para o papel do mesmo jeito.
A decisão
O terminal mantém a própria cópia do que precisa para operar, funciona sobre ela e reconcilia quando a rede volta. PWA com armazenamento local e sincronização, decidido antes de escrever o cliente.
O tracejado é o que importa: tudo dentro dele continua funcionando sem a seta que sai. Se o terminal fosse uma casca sobre o servidor, essa caixa não existiria — e é ela que custa caro para acrescentar depois.
Conflito, e a política que eu escolhi
No momento em que o terminal pode decidir sozinho, dois terminais podem discordar sobre a mesma máquina, e a reconciliação deixa de ser detalhe e vira regra de negócio.
A política adotada é última escrita vence, pelo carimbo de tempo da alteração registrado no próprio terminal, com a sincronização acontecendo em lote e devolvendo resultado individual por operação: uma operação rejeitada não derruba as outras do mesmo lote, o que importa quando o terminal volta de horas offline com dezenas de registros acumulados.
É a política mais simples que resolve o caso real, e tem uma fraqueza conhecida que eu aceito de olhos abertos: ela confia no relógio do terminal. Dois tablets com horário divergente produzem uma ordem de precedência que não corresponde à ordem dos fatos. No contexto real, com os terminais na mesma rede sincronizando horário e conflito genuíno sendo raro porque cada terminal atende um posto, o risco é pequeno. Em outro contexto seria a escolha errada.
O outro custo é permanente: o frontend deixa de ser uma casca sobre a API e passa a ter estado próprio, ciclo de vida próprio e bugs próprios, inclusive a classe mais difícil de todas — a que só aparece na transição entre offline e online.
Como envelheceu
Foi a decisão certa, e o que a validou foi o custo evitado. Decidir isso no início mudou a arquitetura inteira do cliente. Como recurso para acrescentar na segunda fase, teria custado reescrita, porque “funcionar offline” não é uma camada que se instala sobre uma aplicação que assume conexão: é uma premissa que atravessa cada tela.
É o argumento de Projetar antes de implementar no caso concreto. A decisão custou uma conversa na fase de projeto e teria custado meses depois.
O que eu faria diferente
Teria decidido a política de conflito na fase de projeto, e não durante a implementação. Ela funciona e está documentada no código, mas foi consequência e não escolha deliberada — e as duas coisas se parecem enquanto nada dá errado.
Concretamente, teria avaliado carimbo de tempo do servidor no momento do recebimento. Perde a ordem real dos fatos quando o terminal ficou muito tempo offline, mas elimina a dependência do relógio do cliente. Não é obviamente melhor, é uma troca — e o ponto é que eu não fiz essa troca conscientemente na época.
Ver também
Monitoramento industrial · Trajetória · Projetar antes de implementar