4) Sincronização offline

Esta rota permite que o app, quando estiver online, consulte o ERP e baixe os QR Codes ativos + metadados mínimos necessários para operação offline. O objetivo é abastecer o cache local do aplicativo para uso em campo quando não houver internet.

Auth: X-APP-KEY + X-DEVICE-TOKEN Formato: JSON Cache QR: TTL 48h Função: sincronizacao_offline Inclui: preparo_bio Obrigatório: app_version

Objetivo deste fluxo

Permitir que o app sincronize com o ERP os dados necessários para operar offline, sem depender exclusivamente de consulta online no momento do scan. O app baixa os QR Codes disponíveis para o contexto do dispositivo e armazena tudo localmente para uso temporário.

Esta sincronização também deve retornar QR Codes de Preparação Eko´s Bio, identificados por tipo_conteudo=preparo_bio, vinculados a nome_tabela=pedidos e id_tabela=<número do pedido>.

Como funciona no app

  1. O app valida a sessão do dispositivo com X-APP-KEY e X-DEVICE-TOKEN.
  2. Quando estiver online, chama a rota f=sincronizacao_offline.
  3. O app deve enviar sempre a versão instalada no aparelho através do campo app_version.
  4. Opcionalmente, envia last_sync_at para buscar apenas itens novos/alterados.
  5. O ERP retorna os QR Codes ativos, dados offline e o bloco versao_app.
  6. O app grava ou atualiza esses dados no SQLite local.
  7. Esses itens ficam disponíveis no cache offline por até 48 horas.
  8. Se houver atualização obrigatória, o app deve bloquear o uso até que a nova versão seja instalada.

Endpoint

POST https://agroecologia.grupoekos.com.br/router/action.php

Headers obrigatórios

X-APP-KEY: <APP_KEY_FIXA_DO_APP>
X-DEVICE-TOKEN: <DEVICE_TOKEN_DO_APARELHO>

Body

action=apiG10
f=sincronizacao_offline
app_version=1.0.3
last_sync_at=YYYY-MM-DD HH:MM:SS   // opcional
tipos=kit_entrega,coleta_analise_solo,coleta_analise_folha,preparo_bio,pagina_publica   // opcional

Parâmetros

Campo Obrigatório Exemplo Descrição
app_version Sim 1.0.3 Versão instalada no aplicativo do aparelho. Deve ser enviada sempre que o app chamar sincronizacao_offline. O ERP usa essa informação para auditoria e para identificar aparelhos atualizados, desatualizados ou bloqueados por atualização obrigatória.
last_sync_at Não 2026-04-14 00:00:00 Retorna somente itens atualizados a partir desta data/hora.
tipos Não kit_entrega,coleta_analise_solo,coleta_analise_folha,preparo_bio,pagina_publica Filtra a sincronização por tipos de QR Code. Para Preparação Eko´s Bio, usar preparo_bio.
Observação: se last_sync_at não for enviado, o ERP retorna todos os itens elegíveis.

Resposta esperada da API

Sucesso para produtor / produtor_funcionario (HTTP 200)

Para usuários do tipo produtor ou produtor_funcionario, a resposta mantém o padrão antigo com items e pendencias, limitado ao cliente vinculado ao device token.

{
  "success": true,
  "msg": "Sincronização offline realizada com sucesso.",
  "data": {
    "server_time": "2026-04-14 15:10:00",
    "device_id": 999,
    "cliente_id": 123,
    "account_type": "produtor",
    "last_sync_at": "2026-04-14 00:00:00",
    "ttl_qr_horas": 48,
    "versao_app": {
    "versao_instalada": "1.0.3",
    "versao_atual": "1.0.4",
    "atualizado": 0,
    "atualizacao_obrigatoria": 1,
    "observacao": "Atualização obrigatória para correção da sincronização offline."
    },
    "total": 1,
    "items": [
      {
        "qrcode_id": 10,
        "referencia": "KIT PEDIDO 1500",
        "qrcode": "KIT_ABC123",
        "tipo_conteudo": "kit_entrega",
        "nome_tabela": "pedidos",
        "id_tabela": 1500,
        "status": 1,
        "cliente_id": 123,
        "id_g10_participacao": 2,
        "updated_at": "2026-04-14 09:00:00",
        "total_pontos": 4,
        "centro": {
          "latitude": -21.864533055,
          "longitude": -47.499776985
        }
      }
    ],
    "total_pendencias": 0,
    "pendencias": []
  }
}

