intermediate
juicer
recompensa
claim

Claim e Drop de Recompensa

Fluxo completo de um Juicer reivindicando recompensa, pegando o veiculo, carregando e devolvendo em zona - com validacao de foto e GPS nas duas pontas

Levy Fleets TeamMay 18, 20268 min read

Claim e Drop de Recompensa

Este e o ciclo completo de uma recompensa do ponto de vista do Juicer - incluindo o que a plataforma valida em cada passo.

As Cinco Fases

open -> claimed -> picked_up -> charging -> ready_to_drop -> completed
                                                                v
                                                             payout

Uma recompensa pode tambem cair em expired (TTL), canceled (operador) ou disputed (fraude + revisao).

Fase 1: Open

Motor roda a cada 5 minutos. Para cada subconta habilitada, percorre cada veiculo candidato e decide criar/atualizar recompensa. Linha contem:

  • Pagamento em centavos
  • Multiplicador surge
  • Timestamp de expiracao (TTL)
  • Localizacao atual (GIST indexado)
  • Status open
  • Predicao de queda no pico (Fase 4)

Recompensas abertas aparecem no mapa.

Fase 2: Claim

Juicer toca Claim em um pin.

Plataforma chama claim_bounty(p_bounty_id, p_juicer_id, p_claim_ttl_seconds). Funcao trava com FOR UPDATE recompensa e Juicer, valida todas:

  • Juicer status = 'active'
  • Juicer kyc_status = 'verified'
  • Abaixo de max_concurrent_claims
  • Recompensa open, nao expirada
  • Telemetria fresca (30 min)
  • Veiculo nao em corrida ativa
  • Pacote nao em maintenance/recalled
  • Juicer dentro de claim_radius_m
  • Subconta combina

Falha em qualquer -> rollback. Dois Juicers nao podem ganhar.

Sucesso:

  • bounties.status = 'claimed', claimed_by, claimed_at, expires_at (60 min TTL)
  • Linha juicer_sessions em claimed
  • Comando IoT para desabilitar acelerador (best-effort)

Veiculo some dos outros mapas.

Fase 3: Pickup (Foto + GPS)

Juicer chega, foto com ID visivel, toca Peguei.

Plataforma valida:

VerificacaoLimiteFalha
Drift GPS<=50 m limpo
50-200 m aviso (+5)
>200 m bloqueia
Rejeita, claim aberto ate TTL
TimestampDentro de 5 min do claimAviso, +3
Hash de fotoNao pode bater com anteriorBloqueia +20
ID OCRNumero legivelVerificacao leve hoje

Passou: estado picked_up. URL e hash do foto guardados.

Por Que Validar Duas Vezes

Previne tres falhas: (1) claim sem estar perto (radius spoof), (2) foto de estoque (hash), (3) dias entre claim e pickup (timestamp).

Fase 4: Transporte e Carga

Juicer transporta para casa ou estacao. Pluga em tomada padrao.

App pede periodicamente: Ainda carregando?. Padrao 30 min. Endpoint POST /api/juicer/bounties/[id]/charge-checkin com current_soc.

  • Dois check-ins perdidos -> claim expira, demerito.
  • current_soc < anterior -> marcado, revisao manual.
  • >=95% -> estado ready_to_drop, botao Drop ativa.

Sessao rastreia pickup_soc, ultimo SoC, duracao em segundos.

Fase 5: Drop (Foto + GPS)

Juicer dirige para zona, estaciona, foto de drop, Concluir.

Plataforma valida:

VerificacaoO QueFalha
Poligono de zonaGPS em zona ativa (ST_Contains)Bloqueia, claim aberto
Plausibilidade de cargaTempo vs SoC delta >=0,6 min/%Bloqueia + revisao
Hash de dropNao pode baterAviso +20
Pacote nao em maintenanceNao marcado durante sessaoBloqueia + disputa

Zona usa RPC PostGIS sobre zonas ativas Juicer-elegiveis. Operadores marcam zonas como Juicer-elegiveis no dashboard.

Tudo passa:

  • bounties.status = 'completed'
  • Session completed, drop_soc, drop_gps, drop_photo_url
  • Linha juicer_payouts em queued (ou on_hold se fraude)
  • Desbloqueio acelerador

Fase 6: Pagamento

Drenados de queued para Stripe Connect a cada 15 min via cron juicer-payouts. Chaves idempotentes para retries.

Detalhes em Pagamentos.

O Que o Operador Ve

Pagina Juicers mostra sessoes ao vivo. Pagamentos mostra livro:

ColunaSignificado
Estadoqueued / paid / on_hold / reversed / canceled
ValorLiquido em centavos
TaxaParte Levy
Transfer ID StripeQuando pago
Session IDTrilha completa

Operadores podem segurar, liberar, reverter, cancelar.

Como um Claim Expirado Parece

  • TTL (60 min) -> bounties.status volta para open, sessao expired, demerito 3 pontos.
  • Dois check-ins perdidos -> igual, mais nota "nao carregou".
  • Contador lifetime_no_shows aumenta.

Problemas Comuns

  • "GPS muito longe" - >200 m. Aproxime ou aguarde telemetria fresca.
  • "Drop fora da zona" - reubique.
  • "Carga implausivel" - <0,6 min/%.
  • "Recompensa ja reivindicada" - outro mais rapido.
  • "Veiculo em corrida" - aluguel iniciou entre claim e pickup.