Une API NestJS modulaire
Le backend d'Open Dossard est une API REST en NestJS, découpée en modules métier : compétitions, courses et engagements, licences, clubs, challenges, tableau de bord, notifications, traces GPX, paiements et rapports. Les DTO sont validés et transformés avec class-validator et class-transformer, et la documentation Swagger / OpenAPI est générée à partir du code. La compilation passe par SWC.
L'API pilote aussi les services transverses : notifications push Firebase Cloud Messaging envoyées via firebase-admin, tâches planifiées (@nestjs/schedule), exports PDF (jsPDF) et CSV des classements, fiches d'épreuve, licences et clubs, et intégration du paiement en ligne HelloAsso pour les inscriptions.
La qualité est garantie par des tests unitaires Jest et une suite de tests de bout en bout Supertest qui s'exécute contre une vraie base PostgreSQL démarrée à la volée par Testcontainers. Les règles d'autorisation, les cycles de vie des challenges ou le paiement en ligne sont ainsi vérifiés sur un environnement identique à la production.
La donnée avec PostgreSQL
Les données sont stockées dans PostgreSQL et accédées via TypeORM, avec un schéma qui n'évolue que par des migrations versionnées (la synchronisation automatique est désactivée). Le modèle couvre licenciés, clubs, épreuves, engagements et résultats de plusieurs fédérations, chacune avec ses propres catégories et barèmes.
Nous exploitons les capacités natives de PostgreSQL plutôt que de tout recalculer côté application :
- une recherche insensible aux accents et à la casse sur les coureurs, clubs et épreuves, avec l'extension unaccent et
ILIKE ;
- des fonctions de fenêtrage (
ROW_NUMBER() OVER) et DISTINCT ON pour calculer classements, palmarès et points de challenges directement en SQL ;
- des index ciblés sur les requêtes les plus sollicitées, et des colonnes JSONB là où la structure est variable.
Le back-office web et l'exploitation
Les organisateurs gèrent leurs épreuves dans une application web en React et Vite, avec Tailwind CSS et Radix UI pour l'accessibilité, TanStack Query et TanStack Table pour les grilles de données, React Hook Form et Zod pour la validation des formulaires. Elle est installable en PWA.
L'ensemble est conteneurisé avec Docker Compose derrière un reverse proxy Nginx avec TLS Let's Encrypt. Un pipeline GitHub Actions enchaîne release, build, tests et déploiement, avec publication des images sur GitHub Container Registry. Côté mobile, les binaires sont produits avec EAS Build et publiés sur les stores avec Fastlane, tandis que Firebase Crashlytics et Firebase Performance surveillent la stabilité et les temps de réponse en production.