Sucesso para colaborador (HTTP 200)

Para usuários do tipo colaborador, a resposta deve vir separada em blocos: qrcodes, fazendas e geocercas.

{
  "success": true,
  "msg": "Sincronização offline realizada com sucesso.",
  "data": {
    "server_time": "2026-04-14 15:10:00",
    "device_id": 999,
    "cliente_id": 112,
    "account_type": "colaborador",
    "last_sync_at": "2026-04-14 00:00:00",
    "ttl_qr_horas": 48,

    "versao_app": {
    "versao_instalada": "1.0.3",
    "versao_atual": "1.0.4",
    "atualizado": 0,
    "atualizacao_obrigatoria": 1,
    "observacao": "Atualização obrigatória para correção da sincronização offline."
    },

    "qrcodes": [
      {
        "qrcode_id": 10,
        "referencia": "KIT PEDIDO 1500",
        "qrcode": "KIT_ABC123",
        "tipo_conteudo": "kit_entrega",
        "nome_tabela": "pedidos",
        "id_tabela": 1500,
        "status": 1,
        "cliente_id": 123,
        "id_g10_participacao": 2,
        "updated_at": "2026-04-14 09:00:00",
        "total_pontos": 4,
        "centro": {
          "latitude": -21.864533055,
          "longitude": -47.499776985
        }
      },
      {
        "qrcode_id": 18,
        "referencia": "Página Pública G10 - 02",
        "qrcode": "https://regenerag10.com.br/qrcode/cli_EXEMPLO123",
        "tipo_conteudo": "pagina_publica",
        "nome_tabela": "g10_participacoes",
        "id_tabela": 2,
        "status": 1,
        "cliente_id": 123,
        "id_g10_participacao": 2,
        "updated_at": "2026-04-14 09:30:00",
        "total_pontos": 4,
        "centro": {
          "latitude": -21.864533055,
          "longitude": -47.499776985
        }
      }
    ],

    "fazendas": [
      {
        "cliente_id": 123,
        "razao_social": "FAZENDA MODELO",
        "cidade": "Araras",
        "uf": "SP",
        "segmento": "Citros",
        "idade_pomar": "8",
        "variedade_planta": "Pera Rio",
        "porta_enxerto": "Swingle",
        "qtde_planta": 450,
        "capacidade_tanque": 2000,
        "qtde_tanque_aplic": 2,
        "qtde_planta_tanque": 225,
        "area_irrigada": 3.5,
        "plano_manejo": "Plano de manejo G10",
        "id_g10_participacao": 2,
        "unidade_referencia": "G10 - 02"
      }
    ],

    "geocercas": [
      {
        "id_geocerca": 7,
        "cliente_id": 123,
        "id_g10_participacao": 2,
        "descricao": "Talhão 9",
        "qtde_plantas_area_tratada": 450,
        "total_pontos": 4,
        "centro": {
          "latitude": -21.864533055,
          "longitude": -47.499776985
        },
        "poligonos": [
          {
            "latitude": -21.8645679,
            "longitude": -47.49966836,
            "ordem": 1
          },
          {
            "latitude": -21.86449821,
            "longitude": -47.49988561,
            "ordem": 2
          }
        ]
      }
    ]
  }
}

Bloco qrcodes

O bloco qrcodes contém todos os QR Codes ativos disponíveis para o contexto do usuário. Para colaboradores, pode conter QR Codes de várias fazendas G10.

Campo Descrição
qrcode_id ID interno do QR Code no ERP.
referencia Descrição/referência do QR Code.
qrcode Conteúdo lido pela câmera do app.
tipo_conteudo Tipo operacional do QR Code, como kit_entrega, preparo_bio ou pagina_publica.
cliente_id ID do cliente/fazenda vinculado ao QR Code.
id_g10_participacao ID da participação G10 vinculada ao QR Code.
total_pontos Total de pontos existentes na geocerca vinculada à participação G10.
centro JSON com latitude e longitude aproximadas do centro da geocerca.

