BlockLucky Documentation officielle GitHub

Référence de l'API

Cette page liste toutes les routes HTTP du backend. Le tableau est généré à la construction de la documentation en lisant backend/src/app.ts et chaque fichier *.routes.ts : méthode, chemin complet, accès requis, middlewares de contrôle et résumé OpenAPI. Les règles métier, les corps de requête et les erreurs de chaque route sont détaillés dans les pages Modules métier.

Swagger UI

Le serveur publie une interface Swagger sur /api/docs, par exemple http://localhost:2053/api/docs en local. La spécification OpenAPI 3.0 est construite au démarrage par swagger-jsdoc à partir des blocs @openapi placés au-dessus de chaque route (backend/src/config/swagger.config.ts). Elle lit les fichiers src/api/**/*.routes.ts en développement et dist/src/api/**/*.routes.js après compilation.

Élément Valeur
Titre BlockLucky EtherBay API, version 1.0.0
Serveur déclaré http://localhost:<PORT> uniquement
Sécurité schéma bearerAuth (HTTP, bearer, format JWT) appliqué par défaut à toutes les opérations
Chemins documentés sous le préfixe /api/... non versionné

Les blocs OpenAPI ne contiennent qu'une étiquette et un résumé : ni paramètres, ni corps, ni réponses. Swagger UI sert donc d'index cliquable et de console pour envoyer une requête avec un jeton (bouton Authorize), pas de contrat d'interface. La route /api/docs est servie dans tous les environnements, production comprise, et passe par le rate limiting global.

Préfixes

Préfixe Usage
/api/v1/... préfixe recommandé pour tout nouveau client
/api/... même routeur, monté une seconde fois pour compatibilité ; c'est celui qu'utilisent aujourd'hui le web (NEXT_PUBLIC_API_URL=http://localhost:2053/api dans la stack Docker) et les blocs OpenAPI
racine sondes /health*, /api/config et /metrics, hors routeur versionné

Les deux préfixes partagent les mêmes compteurs de rate limiting et les mêmes clés d'idempotence par utilisateur, mais pas le même chemin : une clé d'idempotence utilisée sur /api/lottery/buy n'est pas reconnue sur /api/v1/lottery/buy.

Authentification

Les routes protégées attendent un jeton de session dans l'en-tête Authorization :

HTTP
GET /api/v1/user/profile HTTP/1.1
Host: localhost:2053
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOiIwMTlhN2MzZS...

Le jeton s'obtient par POST /auth/login puis POST /auth/2fa/verify (voir Authentification). Il n'y a ni cookie de session, ni jeton de rafraîchissement : à l'expiration (12 heures par défaut), le client doit se reconnecter. Le préfixe Bearer est sensible à la casse.

Colonne « Accès » du tableau Signification
public aucun jeton requis ; certaines routes l'exploitent s'il est fourni (optionalAuthenticate)
connecté authenticate : jeton valide et non révoqué
rôle ... authenticate puis requireRoles(...) : rôle vérifié dans le jeton et relu en base

Idempotence

Cinq routes acceptent l'en-tête Idempotency-Key : POST /lottery/buy, POST /lottery/gift, POST /lottery/claim-prize, POST /marketplace/claim et POST /marketplace/scratch. Le middleware backend/src/middlewares/idempotency.middleware.ts protège contre le double clic et les nouvelles tentatives réseau d'une opération qui dépense des ethers ou des points.

HTTP
POST /api/v1/lottery/buy HTTP/1.1
Authorization: Bearer eyJhbGciOi...
Content-Type: application/json
Idempotency-Key: 6b0f3c2e-9d41-4a7e-b5a8-1c2d3e4f5a6b

{"quantity":1}
Règle Détail
Format 8 à 128 caractères [A-Za-z0-9_-], sinon 400 En-tête Idempotency-Key invalide
Portée clé Redis idempotency:<userId>:<méthode>:<chemin>:<clé> : propre à l'utilisateur, à la méthode et au chemin exact
Première requête verrou __pending__ posé pour 60 secondes, puis la réponse est mémorisée 24 heures si son statut est inférieur à 500
Requête identique en cours 409 Une requête identique est déjà en cours de traitement avec Retry-After: 1
Requête rejouée réponse d'origine, même statut et même corps, avec l'en-tête Idempotent-Replayed: true
Réponse 5xx la clé est effacée : la requête peut être retentée avec la même clé
Sans en-tête aucun contrôle

