11) Fotos dos Talhões

Este endpoint permite que o aplicativo envie fotos da plantação nos talhões vinculados ao G10. Antes de liberar a câmera, o app deve ler o QR Code da placa instalada na geocerca. Esse QR Code serve como validação complementar para confirmar que o usuário está no local correto.

Auth: X-APP-KEY + X-DEVICE-TOKEN Formato: multipart/form-data Endpoint: registrar_fotos Obrigatório: client_event_id Obrigatório: tipo_foto Status inicial: pendente_revisao

Observação: a identificação principal do cliente/aparelho continua sendo feita pelo X-DEVICE-TOKEN. O QR Code da placa é apenas uma validação adicional do local/G10.

Fluxo resumido

  1. ERP gera um QR Code do tipo pagina_publica vinculado à participação G10.
  2. Esse QR Code é impresso e colocado em uma placa dentro da geocerca/talhão.
  3. App lê o QR Code da placa antes de liberar a câmera.
  4. App gera um client_event_id único para cada foto.
  5. App salva a foto primeiro no aparelho/fila offline.
  6. App envia uma foto por vez para a API, junto com data, hora, latitude, longitude e QR Code lido.
  7. API valida X-APP-KEY, X-DEVICE-TOKEN e o QR Code da placa.
  8. API grava a foto em g10_fotos com status pendente_revisao.
  9. Se a API responder success=true, o app pode excluir a imagem local.
  10. No ERP, as fotos aparecem na aba Eventos > Galeria para aprovação ou descarte.

Endpoint: Registrar fotos dos talhões

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

Headers

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

Formato

multipart/form-data

Body

action=apiG10
f=registrar_fotos
client_event_id=<UUID_OU_ID_UNICO_DO_APP>
qrcode=<CONTEUDO_LIDO_DO_QRCODE_DA_PLACA>
data=YYYY-MM-DD
hora=HH:MM:SS
latitude=<LATITUDE>
longitude=<LONGITUDE>
foto=<ARQUIVO_DA_IMAGEM>
observacao=<OPCIONAL>
tipo_foto=<folha|fruto|chao|pomar>

Exemplo de QR Code lido

https://regenerag10.com.br/qrcode/cli_bce3ebfe0cb2aeaca4aea4ee49

Exemplo de envio via cURL

curl -X POST "https://agroecologia.grupoekos.com.br/router/action.php" \
    -H "X-APP-KEY: APP_KEY_FIXA_DO_APP" \
    -H "X-DEVICE-TOKEN: DEVICE_TOKEN_SALVO_NO_APARELHO" \
    -F "action=apiG10" \
    -F "f=registrar_fotos" \
    -F "client_event_id=550e8400-e29b-41d4-a716-446655440000" \
    -F "qrcode=https://regenerag10.com.br/qrcode/cli_bce3ebfe0cb2aeaca4aea4ee49" \
    -F "data=2026-05-05" \
    -F "hora=10:35:20" \
    -F "latitude=-21.86454000" \
    -F "longitude=-47.49973000" \
    -F "observacao=Foto da área central do talhão" \
    -F "tipo_foto=pomar" \
    -F "foto=@/caminho/foto_talhao.jpg"

Campos enviados pelo app

  • action: sempre apiG10.
  • f: sempre registrar_fotos.
  • client_event_id: ID único gerado pelo app para a foto.
  • qrcode: conteúdo completo lido do QR Code da placa.
  • data: data da foto no formato YYYY-MM-DD.
  • hora: hora da foto no formato HH:MM:SS.
  • latitude: latitude no momento da foto.
  • longitude: longitude no momento da foto.
  • foto: arquivo da imagem. Formatos aceitos: JPG, JPEG ou PNG.
  • observacao: campo opcional.
  • tipo_foto: tipo da foto enviada. Valores permitidos: folha, fruto, chao ou pomar.
Cada foto deve ter seu próprio client_event_id.

Tipos de foto permitidos

O campo tipo_foto é obrigatório e deve ser enviado pelo app para permitir filtros corretos na Galeria, na Página Pública e nas comparações de evolução.

O valor deve ser enviado sempre em minúsculo e sem acento.

Valor enviado na API Exibição sugerida no app/site Uso esperado
folha Folha Fotos aproximadas de folhas da planta.
fruto Fruto Fotos aproximadas de frutos.
chao Chão Fotos do solo, cobertura, matéria orgânica ou condição do chão.
pomar Pomar Fotos abertas da área, linhas de plantio ou visão geral do talhão.
Regra: fotos de tipos diferentes não devem ser comparadas entre si na evolução.

