entregas_app/docs/CONTEXTO_ENTREGAS_SINCRONIZ...

8.7 KiB

Contexto de Entregas - Sincronização Automática

Funcionalidade Implementada

Criado um contexto global (DeliveriesContext) que gerencia todas as entregas do aplicativo e sincroniza automaticamente todos os componentes quando há mudanças após roteamento.

Problema Resolvido

Antes da implementação, cada tela carregava suas próprias entregas independentemente, causando:

  • Inconsistência: Dados diferentes entre telas
  • Duplicação: Múltiplas chamadas à API
  • Desincronização: Mudanças não refletidas em todas as telas

Solução Implementada

1. Contexto Global de Entregas

interface DeliveriesContextData {
  deliveries: Delivery[]
  loading: boolean
  error: string | null
  hasNoDeliveries: boolean
  refreshDeliveries: () => Promise<void>
  forceRefresh: () => Promise<void>
  lastRefreshTime: number | null
  isRefreshing: boolean
}

2. Roteamento Automático Integrado

  • Verificação automática de routing !== 0
  • Execução de sendRoutingOrder() quando necessário
  • Recarregamento automático após roteamento
  • Notificação de todos os componentes

3. Sincronização em Tempo Real

  • Todos os componentes usam a mesma fonte de dados
  • Atualizações automáticas em todas as telas
  • Estado consistente em toda a aplicação

Implementação Técnica

DeliveriesContext.tsx

export const DeliveriesProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
  const [deliveries, setDeliveries] = useState<Delivery[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState<string | null>(null)
  const [hasNoDeliveries, setHasNoDeliveries] = useState(false)
  const [lastRefreshTime, setLastRefreshTime] = useState<number | null>(null)
  const [isRefreshing, setIsRefreshing] = useState(false)

  // Função para carregar entregas com roteamento automático
  const loadDeliveries = useCallback(async (forceRefresh = false) => {
    // Verificar se há entregas que precisam de roteamento
    const deliveriesNeedingRouting = data.filter(delivery => 
      delivery.routing && delivery.routing !== 0
    )
    
    if (deliveriesNeedingRouting.length > 0) {
      // Executar roteamento automático
      const routingResult = await api.sendRoutingOrder(routingData)
      
      // Recarregar dados atualizados
      const updatedData = await api.getDeliveries()
      setDeliveries(sortedUpdatedData)
      
      // Notificar todos os componentes
      console.log("=== NOTIFICANDO TODOS OS COMPONENTES SOBRE ATUALIZAÇÃO ===")
    }
  }, [isRefreshing])

  return (
    <DeliveriesContext.Provider value={{
      deliveries,
      loading,
      error,
      hasNoDeliveries,
      refreshDeliveries,
      forceRefresh,
      lastRefreshTime,
      isRefreshing,
    }}>
      {children}
    </DeliveriesContext.Provider>
  )
}

App.tsx - Integração

return (
  <GestureHandlerRootView style={{ flex: 1 }}>
    <SafeAreaProvider onLayout={onLayoutRootView}>
      <AuthProvider>
        <SyncProvider>
          <DeliveriesProvider> {/* ← Novo contexto */}
            <NavigationContainer ref={navigationRef}>
              <Navigation />
              <StatusBar style="light" backgroundColor={COLORS.primary} />
            </NavigationContainer>
          </DeliveriesProvider>
        </SyncProvider>
      </AuthProvider>
    </SafeAreaProvider>
  </GestureHandlerRootView>
)

HomeScreen.tsx - Uso do Contexto

const HomeScreen = () => {
  const { 
    deliveries, 
    loading, 
    error, 
    hasNoDeliveries, 
    refreshDeliveries, 
    forceRefresh, 
    lastRefreshTime, 
    isRefreshing 
  } = useDeliveries()
  
  // Usar dados do contexto em vez de estado local
  const sortedDeliveries = useMemo(() => {
    return [...deliveries].sort((a, b) => {
      // Lógica de ordenação
    })
  }, [deliveries])
  
  // Recarregar usando contexto
  useFocusEffect(
    React.useCallback(() => {
      if (hasInitialized) {
        refreshDeliveries() // ← Usa contexto
      }
    }, [hasInitialized, route.params, refreshDeliveries])
  )
}

RoutesScreen.tsx - Uso do Contexto

