Pular para o conteúdo

Ajuda — tiro de precisão

API e integração do tiro de precisão

← Todas as guias

A API pública do tiro de precisão permite que o sistema do seu clube crie provas, inscreva atletas e leia o resultado sem ninguém redigitar nada.

A chave

É a mesma chave dos outros módulos. O dono do clube cria em Entidade → Chaves de API; a secret aparece uma única vez, na criação. Guarde-a com o cuidado de uma senha.

Authorization: Bearer <access_key>.<secret>
  • Escopo "leitura" permite só GET; "leitura e escrita" libera o resto.
  • Tudo é escopado ao seu clube. Não existe requisição que alcance dado de outra entidade.
  • Se o módulo não estiver habilitado para o clube, a resposta é 404 — a chave é válida, o recurso é que não existe para você.

Os três eixos da prova

Entender isto antes de integrar economiza a maior parte do retrabalho:

  • Modalidade — o percurso de fogo. No cadastro do clube é reutilizável; dentro da prova é uma CÓPIA. Editar o cadastro depois não muda prova montada — é o que garante que resultado de prova encerrada nunca mude. É a ela que a inscrição aponta e por ela que o ranking agrupa.
  • Série — o eixo de tempo: a rodada.
  • Turno — o eixo de espaço: quem atira junto, com limite de vagas.
Uma inscrição por modalidade. O mesmo atleta pode ter duas inscrições na mesma prova. Repetir a mesma modalidade é que devolve conflito.

Um dia de prova, em quatro chamadas

BASE=https://seu-dominio/api/v1
AUTH="Authorization: Bearer $ACCESS.$SECRET"

# 1. criar a prova já com as modalidades do cadastro do clube
curl -s -X POST $BASE/precisao/provas -H "$AUTH" \
  -H 'Content-Type: application/json' \
  -d '{"nome":"1ª Etapa 2026","data_prova":"2026-03-14",
       "modalidades":["<uuid-da-modalidade>"],
       "external_id":"etapa-1-2026"}'

# 2. inscrever um atleta numa modalidade e num turno
curl -s -X POST $BASE/precisao/provas/$prova/inscricoes -H "$AUTH" \
  -H 'Content-Type: application/json' \
  -d '{"prova_modalidade_uuid":"<uuid>","turno_uuid":"<uuid>",
       "nome":"Fulano","email":"[email protected]",
       "sexo":"M","data_nascimento":"1988-04-02",
       "external_id":"insc-4471"}'

# 3. abrir a prova e publicar os resultados
curl -s -X PATCH $BASE/precisao/provas/$prova -H "$AUTH" \
  -H 'Content-Type: application/json' \
  -d '{"status":"aberta","resultados_publicos":true}'

# 4. ler o ranking (agrupado por modalidade, com o desempate aberto)
curl -s $BASE/precisao/provas/$prova/resultados -H "$AUTH"

external_id: o id do SEU sistema

Todo recurso de prova e de inscrição aceita um external_id. Grave nele o id do registro do seu lado e você reencontra tudo sem precisar guardar os nossos uuid:

curl -s "$BASE/precisao/provas?external_id=etapa-1-2026" -H "$AUTH"

Ele é único no escopo (clube para provas, prova para inscrições), o que o torna também uma chave de idempotência: reenviar o mesmo POST devolve conflito em vez de criar um duplicado silencioso. Enviar null desvincula; omitir o campo não mexe no que está gravado.

Score não se escreve por aqui

A fita nasce assinada no campo — HMAC do juiz, encadeado com o PIN do atleta quando a prova exige. Um POST de score criaria resultado sem essa cadeia, que é justamente o que o módulo existe para impedir. A API lê o resultado; quem o produz é o juiz na tela de lançamento.

Pelo mesmo motivo, a API nunca emite nem devolve o PIN de um atleta. Existe só o caminho de apagá-lo, para que o atleta crie outro — o PIN é segredo dele, e um integrador que o conhecesse esvaziaria o sentido da assinatura do atleta.

O que trava, e por quê

Estas regras valem igual na tela e na API. Todas devolvem 409:

Tentativa Por quê
Mudar desempate ou exigência de PIN com score lançado As duas fazem parte do que foi assinado; mudá-las reordenaria o ranking sem ninguém atirar.
Mudar o percurso da modalidade com score lançado A fita assinada aponta para aqueles alvos.
Renumerar série com score lançado O desempate por série final lê as séries pela ordem.
Trocar a modalidade de uma inscrição com score Moveria uma fita assinada para outro percurso de fogo.
Excluir inscrição com score Sobraria fita assinada sem dono. Use status "cancelada".
Publicar prova em rascunho A estrutura ainda vai mudar; o link mostraria algo que não se confirma.
Alterar estrutura de prova encerrada O resultado já circulou como oficial.
Passar do limite de vagas do turno É o mesmo limite que a tela respeita.

Excluir uma prova exige, além disso, o nome exato dela em ?confirmacao= — a mesma zona de perigo da interface.

Paginação, limites e erros

  • Listagens aceitam ?page (a partir de 1) e ?per_page (padrão 25, máximo 100; nas inscrições, padrão 50 e máximo 200) e devolvem page, per_page e total.
  • Rate limit por chave, com os headers X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset. Excedido devolve 429 com Retry-After — respeite-o em vez de repetir em loop.
  • Erro é sempre JSON no mesmo formato: {"error": {"code": "not_found", "message": "Prova não encontrada."}}. A mensagem é escrita para ser lida por quem está integrando, não só registrada.

Conferir o que a integração fez

Cada prova expõe a própria trilha de auditoria, e as ações feitas por chave aparecem nela junto com as feitas na tela. É como se reconcilia o que o robô fez com o que a secretaria fez:

curl -s "$BASE/precisao/provas/$prova/auditoria?acao=precisao.prova_update" -H "$AUTH"

Referência interativa

Explore e teste os endpoints abaixo (Swagger UI). O JSON da especificação OpenAPI está em openapi.json.

Este guia cobre as provas de tiro de precisão (fogo circular e bullseye), nos moldes dos regulamentos SCTSL e CBTT.