Introduction
L'application Corpo Padel permet de gérer les tournois de padel corporatifs (inter-entreprises) d'une ligue. Elle s'adresse à trois types d'utilisateurs : les visiteurs, les joueurs inscrits, et les administrateurs bénévoles qui pilotent les tournois.
L'application doit permettre aux administrateurs de gérer l'ensemble des tournois (planification, équipes, matchs, résultats) et aux joueurs de suivre leur progression et leurs prochains matchs.
Glossaire
| Terme | Définition |
|---|---|
| Padel | Sport de raquette combinant tennis et squash, joué en double sur un court fermé |
| Corpo | « Corporatif », désigne un tournoi inter-entreprises |
| Poule | Groupe de 6 équipes s'affrontant en championnat |
| Équipe | Binôme de joueurs représentant une entreprise |
| Événement | Créneau de jeu regroupant 1 à 3 matchs à une date et heure données |
| Piste | Terrain de padel identifié par un numéro (1 à 10) |
| Saison | Période annuelle d'un tournoi (1ᵉʳ septembre → 31 août) |
| Licence | Identifiant unique d'un joueur, format LXXXXXX |
Spécifications fonctionnelles
2.1 · Rôles et authentification
Visiteur
Non authentifié. Accès à la page d'accueil uniquement.
Joueur
Inscrit dans au moins une équipe. Toutes les pages sauf Administration.
Administrateur
Bénévole gestionnaire. Toutes les pages, avec droits d'édition.
Processus d'authentification
- Méthode : JWT (JSON Web Token), durée de validité 24 heures, stocké côté client.
- Le token contient au minimum :
user_id,email,role,exp. - Chaque requête protégée inclut le token dans l'en-tête
Authorization.
Mécanisme anti-brute force (obligatoire)
- Maximum 5 tentatives de connexion échouées.
- Blocage du compte pendant 30 minutes après le 5ᵉ échec.
- Le compteur se réinitialise après une connexion réussie.
- L'utilisateur est informé du nombre de tentatives restantes, puis du temps restant avant déblocage.
2.2 · Les pages
Accueil
Page d'atterrissage. Pour un visiteur : message de bienvenue + bouton « Se connecter ». Pour un utilisateur connecté : message personnalisé et accès au menu complet.
Planning
Vue calendrier (mensuelle par défaut) de tous les événements de la saison. Un jour contenant un événement est marqué ; le clic affiche les événements du jour. Un joueur voit par défaut les événements où il est impliqué (filtre désactivable). Un admin peut ajouter, modifier et supprimer un événement.
Matchs
Liste des matchs à venir (30 prochains jours). Pour chaque match : date/heure, piste, équipes (entreprises + joueurs), statut. Un joueur voit par défaut ses matchs (filtre désactivable) ; un admin voit tout, peut filtrer (entreprise, poule, statut) et gérer les matchs (ajout, modification, suppression, saisie de score).
Résultats
Résultats des matchs terminés et classement général. Le joueur consulte ses propres résultats (chronologique, victoires/défaites). Le classement des entreprises applique : victoire = 3 points, défaite = 0 point.
Profil
Consultation et modification de ses informations (nom, prénom, date de naissance, email) et de sa photo de profil (formats .jpg/.jpeg/.png, max 2 Mo).
Administration
Réservée aux admins : gestion des joueurs, équipes, poules et comptes. Création de compte joueur (mot de passe temporaire affiché une seule fois) et réinitialisation de mot de passe.
2.3 · Règles métier essentielles
| # | Règle |
|---|---|
| R1 | La date d'un événement / match doit être postérieure ou égale à la date du jour à la création. |
| R2 | Deux matchs ne peuvent pas utiliser la même piste au même créneau (date + heure). |
| R3 | Au sein d'un même événement, une équipe ne joue qu'un seul match et une piste n'est utilisée qu'une fois. |
| R4 | Un événement / match ne peut être supprimé que si son statut est A_VENIR. |
| R5 | Un score doit être tennistiquement valide : chaque set a un vainqueur à 6 jeux (ou 7, l'autre ≤ 5, sauf 7-6 au tie-break). |
| R6 | Le filtre par défaut d'un joueur (planning, matchs) ne montre que les éléments le concernant. |
| R7 | Classement : 3 points par victoire, 0 par défaite ; départage par sets gagnés/perdus. |
Spécifications techniques
3.1 · Architecture & stack
Architecture client-serveur : une SPA (Single Page Application) qui consomme une API REST.
| Couche | Technologies |
|---|---|
| Frontend | Vue 3 · Vite · Vue Router · Pinia · axios · Tailwind CSS |
| Backend | Python 3.11+ · FastAPI · SQLAlchemy · Pydantic |
| Base de données | SQLite |
| Sécurité | JWT · hachage bcrypt |
3.2 · Modèle de données
| Entité | Champs principaux |
|---|---|
| User | id, email, role (VISITEUR / JOUEUR / ADMINISTRATEUR), password_hash |
| Player | id, first_name, last_name, company, license_number, birth_date, photo_url |
| Team | id, company, binôme de 2 players |
| Pool | id, libellé, jusqu'à 6 teams |
| Event | id, date, time, 1 à 3 matches |
| Match | id, court_number (1-10), team1, team2, status (A_VENIR / TERMINE / ANNULE), score_team1, score_team2 |
| LoginAttempt | email, attempts_count, last_attempt, locked_until |
3.3 · API REST
Toutes les routes sont préfixées par /api/v1. La documentation interactive complète (schémas de requêtes/réponses) est disponible sur /docs (Swagger). Vue d'ensemble des principaux endpoints :
Authentification
POST/auth/login : connexion, renvoie le JWT (gère l'anti-brute force).
Événements & matchs
GET/events · POST/events · PUT/events/{id} · DEL/events/{id}
GET/matches · POST/matches · PUT/matches/{id} · DEL/matches/{id}
Création/édition réservées à l'admin. PUT /matches/{id} permet aussi la saisie de score (passage en TERMINE). Les règles R1–R5 s'appliquent.
Résultats
GET/results/my-results : résultats du joueur connecté.
GET/results/rankings : classement général des entreprises.
Profil
GET/profile/me · PUT/profile/me · POST/profile/me/photo · DEL/profile/me/photo
Administration · ADMIN uniquement
POST/admin/accounts/create : créer un compte (mot de passe temporaire à usage unique).
POST/admin/accounts/{user_id}/reset-password : réinitialiser un mot de passe.
Gestion CRUD des players, teams et pools (admin).
3.4 · Formats & validation
| Champ | Règle / Regex | Message d'erreur |
|---|---|---|
| Date | ^\d{4}-\d{2}-\d{2}$ (YYYY-MM-DD) | Format de date invalide |
| Heure | ^([01]\d|2[0-3]):([0-5]\d)$ | Format d'heure invalide |
^[\w.%+-]+@[\w.-]+\.[A-Za-z]{2,}$ | Format d'email invalide | |
| Licence | ^L\d{6}$ | Format LXXXXXX attendu |
| Nom / Prénom | 2 à 50 caractères, lettres | 2 à 50 caractères, lettres uniquement |
| Score | Sets valides (voir R5) | Format de score invalide (ex : 6-4, 6-3) |
| Piste | 1 ≤ n ≤ 10 | La piste doit être entre 1 et 10 |
Codes de statut HTTP attendus
| Code | Usage |
|---|---|
200 / 201 / 204 | Succès (lecture/màj · création · suppression) |
400 | Données invalides |
401 | Non authentifié (token absent / invalide / expiré) |
403 | Accès interdit (rôle insuffisant ou compte bloqué) |
404 | Ressource inexistante |
409 | Conflit (ex. piste déjà occupée) |
Exigences de sécurité
L'application manipule des comptes utilisateurs et doit respecter un socle de sécurité aligné sur l'OWASP Top 10. Ces exigences sont autant de points à vérifier lors de vos tests.
4.1 · Authentification & autorisation
- Les mots de passe sont hachés avec bcrypt, jamais stockés ni renvoyés en clair.
- Les tokens JWT expirent et l'expiration est vérifiée côté serveur à chaque requête.
- Le contrôle de rôle est effectué côté serveur sur chaque route protégée, masquer un élément d'interface ne constitue pas une protection.
- Une route admin appelée par un compte joueur doit renvoyer
403.
4.2 · Protection contre les attaques
- Anti-brute force conforme : blocage exactement au 5ᵉ échec, 30 minutes.
- Injection / XSS : les entrées utilisateur sont validées côté serveur et échappées à l'affichage côté client.
- Énumération de comptes : les messages d'erreur de connexion sont génériques et identiques, que le compte existe ou non.
- En-têtes de sécurité présents ; HTTPS forcé en production ; secrets en variables d'environnement.
4.3 · Validation des données
- Toute donnée entrante est validée côté serveur (formats du §3.4), indépendamment des contrôles du frontend.
- Les fichiers uploadés (photo de profil) sont validés (type, taille).