Bloco fazendas

O bloco fazendas contém os dados necessários para alimentar a tela já existente de dados da fazenda/geocerca no app.

Campo Descrição
cliente_id ID do cliente/fazenda.
razao_social Razão social ou nome da fazenda.
cidade / uf Cidade e estado da fazenda.
segmento Segmento/cultura principal do cliente.
qtde_planta Quantidade total de plantas cadastradas no cliente.
capacidade_tanque Capacidade do tanque utilizado na aplicação.
qtde_tanque_aplic Quantidade de tanques por aplicação.
qtde_planta_tanque Quantidade de plantas atendidas por tanque.
area_irrigada Área irrigada cadastrada para o cliente.
plano_manejo Plano de manejo cadastrado para o cliente.
id_g10_participacao ID da participação G10 vinculada ao cliente.
unidade_referencia Identificação visual da unidade, exemplo: G10 - 02.

Bloco geocercas

O bloco geocercas contém os dados da área e o polígono que será exibido no mapa do aplicativo.

Bloco versao_app

O bloco versao_app informa ao aplicativo se a versão instalada no aparelho está atualizada em relação à versão ativa cadastrada no ERP.

Campo Descrição
versao_instalada Versão que o app informou no campo app_version.
versao_atual Versão mais recente ativa cadastrada no ERP.
atualizado Indica se o aparelho está atualizado. Usar 1 para atualizado e 0 para desatualizado.
atualizacao_obrigatoria Indica se a atualização é obrigatória. Quando for 1 e o aparelho estiver desatualizado, o app deve bloquear o uso até a instalação da nova versão.
observacao Texto explicativo cadastrado no ERP sobre a versão atual.

Erro (HTTP != 200)

A sincronização offline também valida o campo app_version. Se o app não enviar esse campo ou enviar em formato inválido, a API retorna erro e a sincronização não continua.

Erro: app_version não informado

{
  "success": false,
  "error": "missing_app_version",
  "msg": "app_version não informado.",
  "data": {}
}

Erro: app_version inválido

{
  "success": false,
  "error": "invalid_app_version",
  "msg": "app_version inválido. Use o formato 1.0.0.",
  "data": {}
}

Erro: last_sync_at inválido

{
  "success": false,
  "error": "invalid_last_sync_at",
  "msg": "last_sync_at inválido. Use YYYY-MM-DD ou YYYY-MM-DD HH:MM:SS.",
  "data": {}
}

Como o app deve usar essa sincronização

  • O app deve chamar esta rota sempre que estiver online, principalmente na abertura do app.
  • O app deve enviar sempre o campo app_version com a versão instalada no aparelho.
  • O app deve ler o bloco versao_app retornado pelo ERP.
  • Se versao_app.atualizado = 0 e versao_app.atualizacao_obrigatoria = 1, o app deve bloquear o uso até a atualização.
  • Se versao_app.atualizado = 0 e versao_app.atualizacao_obrigatoria = 0, o app pode apenas exibir um aviso e permitir continuar.
  • Os QR Codes recebidos devem ser gravados/atualizados no SQLite local.
  • Para colaboradores, o app deve gravar também os blocos fazendas e geocercas.
  • O cache local deve ter TTL de 48 horas.
  • Ao tocar em Identificar Cliente, o app deve abrir a câmera e ler qualquer QR Code G10 disponível na fazenda.
  • O app deve procurar o QR Code lido no cache local.
  • Se encontrar, deve definir o contexto ativo usando cliente_id e id_g10_participacao.
  • Depois disso, deve reaproveitar a tela já existente do produtor para exibir dados da fazenda, cultura, quantidade de plantas e geocerca.
  • Para o menu Preparação Eko´s Bio, o app deve aceitar somente QR Codes com tipo_conteudo=preparo_bio.
  • A validação definitiva do evento continua sendo feita pelo ERP quando houver sincronização do evento real.

Controle de versão do app

Como o app não será distribuído pela Play Store neste momento, o controle de versão será feito diretamente pelo ERP através da rota sincronizacao_offline.