Validação do QR Code da placa

O QR Code da placa é usado para confirmar que o usuário está no local correto antes de tirar a foto. A API deve procurar o conteúdo lido na tabela qr_codes.

Regra esperada no ERP

qr_codes.tipo_conteudo = pagina_publica
qr_codes.status = 1
qr_codes.nome_tabela = g10_participacoes
qr_codes.id_tabela = id da participação G10
qr_codes.conteudo = conteúdo lido pelo app

A partir de qr_codes.id_tabela, a API identifica a participação G10 e o cliente. Depois compara esse cliente com o cliente identificado pelo X-DEVICE-TOKEN.

O QR Code não substitui o DEVICE_TOKEN. Ele é uma validação adicional do local.

Modo de operação do app (offline-first)

  • O app deve salvar a foto localmente antes de tentar enviar para a API.
  • Cada foto deve entrar na fila/outbox com status pendente.
  • O app deve gerar e salvar o client_event_id junto da foto.
  • Se o envio falhar, a foto deve permanecer salva no aparelho para reenvio.
  • Em cada reenvio da mesma foto, o app deve reutilizar o mesmo client_event_id.
  • Se a API responder success=true, o app pode excluir a imagem local.
  • Se a API responder already_registered=true, o app também pode excluir a imagem local.
  • Se a API responder success=false, o app deve manter a foto na fila.

Respostas esperadas da API

Sucesso HTTP 200

{
  "success": true,
  "msg": "Foto registrada com sucesso.",
  "data": {
    "id_foto": 123,
    "client_event_id": "550e8400-e29b-41d4-a716-446655440000",
    "cliente_id": 664,
    "id_g10": 2,
    "device_id": 8,
    "status": "pendente_revisao",
    "tipo_foto": "pomar"
  }
}

Reenvio idempotente HTTP 200

{
  "success": true,
  "msg": "Foto já registrada.",
  "data": {
    "id_foto": 123,
    "client_event_id": "550e8400-e29b-41d4-a716-446655440000",
    "already_registered": true
  }
}

Quando receber already_registered=true, o app deve considerar a foto como sincronizada e pode remover a imagem local da fila.

Erro HTTP diferente de 200

{
  "success": false,
  "error": "invalid_qrcode",
  "msg": "QR Code inválido ou não encontrado.",
  "data": {}
}

Em caso de erro, o app deve manter a foto salva localmente e tentar reenviar depois, exceto quando o erro for tratado pelo aplicativo como impeditivo.

Status no ERP

Ao chegar no ERP, toda foto deve entrar inicialmente como pendente_revisao. Depois, no ERP, o usuário poderá acessar a aba Eventos > Galeria e alterar o status.

  • pendente_revisao: foto recebida e aguardando análise.
  • aprovada: foto selecionada/aprovada pelo ERP.
  • descartada: foto rejeitada ou excluída da seleção.

Somente em outro endpoint futuro as fotos aprovadas serão disponibilizadas novamente para o app.

Resumo para os devs do app

  • Ler o QR Code da placa antes de liberar a câmera.
  • Salvar a foto primeiro localmente.
  • Gerar um client_event_id único por foto.
  • Enviar uma foto por requisição.
  • Enviar sempre X-APP-KEY e X-DEVICE-TOKEN.
  • Enviar o conteúdo completo do QR Code no campo qrcode.
  • Enviar data, hora, latitude, longitude, imagem e tipo_foto.
  • Enviar tipo_foto com um dos valores: folha, fruto, chao ou pomar.
  • Excluir a imagem local somente se a API retornar success=true ou already_registered=true.

Atualizações

Atualização — Tipo da foto — 15/07/2026

O endpoint registrar_fotos passa a exigir o envio do campo tipo_foto no corpo da requisição.

Esse campo será usado para permitir filtros corretos na Galeria, na Página Pública e nas comparações de evolução.

  • Adicionado parâmetro obrigatório tipo_foto.
  • Valores permitidos: folha, fruto, chao, pomar.
  • O valor deve ser enviado em minúsculo e sem acento.
  • Fotos de tipos diferentes não devem ser comparadas entre si.
  • Fotos antigas sem tipo_foto podem ser tratadas como sem classificação.
tipo_foto=<folha|fruto|chao|pomar>