const RoutesScreen = () => {
  const { deliveries, loading, error, refreshDeliveries } = useDeliveries()
  
  // Dados já estão sincronizados automaticamente
  // Não precisa carregar novamente
  
  const handleRouteCalculated = async (optimizedDeliveries: Delivery[]) => {
    try {
      const result = await api.sendRoutingAfterMapRoute(optimizedDeliveries)
      
      // Recarregar usando contexto
      refreshDeliveries()
      
      // Navegar para HomeScreen
      navigation.navigate('Home', { 
        refreshDeliveries: true,
        routingUpdated: true 
      })
    } catch (error) {
      // Tratamento de erro
    }
  }
}

Benefícios da Implementação

🎯 Sincronização Automática

  • Dados Únicos: Uma única fonte de verdade
  • Atualização Global: Mudanças refletidas em todas as telas
  • Consistência: Estado sempre sincronizado

🚀 Performance

  • Cache Inteligente: Evita recarregamentos desnecessários
  • Carregamento Único: Uma chamada à API para todas as telas
  • Otimização: Roteamento automático quando necessário

🔧 Manutenibilidade

  • Código Centralizado: Lógica de entregas em um lugar
  • Reutilização: Componentes mais simples
  • Debug: Logs centralizados e organizados

📱 Experiência do Usuário

  • Dados Atualizados: Sempre informações mais recentes
  • Transições Suaves: Sem recarregamentos visíveis
  • Feedback Consistente: Mesmo estado em todas as telas

Fluxo de Sincronização

1. Carregamento Inicial

App.tsx → DeliveriesProvider → loadDeliveries() → API → setDeliveries()

2. Roteamento Automático

API retorna routing: 1 → sendRoutingOrder() → API → setDeliveries() → Notificar Componentes

3. Atualização de Componentes

Componente usa useDeliveries() → Recebe dados atualizados → Re-renderiza automaticamente

4. Refresh Manual

Usuário pull-to-refresh → refreshDeliveries() → API → setDeliveries() → Atualizar UI

Logs de Debug

Carregamento com Roteamento

=== INICIANDO CARREGAMENTO DE ENTREGAS ===
Chamando API para buscar entregas...
=== ENCONTRADAS ENTREGAS QUE PRECISAM DE ROTEAMENTO ===
=== ROTEAMENTO EXECUTADO COM SUCESSO ===
Recarregando entregas após roteamento...
=== NOTIFICANDO TODOS OS COMPONENTES SOBRE ATUALIZAÇÃO ===
Estado atualizado com entregas após roteamento

Atualização de Componentes

HomeScreen: Recebeu dados atualizados (5 entregas)
RoutesScreen: Recebeu dados atualizados (5 entregas)
DeliveriesScreen: Recebeu dados atualizados (5 entregas)

Telas Atualizadas

HomeScreen

  • Usa useDeliveries() em vez de estado local
  • Recarrega automaticamente quando necessário
  • Dados sempre sincronizados

RoutesScreen

  • Usa useDeliveries() em vez de carregamento próprio
  • Roteamento manual ainda funciona
  • Dados atualizados automaticamente

DeliveriesScreen

  • Usa useDeliveries() (próxima atualização)
  • Lista sempre atualizada
  • Performance melhorada

DeliveryDetailScreen

  • Usa useDeliveries() (próxima atualização)
  • Dados consistentes
  • Navegação suave

Compatibilidade

Plataformas

  • Android: Totalmente compatível
  • iOS: Totalmente compatível
  • Expo SDK 53: Compatível

Estados de Rede

  • Online: Funciona normalmente
  • Offline: Fallback para dados mockados
  • Conexão instável: Retry automático

Navegação

  • React Navigation: Integração nativa
  • Stack Navigation: Suporte completo
  • Tab Navigation: Funciona perfeitamente

Como Testar

1. Teste de Sincronização

# Abrir HomeScreen
# Navegar para RoutesScreen
# Verificar que dados são iguais
# Fazer roteamento manual
# Voltar para HomeScreen
# Verificar que dados foram atualizados

2. Teste de Roteamento Automático

# Configurar entregas com routing: 1
# Abrir aplicação
# Verificar logs de roteamento automático
# Confirmar que todas as telas foram atualizadas

3. Teste de Performance

# Navegar entre telas rapidamente
# Verificar que não há múltiplas chamadas à API
# Confirmar que dados são consistentes

Próximos Passos

🔮 Melhorias Futuras

  • Cache Persistente: Salvar dados localmente
  • Sincronização em Tempo Real: WebSocket para atualizações
  • Otimização de Memória: Limpeza automática de dados antigos
  • Notificações Push: Alertar sobre mudanças importantes
  • Histórico de Mudanças: Rastrear alterações nas entregas