Toda vez que o app abrir com internet, ele deve chamar a sincronização offline informando a versão instalada no aparelho através do campo app_version.

Regra de bloqueio

  • Se o aparelho estiver atualizado, o app segue normalmente.
  • Se houver versão nova não obrigatória, o app exibe um aviso e permite continuar.
  • Se houver versão nova obrigatória, o app bloqueia o uso até que a atualização seja instalada.

Mensagem sugerida para atualização obrigatória

Atualização obrigatória disponível.

Versão instalada: 1.0.3
Versão disponível: 1.0.4

Atualização obrigatória para correção da sincronização offline.

Atualize o aplicativo para continuar usando.

Auditoria no ERP

A cada sincronização, o ERP registra a versão informada pelo aparelho. Com isso será possível consultar no ERP quais aparelhos estão atualizados, quais estão desatualizados e quais estão pendentes de uma atualização obrigatória.

Pendências de atualização: dados do cliente e geocerca (Atualizado 24/04/26).

Além dos QR Codes offline, a rota f=sincronizacao_offline também pode retornar pendências de atualização para o aplicativo. Essas pendências avisam o app que houve alteração no ERP em dados que precisam ser atualizados no banco offline local, como dados básicos do cliente, dados de plantio ou geocerca.

Quando o ERP altera informações relevantes do cliente ou da geocerca, ele grava uma pendência na tabela g10_app_sync_pendencias. Enquanto essa pendência estiver com sincronizado_em = NULL, ela será enviada ao app na próxima sincronização.

Quando uma pendência é gerada?

  • Quando dados básicos do cliente são alterados.
  • Quando dados de plantio do cliente são alterados.
  • Quando o cliente é vinculado ao projeto G10.
  • Quando uma nova geocerca é criada.
  • Quando o desenho/polígono da geocerca é salvo ou alterado.

Tipo de pendência

Para atualização da tela Seus Dados e da geocerca, o ERP retorna:

tipo_conteudo=atualizar_dados_geocerca

Ao encontrar esse tipo de pendência, o app deve buscar novamente os dados completos do cliente e da geocerca usando o endpoint f=meus_dados_geocerca.

Exemplo no retorno da sincronização offline

{
        "success": true,
        "msg": "Sincronização offline realizada com sucesso.",
        "data": {
            "server_time": "2026-04-24 15:30:00",
            "device_id": 8,
            "cliente_id": 123,
            "account_type": "produtor",
            "last_sync_at": "",
            "ttl_qr_horas": 48,
            "total": 3,
            "items": [],
            "total_pendencias": 1,
            "pendencias": [
            {
                "id": 55,
                "id_cliente": 123,
                "id_g10": 10,
                "tipo_conteudo": "atualizar_dados_geocerca",
                "nome_tabela": "g10_geocerca",
                "id_tabela": 7,
                "status": 1,
                "criado_em": "2026-04-24 15:10:00",
                "updated_at": "2026-04-24 15:20:00"
            }
            ]
        }
        }

Fluxo esperado no app

  1. O app chama f=sincronizacao_offline.
  2. O app verifica se existe item no array pendencias.
  3. Se houver pendência com tipo_conteudo=atualizar_dados_geocerca, o app chama f=meus_dados_geocerca.
  4. O app salva no banco offline local os dados do cliente, G10, geocercas e polígonos.
  5. Após salvar tudo localmente com sucesso, o app chama f=confirmar_pendencia_sync.
  6. O ERP marca a pendência como sincronizada preenchendo sincronizado_em.

Endpoint para buscar dados atualizados

POST https://agroecologia.grupoekos.com.br/router/action.php

        Headers:
        X-APP-KEY: <APP_KEY_FIXA_DO_APP>
        X-DEVICE-TOKEN: <DEVICE_TOKEN_DO_APARELHO>

        Body:
        action=apiG10
        f=meus_dados_geocerca

Esse endpoint retorna os dados básicos do cliente, a participação G10 e as geocercas com seus respectivos polígonos. O app deve usar esse retorno para atualizar a tela Seus Dados.

Endpoint para confirmar pendência sincronizada