Le corps de la requête ne fait pas partie de la clé : la même clé avec un autre corps rejoue la première réponse. Une erreur 400 ou 409 est mémorisée comme un succès ; après une erreur de validation, il faut une nouvelle clé. Sans Redis, les clés sont gardées dans la mémoire du process et ne protègent plus contre un rejeu reçu par une autre instance.

Limites de débit

Limiteur Portée Limite
globalRateLimiter toutes les routes après la maintenance, sauf sondes, /api/config et /metrics 300 requêtes par 15 minutes et par IP
authRateLimiter /auth/login, /signup, /signin, /password/forgot, /password/reset, /password/change, /email/change, /email/confirm, /oauth/google, /2fa/verify, /2fa/disable 30 requêtes par 10 minutes et par IP pour l'ensemble de ces routes, en plus de la limite globale
identityUploadRateLimiter POST /user/identity 10 requêtes par heure et par IP, en plus de la limite globale
supportRateLimiter POST /user/support 5 messages par heure et par compte (par IP à défaut), en plus de la limite globale

Les réponses portent les en-têtes RateLimit et RateLimit-Policy (format draft-7 de l'IETF), exposés aux navigateurs par CORS. Au-delà de la limite, la réponse est un 429 au format habituel, par exemple { "success": false, "message": "Trop de requêtes depuis cette adresse IP, veuillez réessayer plus tard." }. Les compteurs sont dans Redis (ratelimit:global:, ratelimit:auth:, ratelimit:identity: et ratelimit:support:) ; si Redis répond en erreur, la requête passe (passOnStoreError). Derrière un proxy, TRUST_PROXY doit être réglé, sinon tous les clients partagent l'IP du proxy.

Corps et formats

Les corps sont en JSON (Content-Type: application/json) ou en formulaire URL-encodé, 1 Mo au plus, sauf POST /user/identity, qui accepte 12 Mo de JSON pour les deux photos encodées en base64. Un JSON mal formé renvoie 400 Corps de requête JSON invalide, un corps trop gros 413 Corps de requête trop volumineux. Les réponses suivent le format décrit dans Réponses et erreurs, sauf trois exceptions : les sondes /health*, les métadonnées POAP GET /lottery/poap/:file et /metrics.

Lire les résumés OpenAPI

La colonne « Résumé » du tableau reprend le summary du bloc @openapi placé au-dessus de chaque route, celui qu'affiche aussi Swagger. Les résumés ont été alignés sur le comportement réel du code. Quelques nuances ne tiennent pas dans une ligne : elles sont détaillées dans les pages de modules.

Route Nuance
POST /auth/login La déclaration de majorité est déclarative ; l'achat exige en plus la vérification d'âge par pièce d'identité.
POST /auth/2fa/verify Un code d'application n'est accepté qu'avec le loginTicket reçu après le premier facteur ou avec une session du compte.
POST /auth/oauth/google Répond 503 tant que GOOGLE_CLIENT_IDS est vide, ce qui est le cas par défaut.
POST /lottery/gift Le destinataire est désigné par son email, mais aucun email ne lui est envoyé ; seul l'âge de l'expéditeur est vérifié.
POST /lottery/refund En mode simulé, seul le statut du tour change ; le remboursement réel n'existe qu'en mode onchain.
GET /lottery/my-tickets En mode simulé, les badges POAP sont fictifs.
POST /partners/offers La date d'expiration est enregistrée dans Redis mais n'est jamais appliquée.
GET /user/notifications Les trois notifications renvoyées sont codées en dur.
GET /analytics/dashboard En l'absence de données, la répartition par âge affichée est fictive.
POST /admin/treasury/withdraw Le montant amountEth envoyé est ignoré : toute la commission accumulée est versée.
GET /admin/reports/export Le format pdf produit en réalité un fichier JSON.

Routes

Chaque route est servie sous /api/v1 et, pour compatibilité, sous /api. Les sondes et métriques du module système sont à la racine du serveur.

L'API expose 70 routes réparties en 9 modules.

Système

Fichier source : backend/src/api/system/system.routes.ts

Méthode Chemin Accès Contrôles Résumé (OpenAPI)
GET /health public - Vérifier que l'API répond, avec l'état du disjoncteur du Smart Contract
GET /health/live public - Sonde de vivacité (le process répond, aucune dépendance testée)
GET /health/ready public - Sonde de disponibilité (PostgreSQL joignable, serveur non en cours d'arrêt)
GET /health/deep public - Diagnostic détaillé de chaque dépendance avec latence (mis en cache 5 secondes)
GET /api/config public - Configuration runtime pour les clients (version mobile minimale, mode maintenance)

Authentification

Fichier source : backend/src/api/auth/auth.routes.ts

Méthode Chemin Accès Contrôles Résumé (OpenAPI)
POST /api/v1/auth/signup public authRateLimiter, validation signupSchema Créer un compte avec email et mot de passe, puis recevoir un code à 6 chiffres par email (le compte est créé à la vérification du code via /auth/2fa/verify)
POST /api/v1/auth/signin public authRateLimiter, validation signinSchema Connexion par email et mot de passe, avec étape 2FA si elle est activée sur le compte
POST /api/v1/auth/password/forgot public authRateLimiter, validation forgotPasswordSchema Demander un code de réinitialisation du mot de passe par email (réponse identique que le compte existe ou non)
POST /api/v1/auth/password/reset public authRateLimiter, validation resetPasswordSchema Définir un nouveau mot de passe avec le code reçu par email et révoquer toutes les sessions du compte
POST /api/v1/auth/password/change connecté authRateLimiter, validation changePasswordSchema Modifier son mot de passe (mot de passe actuel exigé s'il en existe un, sinon définition d'un premier mot de passe), révoquer toutes les sessions et recevoir une nouvelle session
POST /api/v1/auth/email/change connecté authRateLimiter, validation emailChangeRequestSchema Demander le changement d'adresse email (mot de passe exigé s'il en existe un) et recevoir un code à 6 chiffres sur la nouvelle adresse
POST /api/v1/auth/email/confirm connecté authRateLimiter, validation emailChangeConfirmSchema Confirmer la nouvelle adresse email avec le code reçu, puis prévenir l'ancienne adresse
POST /api/v1/auth/oauth/google public authRateLimiter, validation googleOAuthSchema Connexion ou inscription avec un jeton d'identité Google vérifié côté serveur
GET /api/v1/auth/onboarding public - Récupérer les écrans illustrés de l'onboarding interactif
POST /api/v1/auth/login public authRateLimiter, validation socialLoginSchema Connexion sans mot de passe avec déclaration de majorité (18+), avec envoi d'un code à 6 chiffres par email
POST /api/v1/auth/2fa/setup connecté validation setup2FASchema Initialiser la configuration 2FA (QR Code Google Authenticator ou Email OTP)
POST /api/v1/auth/2fa/verify public authRateLimiter, optionalAuthenticate, validation verify2FASchema Vérifier le code OTP à 6 chiffres (Email, ou App avec le loginTicket délivré après le premier facteur ou une session authentifiée)
POST /api/v1/auth/logout connecté validation logoutSchema Révoquer la session courante, ou toutes les sessions du compte avec allDevices=true
POST /api/v1/auth/2fa/disable connecté authRateLimiter, validation disable2FASchema Désactiver la double authentification 2FA

Loterie

Fichier source : backend/src/api/lottery/lottery.routes.ts

Méthode Chemin Accès Contrôles Résumé (OpenAPI)
GET /api/v1/lottery/status public - Obtenir le compte à rebours, la jauge de progression vers le plafond du tour, les paliers et la preuve Chainlink VRF
GET /api/v1/lottery/transparency-charter public - Obtenir la charte de transparence du Smart Contract vulgarisée
GET /api/v1/lottery/leaderboard public - Obtenir le classement anonymisé des meilleurs ambassadeurs d'EtherBay
GET /api/v1/lottery/poap/:file public - Métadonnées ERC-721 (roundId.json) et visuel (roundId.svg) du badge POAP d'un tour
POST /api/v1/lottery/buy connecté requireAgeVerification, idempotence, validation buyTicketSchema Acheter son ticket unique du grand tirage en 1 clic (âge vérifié requis), transaction signée par le portefeuille intégré du citoyen, et gagner 50 EtherPoints
POST /api/v1/lottery/gift connecté requireAgeVerification, idempotence, validation giftTicketSchema Offrir un ticket à un proche désigné par son email, acheté pour son portefeuille intégré (âge vérifié requis, un ticket par participant)
GET /api/v1/lottery/my-tickets connecté - Historique des tickets (liens vers l'explorateur de blocs si EXPLORER_URL est défini) et galerie des badges POAP
GET /api/v1/lottery/wallet connecté - Portefeuille Ethereum intégré du citoyen (adresse, solde en ethers fictifs, dotation de bienvenue)
POST /api/v1/lottery/claim-prize connecté idempotence, validation claimPrizeSchema Retirer la cagnotte gagnée depuis le Smart Contract vers le portefeuille du gagnant
POST /api/v1/lottery/draw rôle ADMIN validation triggerDrawSchema Déclencher le tirage au sort certifié Chainlink VRF (Admin)
POST /api/v1/lottery/refund rôle ADMIN - Annuler le tour en cours ; en mode onchain, chaque mise devient remboursable dans le Smart Contract et est réclamée automatiquement

Boutique et récompenses

Fichier source : backend/src/api/marketplace/marketplace.routes.ts

Méthode Chemin Accès Contrôles Résumé (OpenAPI)
GET /api/v1/marketplace/catalog public - Consulter le catalogue des récompenses et commerçants partenaires d'EtherBay
GET /api/v1/marketplace/rewards/:id public - Obtenir le détail d'une récompense et sa jauge de stock restant
GET /api/v1/marketplace/points connecté - Obtenir le compteur dynamique d'EtherPoints et l'historique du Ledger
POST /api/v1/marketplace/claim connecté requireAgeVerification, idempotence, validation claimRewardSchema Échanger ses EtherPoints contre une carte à gratter virtuelle (Scratch Card)
POST /api/v1/marketplace/scratch connecté requireAgeVerification, idempotence, validation scratchTicketSchema Acheter un ticket à gratter en EtherPoints (violet ou lucky, âge vérifié requis) qui attribue au hasard une récompense partenaire en stock
GET /api/v1/marketplace/my-codes connecté - Obtenir son Wallet de Récompenses (Mes Codes Promos + QR Codes à scanner)
POST /api/v1/marketplace/redeem rôle PARTNER, ADMIN validation usePromoCodeSchema Valider un QR Code / Code Promo client en magasin (Partenaire ou Admin)

Partenaires

Fichier source : backend/src/api/partners/partners.routes.ts

Méthode Chemin Accès Contrôles Résumé (OpenAPI)
GET /api/v1/partners/ public - Lister toutes les entreprises locales partenaires d'EtherBay
POST /api/v1/partners/ rôle PARTNER, ADMIN validation createPartnerSchema Enregistrer une nouvelle entreprise partenaire locale
POST /api/v1/partners/offers rôle PARTNER, ADMIN validation createRewardOfferSchema Créer une offre de récompense (titre, coût en EtherPoints, stock, date d'expiration indicative)
POST /api/v1/partners/codes/upload rôle PARTNER, ADMIN validation uploadCodesBatchSchema Importer un lot de codes promos uniques, jusqu'à 5 000 (CSV ou tableau JSON)
GET /api/v1/partners/:partnerId/consumption rôle PARTNER, ADMIN - Indicateur circulaire de consommation des codes promos réclamés par les habitants

Utilisateur et RGPD

Fichier source : backend/src/api/user/user.routes.ts

Méthode Chemin Accès Contrôles Résumé (OpenAPI)
GET /api/v1/user/profile connecté - Obtenir le profil complet du citoyen connecté
PATCH /api/v1/user/profile connecté validation updateProfileSchema Modifier son prénom et son nom (50 caractères au plus, lettres, espaces, traits d'union et apostrophes ; une chaîne vide efface le champ)
POST /api/v1/user/support connecté supportRateLimiter, validation supportRequestSchema Envoyer un message au support de la Ville d'EtherBay (5 messages par heure au plus)
POST /api/v1/user/identity connecté identityUploadRateLimiter, identityUploadJsonParser, validation submitIdentitySchema Envoyer le recto et le verso de sa pièce d'identité (JPEG ou PNG en base64, 4 Mo au plus chacun) pour la vérification d'âge par la Mairie
GET /api/v1/user/identity connecté - Consulter le statut de sa vérification d'âge (date d'envoi, date de décision et motif d'un refus)
GET /api/v1/user/referrals connecté - Obtenir son lien de parrainage unique et les boutons de partage rapide (SMS, WhatsApp, Twitter)
GET /api/v1/user/quests connecté - Obtenir la liste des quêtes sociales (Tasks) disponibles
POST /api/v1/user/quests/complete connecté validation completeSocialQuestSchema Valider une quête sociale et gagner des EtherPoints bonus
PUT /api/v1/user/preferences connecté validation updatePreferencesSchema Modifier le thème (clair, sombre ou système), la langue (FR/EN), l'interrupteur général des notifications et leurs catégories (rappels de tirage, résultats, récompenses, parrainage)
GET /api/v1/user/notifications connecté - Consulter le centre de notifications (contenu de démonstration, aucun envoi push), sans les catégories désactivées dans les préférences
GET /api/v1/user/gdpr/export connecté - Exporter l'intégralité de ses données personnelles au format JSON (RGPD)
POST /api/v1/user/gdpr/delete-request connecté - Demander la suppression/anonymisation de son compte avec envoi d'email de confirmation
POST /api/v1/user/gdpr/confirm-delete public validation confirmGdprDeletionSchema Confirmer définitivement la suppression/anonymisation RGPD via le jeton reçu par email

Analytique

Fichier source : backend/src/api/analytics/analytics.routes.ts

Méthode Chemin Accès Contrôles Résumé (OpenAPI)
POST /api/v1/analytics/track public optionalAuthenticate, validation trackEventSchema Enregistrer un événement analytique ou un tag d'acquisition UTM (Twitter, Instagram...)
GET /api/v1/analytics/dashboard rôle ADMIN - Obtenir la répartition par tranche d'âge et les courbes d'acquisition UTM (Mairie)

Administration Mairie

Fichier source : backend/src/api/admin/admin.routes.ts

Méthode Chemin Accès Contrôles Résumé (OpenAPI)
GET /api/v1/admin/dashboard rôle ADMIN - Tableau de Bord Central Mairie (KPIs globaux, Cagnotte, Tickets vendus, Démographie)
POST /api/v1/admin/circuit-breaker rôle ADMIN validation circuitBreakerSchema Interrupteur d'Urgence (Circuit Breaker) pour mettre en pause ou reprendre le Smart Contract
POST /api/v1/admin/treasury/withdraw rôle ADMIN validation treasuryWithdrawalSchema Reverser toute la commission accumulée dans le Smart Contract vers l'adresse de trésorerie de la Mairie
PATCH /api/v1/admin/partners/:partnerId/status rôle ADMIN validation approvePartnerSchema Approuver ou suspendre une entreprise partenaire locale
GET /api/v1/admin/reports/export rôle ADMIN - Générer un rapport analytique et comptable (CSV, ou export JSON pour le format pdf)
GET /api/v1/admin/identity-verifications rôle ADMIN validation listIdentityVerificationsSchema Lister les demandes de vérification d'âge par statut (PENDING par défaut), paginées
GET /api/v1/admin/identity-verifications/:id rôle ADMIN validation identityVerificationIdSchema Consulter une demande de vérification d'âge avec le recto et le verso déchiffrés tant qu'elle est en attente (consultation journalisée dans l'audit)
POST /api/v1/admin/identity-verifications/:id/decision rôle ADMIN validation identityDecisionSchema Approuver ou refuser (motif obligatoire) une vérification d'âge, effacer les images, prévenir le citoyen par email et tracer la décision
GET /api/v1/admin/accounts rôle ADMIN validation listStaffAccountsSchema Lister les comptes Mairie et partenaires (filtre par rôle, recherche par email ou nom, paginé) avec leurs établissements rattachés
POST /api/v1/admin/accounts rôle ADMIN validation createStaffAccountSchema Créer un compte Mairie ou partenaire, ou attribuer ce rôle à un compte existant, puis envoyer l'invitation par email (action journalisée)
PATCH /api/v1/admin/accounts/:id/role rôle ADMIN validation updateStaffRoleSchema Modifier ou retirer le rôle d'un compte (refus sur son propre compte et sur le dernier compte Mairie, sessions révoquées, action journalisée)
GET /api/v1/admin/audit-logs rôle ADMIN - Tableau chronologique de traçabilité des actions effectuées par les administrateurs Mairie

Webhooks

Fichier source : backend/src/api/webhooks/webhooks.routes.ts

Méthode Chemin Accès Contrôles Résumé (OpenAPI)
POST /api/v1/webhooks/blockchain public requireWebhookSignature, validation blockchainWebhookSchema Webhook signé d'indexation des événements, réservé au mode simulé (409 en mode onchain)