Plateforme de gestion pour le Club Athlétique L'Haÿ-les-Roses - Inscriptions, événements, résultats.
- Framework: Next.js 15.5.6 (App Router, RSC)
- Language: TypeScript 5.9.3 (strict mode)
- Styling: Tailwind CSS 4.1.14 (alpha), shadcn/ui
- Testing: Vitest, Testing Library, Playwright
- Quality: ESLint, Prettier, Husky, lint-staged, commitlint
- Database: PostgreSQL 16
- Storage: MinIO (S3-compatible)
- Logging: Pino, Loki, Grafana
- Package Manager: pnpm 10.17.0
- Runtime: Node.js 22.19.0
# Developpement
pnpm dev # Demarrer le serveur de developpement (Turbopack)
# Build & Production
pnpm build # Build de production
pnpm start # Demarrer le serveur de production
# Qualite du Code
pnpm lint # Linter le code
pnpm lint:fix # Corriger automatiquement les erreurs de lint
pnpm typecheck # Verification TypeScript
pnpm format # Formater le code (Prettier)
pnpm format:check # Verifier le formatage
# Tests
pnpm test:unit # Tests unitaires (Vitest)
pnpm test:unit:watch # Tests unitaires en mode watch
pnpm test:e2e # Tests E2E (Playwright)
pnpm test:e2e:ui # Tests E2E avec interface UI
# Base de donnees
pnpm db:migrate # Appliquer les migrations (dev)
pnpm db:migrate:deploy # Appliquer les migrations (prod)
pnpm db:reset # Nettoyer + reseeder la base demo
pnpm db:reset:prisma # Reset Prisma standard (optionnel)
pnpm db:seed # Seed manuel (si besoin)
pnpm db:studio # Prisma Studio
# MinIO (Stockage S3)
pnpm minio:configure # Configurer le bucket (policy + CORS)
pnpm minio:setup # Creer docs test ET uploader vers MinIO
pnpm minio:create-test-docs # Creer uniquement les documents de test
pnpm minio:upload # Uploader uniquement vers MinIO
# Validation Complete (CI)
pnpm ci:validate # Executer lint + typecheck + tests + buildConsultez docs/developer/database-reset.md pour le workflow complet de reset.
# Installer les dépendances
pnpm install
# Copier le fichier d'environnement
cp .env.example .env.local
# Démarrer l'infrastructure
docker compose up -d postgres minio grafana
# Configurer MinIO (créer bucket + policy publique)
pnpm minio:configure
# Uploader les assets
pnpm minio:setup
# Configurer la base de données
pnpm db:migrate
pnpm db:seed
# Démarrer le serveur de développement
pnpm devAccéder à l'application : http://localhost:3000
Le projet utilise deux types d'assets :
Les fichiers statiques dans public/ sont servis directement par Next.js :
- logo.svg : Logo du club (placeholder - remplacer pour production)
- hero-bg.svg : Image d'en-tête de la page d'accueil (placeholder - remplacer pour production)
Pour la production : Remplacez ces fichiers par les assets réels du club en conservant les mêmes noms de fichiers.
Les assets dynamiques (logos sponsors, galerie, documents) sont stockés dans MinIO (développement) ou S3 (production) :
Structure des buckets :
cal-uploads/
├── registrations/ # Certificats médicaux PDF + photos ID
├── gallery/ # Photos de la galerie publique
├── sponsors/ # Logos des partenaires
└── posts/ # Images d'illustration des articles
Configuration requise (.env.local) :
S3_ENDPOINT=http://localhost:9000 # MinIO local ou AWS S3
S3_BUCKET_NAME=cal-uploads
S3_ACCESS_KEY_ID=minioadmin
S3_SECRET_ACCESS_KEY=minioadmin123
NEXT_PUBLIC_S3_PUBLIC_URL=http://localhost:9000/cal-uploadsCommandes de gestion :
# 1. Configurer le bucket (obligatoire au premier démarrage)
pnpm minio:configure # Crée bucket + applique policy publique + CORS
# 2. Uploader les assets de démonstration
pnpm minio:setup # Upload 60 fichiers (sponsors, gallery, posts, docs test)
# Commandes avancées
pnpm minio:create-test-docs # Génère uniquement les PDFs de test
pnpm minio:upload # Upload uniquement (nécessite docs déjà créés)Erreur 403 Forbidden ? Si les images retournent une erreur 403, exécutez pnpm minio:configure pour appliquer la politique de lecture publique sur le bucket.
Documentation complète :
- docs/minio-setup.md - Guide de configuration détaillé
- data-assets/README.md - Inventaire des assets et structure
- Scaffolding Next.js 15 TypeScript
- Configuration Tailwind CSS 4 alpha
- Setup shadcn/ui
- Configuration ESLint (security, sonarjs)
- Configuration Prettier + EditorConfig
- Tests unitaires (Vitest + Testing Library)
- Tests E2E (Playwright)
- Hooks Git (Husky, lint-staged, commitlint)
- Logger (Pino)
- Sécurité applicative (CSP, headers)
- Dockerfile multi-stage
- Docker Compose
- Phase 2 : Architecture fonctionnelle (DB, ORM, API, Auth)
- Phase 3 : Features métier
-
Cloudflare Turnstile (anti-spam) :
NEXT_PUBLIC_TURNSTILE_SITE_KEY=your-site-key TURNSTILE_SECRET_KEY=your-secret-key # Dev only - bypass token for development NEXT_PUBLIC_TURNSTILE_BYPASS_TOKEN_DEV=dev-bypass-token -
HubSpot Integration (optionnel) :
HUBSPOT_PORTAL_ID=your-portal-id HUBSPOT_FORM_ID=your-form-id HUBSPOT_SYNC_ENABLED=true NEXT_PUBLIC_HUBSPOT_REGION=eu1 # or na1, ap1, etc. -
S3/MinIO (stockage documents) :
S3_ENDPOINT=http://localhost:9000 S3_BUCKET_NAME=cal-uploads S3_ACCESS_KEY_ID=minioadmin S3_SECRET_ACCESS_KEY=minioadmin123 NEXT_PUBLIC_S3_PUBLIC_URL=http://localhost:9000/cal-uploads
Note: Ces credentials doivent correspondre à ceux définis dans
docker-compose.yml. Après le démarrage de MinIO, exécuterpnpm minio:configurepour créer le bucket et appliquer la politique de lecture publique.
-
Formulaire multi-étapes (
/inscriptions) :- Étape 1 : Informations personnelles
- Étape 2 : Tuteur légal (si mineur)
- Étape 3 : Catégorie & saison
- Étape 4 : Upload documents (certificat médical requis)
- Étape 5 : Consentements + Turnstile
- Étape 6 : Révision et soumission
-
Upload de documents :
- Validation PDF côté client (taille, type MIME, extension)
- Upload vers S3 via API
/api/uploads/registration - Vérification Turnstile obligatoire avant upload
- Stockage des métadonnées (storageKey, checksum, size)
-
Traitement backend :
- Vérification anti-spam (Turnstile)
- Validation des données (Zod)
- Vérification des quotas (liste d'attente si saturé)
- Création famille/tuteur/joueur/inscription
- Création des attachments depuis les documents uploadés
- Soumission à HubSpot (si activé)
- Envoi email de confirmation
# Tests unitaires (124 tests)
pnpm test:unit run
# Tests E2E (si implémentés)
pnpm test:e2e --grep @registration-publicLes quotas sont définis par saison et catégorie (SeasonCategoryQuota). Lorsqu'un quota est saturé :
- L'inscription est créée avec
status: PENDINGetwaitlistPosition - Une entrée
RegistrationWaitlistest créée - Un email "waitlisted" est envoyé au lieu de "confirmation"
Module de gestion des partenaires et sponsors du club avec interface dashboard et affichage public.
Dashboard (/dashboard/sponsors) :
- Gestion CRUD complète (créer, modifier, supprimer)
- Upload de logos via API (PNG/JPG/WebP, max 3 Mo)
- Classification par tier (Platine, Or, Argent, Bronze, Partenaire)
- Toggle actif/inactif pour contrôler la visibilité publique
- Réorganisation avec boutons monter/descendre
- Suivi des clics sur les liens sponsors
- Statistiques : total, actifs/inactifs, total de clics, répartition par tier
Page publique (/sponsors) :
- Affichage des sponsors actifs uniquement
- Groupement par tier avec tailles différenciées
- Logos cliquables vers les sites web des sponsors
- Layout responsive (grid adaptatif)
- Feature flag (
isFeatureEnabled('sponsors')) pour activer/désactiver
sponsors.view- Voir les sponsors (dashboard)sponsors.create- Créer un sponsorsponsors.edit- Modifier un sponsor (informations, actif/inactif, ordre)sponsors.delete- Supprimer un sponsorsponsors.upload- Uploader des logos (implicite via create/edit)
13 sponsors de démonstration avec logos réels (S3/MinIO) répartis par tier :
- 2 Platine : Informatique Séquanienne, Crédit Île-de-France
- 3 Or : Decathlon, Pharmacie des Lilas, Brasserie des Roses
- 3 Argent : Optique Horizon, Boulangerie Dupont, Clinique du Sport
- 2 Bronze : Transports Giraud, NovaPrint
- 3 Partenaires : Mairie de L'Haÿ-les-Roses, Association Le 1924, AXA Assurances Dumont
Commande : pnpm db:seed
Pour les environnements existants avec des sponsors utilisant des URLs Unsplash :
# Prévisualiser les changements
pnpm migrate:sponsor-logos --dry-run
# Appliquer la migration (avec confirmation)
pnpm migrate:sponsor-logos
# Mode forcé (sans confirmation)
pnpm migrate:sponsor-logos --forceLe script migre automatiquement :
- Les anciens sponsors avec URLs Unsplash → URLs S3/MinIO
- Les sponsors sans logo → Logos S3 correspondants
- Crée un audit log de chaque modification
- Affiche un résumé détaillé (mis à jour / ignorés / erreurs)
Prérequis : Les logos doivent être uploadés dans MinIO (pnpm minio:setup)
Outil CLI pour configurer rapidement un club (paramètres site, branding, admin) sans modifier le code.
Mode interactif (recommandé pour la première configuration) :
pnpm bootstrap:clubInvite l'utilisateur à saisir toutes les informations étape par étape avec des valeurs par défaut suggérées.
Mode fichier de configuration (pour automatisation) :
pnpm bootstrap:club --config=./bootstrap.example.jsonCharge la configuration depuis un fichier JSON. Voir bootstrap.example.json pour un exemple complet.
Dry-run (prévisualiser sans appliquer) :
pnpm bootstrap:club --dry-run
pnpm bootstrap:club --config=./config.json --dry-runAffiche les modifications qui seraient appliquées sans les exécuter.
Avec seeds (charger les données de démo après bootstrap) :
pnpm bootstrap:club --with-seedsLe bootstrap permet de configurer :
Club :
- Nom complet et nom court
- Description
- Logo URL
- Site web URL
Contact :
- Téléphone
- Adresse complète (rue, ville, code postal)
Réseaux sociaux (optionnel) :
- Facebook, Twitter, Instagram, YouTube
Feature Flags :
- Activation/désactivation des modules (inscriptions, événements, articles, galerie, sponsors)
Utilisateur Admin :
- Email (identifiant de connexion)
- Mot de passe (min 8 caractères)
- Nom d'affichage
Système (optionnel) :
- Email expéditeur (fromEmail, fromName)
- Email de réponse (replyToEmail)
Voir bootstrap.example.json pour un exemple complet.
{
"club": {
"name": "Club Athletique L'Hay-les-Roses",
"shortName": "CAL",
"description": "Club d'athletisme...",
"logoUrl": "https://example.com/logo.png",
"websiteUrl": "https://www.cal-athletisme.fr"
},
"contact": {
"email": "contact@cal-athletisme.fr",
"phone": "+33 1 45 47 89 12",
"address": "12 Avenue de la Republique",
"city": "L'Hay-les-Roses",
"postalCode": "94240"
},
"features": {
"registrations": true,
"events": true,
"posts": true,
"gallery": true,
"sponsors": true
},
"admin": {
"email": "admin@cal-athletisme.fr",
"password": "SecurePassword123!",
"name": "Admin CAL"
}
}- Les mots de passe sont hachés avec Argon2id avant stockage
- Les opérations critiques sont auditées (création/màj admin, paramètres)
- Aucun secret n'est affiché dans les logs (mot de passe masqué dans les résumés)
pnpm bootstrap:club --helpClub Athlétique L'Haÿ-les-Roses