Sincronização Offline — Visão Geral
Última atualização: 15 de julho de 2026
O que é este fluxo
Praticamente tudo documentado nos fluxos anteriores depende de dados que chegaram ao SQLite local através de uma sincronização: clientes, produtos, preços, estoque, promoções, formas de pagamento, e os próprios pedidos. Este fluxo documenta como esses dados chegam até o dispositivo, como o app decide entre trazer tudo de novo ou só o que mudou, como ele se recupera se a sincronização for interrompida, e o que acontece quando o vendedor troca de organização.
Esta seção documenta o fluxo em cinco partes:
| Doc | Conteúdo |
|---|---|
| Visão Geral (este documento) | Orquestração, sequência real de sincronização, arquivos-chave |
| Sincronização Completa vs Incremental | Como a identidade da sessão decide entre full e recent |
| Estado, Modal e Recuperação de Falha | Persistência do progresso, retomada após o app morrer no meio |
| Troca de Organização | O que é limpo e o que é preservado ao trocar de organização |
| Monitoramento Contínuo e Filas de Retry | Os serviços de fundo que mantêm dados e envios em dia |
Quem de fato orquestra a sincronização
Existe uma armadilha para quem for ler o código pela primeira vez: SyncService.syncAll, em services/sync/sync.services.ts, parece ser o orquestrador principal, mas não é chamado pela UI em lugar nenhum do app. Quem de fato dirige a sincronização é SyncProvider, em providers/sync/sync.provider.tsx, que reimplementa a mesma sequência de syncAll passo a passo, dentro de startSyncAll. A diferença é que o provider precisa acompanhar o progresso de cada etapa individualmente, permitir retomada depois de uma falha, e refletir tudo isso num estado que a UI observa, coisa que uma função só com uma sequência de await não conseguiria expor.
SyncService continua sendo útil, e é usado de fato, só que em pedaços: o provider chama svc.Organization(...), svc.syncClients(...), svc.syncProducts(...) e assim por diante, um a um, controlando o estado de cada chamada.
A sequência real de sincronização
A ordem importa porque entidades mais adiante dependem de dados já sincronizados antes (preço depende de produto e empresa, por exemplo). A sequência real, tirada de startSyncAll, é:
organization → organizationSettings → user → carriers → cities → clients →
aliquots → productAliquots → products → productCategoriesBatch →
alternativeUnits → productFilters → similarProductsDetailed →
suggestedProductsDetailed → formattedReports → stocks → prices →
promotions → operations → operationsGroups → paymentMethods →
companies → saleStatuses → saleDrafts
Cada uma dessas etapas é um passo independente no estado do provider, cada um com seu próprio status (pending, active, done, error), progresso e horários de início/fim.
Arquivos-chave
| Arquivo | Responsabilidade |
|---|---|
providers/sync/sync.provider.tsx | Orquestrador real: sequência de etapas, estado, retomada |
services/sync/sync.services.ts | Um método por entidade, decisão entre full/recent, lastUpdatedAt |
storage/sync/sync.storage.ts | Persistência de lastUpdatedAt por entidade e do estado de sync |
features/sync/sync.tsx + sync.modal.tsx | Modal de progresso mostrado ao usuário |
services/sync-entity-monitor/sync-entity-monitor.service.ts | Mutex entre serviços de fundo + poller de entidades alteradas |
services/sync-queue/sync-queue.service.ts | Cliente HTTP para o endpoint de entidades alteradas |
Onde a sincronização é disparada
startSyncAll é chamado em três momentos distintos: depois de um login com callback de deep link bem-sucedido (documentado em Login e Callback OAuth), manualmente pela ação "Atualizar Base de Produtos" do catálogo ou "Atualizar Base de Clientes" da carteira, e ao trocar de organização (documentado em Troca de Organização).