POST https://agroecologia.grupoekos.com.br/router/action.php

        Headers:
        X-APP-KEY: <APP_KEY_FIXA_DO_APP>
        X-DEVICE-TOKEN: <DEVICE_TOKEN_DO_APARELHO>

        Body:
        action=apiG10
        f=confirmar_pendencia_sync
        pendencia_id=<ID_DA_PENDENCIA>

O app só deve chamar confirmar_pendencia_sync depois que conseguir salvar os dados atualizados no banco offline local.

Resposta esperada da confirmação

{
        "success": true,
        "msg": "Pendência confirmada com sucesso.",
        "data": {
            "pendencia_id": 55,
            "tipo_conteudo": "atualizar_dados_geocerca",
            "id_cliente": 123,
            "id_g10": 10,
            "sincronizado": true,
            "sincronizado_em": "2026-04-24 15:50:00"
        }
        }
Regra: a pendência só deve ser confirmada depois que o app atualizar o banco offline com sucesso.

Atualizações

Atualização 17/07/2026 — Controle de versão do app

A rota sincronizacao_offline passa a receber o campo obrigatório app_version e a retornar o bloco versao_app.

Esse controle será usado para auditoria dos aparelhos e para bloquear o uso do app quando houver uma atualização obrigatória cadastrada no ERP.

  • Adicionado parâmetro obrigatório app_version.
  • Adicionado retorno versao_app.
  • ERP passa a registrar a versão instalada por aparelho.
  • ERP poderá listar aparelhos atualizados, desatualizados e pendentes de atualização obrigatória.
  • App deverá bloquear o uso quando houver atualização obrigatória e a versão instalada estiver desatualizada.
{
  "versao_app": {
    "versao_instalada": "1.0.3",
    "versao_atual": "1.0.4",
    "atualizado": 0,
    "atualizacao_obrigatoria": 1,
    "observacao": "Atualização obrigatória para correção da sincronização offline."
  }
}

Atualização — Colaboradores Offline

Para usuários do tipo colaborador, a sincronização offline passa a retornar dados separados em blocos, permitindo que o app identifique qualquer fazenda G10 por meio da leitura de um QR Code já sincronizado.

  • Adicionado retorno qrcodes para colaboradores.
  • Adicionado retorno fazendas para colaboradores.
  • Adicionado retorno geocercas para colaboradores.
  • Removida a necessidade de seleção manual de fazenda.
  • Definido uso do botão Identificar Cliente no app.
  • Definido reaproveitamento da tela já existente do produtor.

Atualização — Bloco fazendas

O bloco fazendas passa a enviar dados adicionais necessários para preencher a tela da fazenda no aplicativo.

  • segmento
  • qtde_planta
  • capacidade_tanque
  • qtde_tanque_aplic
  • qtde_planta_tanque
  • area_irrigada
  • plano_manejo

Atualização — Bloco qrcodes

O bloco qrcodes passa a enviar informações resumidas da geocerca, permitindo que o app tenha dados mínimos para posicionamento e exibição após a leitura do QR Code.

  • total_pontos: quantidade de pontos da geocerca vinculada ao G10.
  • centro: JSON contendo latitude e longitude aproximadas do centro da geocerca.
{
  "total_pontos": 4,
  "centro": {
    "latitude": -21.864533055,
    "longitude": -47.499776985
  }
}

Observação sobre fotos e arquivos pesados

Fotos, metadados de fotos, imagens em base64, PDFs, trajetos completos e históricos pesados não fazem parte desta sincronização offline. Esses dados devem permanecer em endpoints próprios, sob demanda, quando houver internet.

Exemplo de chamada (cURL)

curl -X POST "https://agroecologia.grupoekos.com.br/router/action.php" \
  -H "Content-Type: application/x-www-form-urlencoded; charset=UTF-8" \
  -H "X-APP-KEY: SUA_APP_KEY" \
  -H "X-DEVICE-TOKEN: SEU_DEVICE_TOKEN" \
  --data "action=apiG10&f=sincronizacao_offline&app_version=1.0.3&last_sync_at=2026-04-14 00:00:00&tipos=kit_entrega,coleta_analise_solo,coleta_analise_folha,preparo_bio"