Simplify scan API: remove /verify, add accepted/refused state with reason and details
- Remove POST /api/scan/verify (redundant with /api/scan) - POST /api/scan now returns state: "accepted" or "refused" with reason - Refused reasons: already_scanned, invalid, expired, exit_definitive, wrong_event - Accepted response includes details object (for future additional data) - Template: render extra section (refusal reasons table in red) - Only 2 POST routes remain: /api/auth/login + /api/scan (all others are GET) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -232,7 +232,7 @@ class ApiDocController extends AbstractController
|
||||
'method' => 'POST',
|
||||
'path' => '/api/scan',
|
||||
'summary' => 'Scanner un billet',
|
||||
'description' => 'Decode le QR code, verifie la reference et l\'etat du billet, marque le billet comme scanne. Gere la sortie definitive si activee.',
|
||||
'description' => 'Decode le QR code, verifie la reference, l\'etat du billet, et le marque comme scanne si valide. Retourne "accepted" ou "refused" avec la raison du refus. Gere la sortie definitive si activee.',
|
||||
'headers' => $this->authHeaders(),
|
||||
'params' => [],
|
||||
'request' => [
|
||||
@@ -240,33 +240,22 @@ class ApiDocController extends AbstractController
|
||||
],
|
||||
'response' => [
|
||||
'success' => ['type' => 'bool', 'example' => true],
|
||||
'data' => ['type' => 'object', 'example' => '{"reference": "ETICKET-XXXX-XXXX", "state": "valid", "billetName": "Entree", "buyerFirstName": "Jean", "buyerLastName": "Dupont", "isInvitation": false, "firstScannedAt": "2026-03-23T14:30:00", "hasDefinedExit": true}'],
|
||||
'data' => ['type' => 'object', 'example' => '{"state": "accepted", "reason": null, "reference": "ETICKET-XXXX-XXXX", "billetName": "Entree", "buyerFirstName": "Jean", "buyerLastName": "Dupont", "isInvitation": false, "firstScannedAt": "2026-03-23T14:30:00", "hasDefinedExit": true, "details": {"...": "donnees supplementaires (si accepted)"}}'],
|
||||
],
|
||||
'statuses' => [
|
||||
200 => 'Billet scanne avec succes',
|
||||
400 => 'Reference invalide ou billet deja scanne',
|
||||
200 => 'Scan traite (state: accepted ou refused)',
|
||||
401 => 'Non authentifie',
|
||||
404 => 'Billet introuvable',
|
||||
],
|
||||
],
|
||||
[
|
||||
'method' => 'POST',
|
||||
'path' => '/api/scan/verify',
|
||||
'summary' => 'Verifier un billet (lecture seule)',
|
||||
'description' => 'Verifie l\'etat d\'un billet sans le marquer comme scanne.',
|
||||
'headers' => $this->authHeaders(),
|
||||
'params' => [],
|
||||
'request' => [
|
||||
'reference' => ['type' => 'string', 'required' => true, 'example' => 'ETICKET-XXXX-XXXX-XXXX'],
|
||||
],
|
||||
'response' => [
|
||||
'success' => ['type' => 'bool', 'example' => true],
|
||||
'data' => ['type' => 'object', 'example' => '{"reference": "ETICKET-XXXX-XXXX", "state": "valid", "billetName": "Entree", "buyerFirstName": "Jean", "buyerLastName": "Dupont"}'],
|
||||
],
|
||||
'statuses' => [
|
||||
200 => 'Billet valide',
|
||||
401 => 'Non authentifie',
|
||||
404 => 'Billet introuvable',
|
||||
'extra' => [
|
||||
'title' => 'Raisons de refus possibles',
|
||||
'items' => [
|
||||
'already_scanned' => 'Billet deja scanne',
|
||||
'invalid' => 'Billet invalide (annule ou rembourse)',
|
||||
'expired' => 'Billet expire',
|
||||
'exit_definitive' => 'Sortie definitive deja effectuee',
|
||||
'wrong_event' => 'Billet n\'appartient pas a cet evenement',
|
||||
],
|
||||
],
|
||||
],
|
||||
[
|
||||
|
||||
@@ -230,6 +230,22 @@
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if endpoint.extra is defined %}
|
||||
<div class="mb-4">
|
||||
<p class="text-[10px] font-black uppercase tracking-widest text-gray-400 mb-2">{{ endpoint.extra.title }}</p>
|
||||
<div class="border-2 border-red-200 bg-red-50 p-4">
|
||||
<table class="w-full text-xs">
|
||||
{% for code, desc in endpoint.extra.items %}
|
||||
<tr class="{{ not loop.last ? 'border-b border-red-200' : '' }}">
|
||||
<td class="py-1.5 font-mono font-bold text-red-700 pr-4">{{ code }}</td>
|
||||
<td class="py-1.5 font-bold text-red-600">{{ desc }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if endpoint.statuses|length > 0 %}
|
||||
<div>
|
||||
<p class="text-[10px] font-black uppercase tracking-widest text-gray-400 mb-2">Codes de reponse</p>
|
||||
|
||||
Reference in New Issue
Block a user