
À propos des captures
Les écrans de cette page proviennent de l'application en production. Les données personnelles des adhérents, les montants financiers de l'association et les adresses d'infrastructure y sont floutés.
Le client
West Coast Connexion est une association strasbourgeoise de West Coast Swing : cinq cours hebdomadaires répartis sur trois soirs, une centaine d'adhérents, des stages, des soirées et une saison qui court de septembre à août.
Une association de cette taille, c'est déjà une petite entreprise : encaisser des cotisations, tenir des listes d'attente équilibrées entre leaders et follows, générer un planning de trente-deux séances par cours, rembourser les frais des professeurs, prouver un consentement RGPD. Tout cela vivait dans des tableurs, des fils de discussion et des formulaires HelloAsso posés côte à côte.
Le problème
Le site ne savait rien de l'association. Il affichait des widgets HelloAsso en iframe — un formulaire par cours, sans lien entre eux. Aucune donnée métier n'existait : pas de notion de membre, d'adhésion, de saison, de tarif ni de paiement. Le bureau recollait les morceaux à la main après chaque encaissement.
Trois conséquences concrètes : impossible de savoir qui était à jour de cotisation sans croiser deux exports, impossible de garantir la parité leaders/follows d'un cours, impossible de répondre à une demande RGPD avec une preuve datée.
Le choix structurant
Le back-end devient la source de vérité unique — catalogue, panier, workflow, encaissement. HelloAsso redevient ce qu'il aurait toujours dû être : un moyen de paiement parmi d'autres, au même titre qu'un virement ou des espèces. Ce renversement est ce qui rend tout le reste possible.
L'architecture
Trois briques déployées séparément : un site public en Next.js 15, un back-office en Next.js 15, et une API .NET 10 sans interface, seule à parler à PostgreSQL. Les deux interfaces sont des façades : aucune donnée persistée ne leur appartient.
L'API suit une architecture en couches où les dépendances ne pointent que vers l'intérieur — le métier ne connaît ni la base de données ni le web. Cette règle n'est pas une intention de documentation : elle est vérifiée par des tests qui échouent si une couche déborde sur une autre.
- 57 entités métier et 361 gestionnaires de commandes et de requêtes, groupés par domaine fonctionnel
- 45 migrations de base versionnées, appliquées automatiquement au démarrage
- 74 écrans dans le back-office, filtrés par les droits du compte connecté
- 996 tests automatisés dont 33 tests d'architecture et une suite d'intégration qui tourne sur une vraie base PostgreSQL, jamais sur un simulacre
La saison, colonne vertébrale du modèle
Tout est rattaché à une saison : le montant de la cotisation, la grille tarifaire, le catalogue de cours, le planning, les comptes des professeurs. Une seule saison est active à la fois, et la suivante se prépare en parallèle sans perturber celle en cours.
L'ouverture des inscriptions est portée par des fenêtres, une par vague : un accès anticipé protégé par un code partagé — stocké haché, jamais en clair — puis l'ouverture publique, puis la clôture. Le bureau décide des dates, le système fait respecter l'ordre.

La parité leaders / follows
C'est la contrainte propre à la danse en couple, et elle structure tout le module d'inscription : un cours ne se remplit pas, il se remplit des deux côtés à la fois. Chaque rôle a sa capacité et sa file d'attente. Un cours peut être ouvert aux leaders et fermé aux follows le même soir.
Une inscription en couple crée deux inscriptions liées, un leader et un follow, qui vivent et s'annulent ensemble. Le prix est figé à la création : changer la grille tarifaire en cours de saison ne réécrit jamais le passé.
Le CRM adhérents
Chaque adhérent a une fiche : identité, coordonnées, rôle de danse préféré, historique de ses saisons. L'adhésion est annuelle et obligatoire pour s'inscrire à un cours — un invariant appliqué par le code, pas par la vigilance du bureau. Elle devient active à l'encaissement, ce qui déclenche l'émission du numéro de carte de membre.

Le RGPD traité comme une contrainte de conception
- Preuve de consentement — chaque changement de préférence de communication est écrit dans un registre qui ne se met jamais à jour et ne se purge pas. On sait qui a accepté quoi, quand, et depuis quel geste.
- Minimisation des justificatifs — une pièce déposée pour obtenir un tarif réduit est détruite dès la décision, qu'elle soit acceptée ou refusée. Ne survivent que le statut, la date et le nom du décideur.
- Consentement non présumé — une fiche créée par le bureau ou un panier abandonné n'abonne personne. Le canal adhérents ne s'ouvre qu'avec l'adhésion qui le fonde.
Le paiement
Une commande agrège dans un même panier tout ce qu'un payeur règle en une fois : sa propre adhésion, celle de son conjoint, deux cours pour l'un, un pour l'autre. Le total est la somme des lignes, et cet invariant est maintenu par le modèle lui-même.
Le paiement en ligne passe par HelloAsso. Le paiement hors ligne — virement, chèque, espèces — s'enregistre à la main dans la même interface. Les deux chemins convergent : les adhésions et les inscriptions se matérialisent au passage de la commande à l'état payé, quelle que soit la méthode. Aucune logique en double, aucun cas particulier à maintenir.

- Reprise sans double encaissement — l'identifiant de la transaction sert de clé d'idempotence : un webhook rejoué ne crée jamais une seconde adhésion.
- Bascule test / production à chaud — deux jeux d'identifiants coexistent en base et se commutent sans redémarrage, pour tester une évolution du tunnel sans toucher aux vrais encaissements.
- Secrets chiffrés — les clés du prestataire de paiement sont chiffrées en base et ne sont jamais réaffichées, même à un administrateur.
- Exports comptables — récapitulatif et ventilation, en Excel, PDF ou CSV, pour clôturer un exercice sans ressaisie.
Le planning
À partir du créneau récurrent d'un cours, le système génère les trente-deux séances de la saison, en retirant les vacances et les jours fériés. Chaque séance vit ensuite sa vie propre : on la déplace, on l'annule avec un motif visible des membres, on change le professeur pour un remplacement ponctuel.
Un bring — une séance partagée entre plusieurs cours — est modélisé comme une séance unique rattachée à plusieurs catalogues, et non comme des doublons à synchroniser.
Chaque adhérent dispose d'une adresse d'abonnement calendrier personnelle et permanente : il l'ajoute une fois dans son agenda, et ses séances s'y mettent à jour toutes seules — y compris les annulations.

Les cagnottes des professeurs
Chaque professeur dispose d'un compte tenu comme un grand livre : une séance enseignée le crédite automatiquement, une dépense le débite avec sa pièce justificative. Un mouvement est immuable — une erreur se corrige par un mouvement d'ajustement, jamais par une réécriture.
Le solde d'une saison se reporte sur la suivante par une ligne d'ouverture explicite, et le professeur consulte son propre compte en libre-service sans voir ceux des autres.
Le domaine musical
C'est la partie la moins attendue, et celle qui apporte le plus aux professeurs et aux DJ de l'association. Préparer une soirée de West Coast Swing, c'est composer un set qui monte progressivement en énergie, alterne les ambiances et reste dansable — un travail fait à la main pendant des heures.
Une bibliothèque qualifiée
Près de 1 300 morceaux importés depuis Spotify, puis enrichis par un pipeline d'analyse : tempo, énergie, genre, année, et un score de dansabilité propre au West Coast Swing. Les titres écartés sont marqués comme tels plutôt que supprimés — la décision reste consultable.

Le profil : la recette d'un set
Un profil décrit ce qu'on attend d'une soirée : sa durée, la forme de sa courbe de tempo, le nombre de morceaux d'un même artiste qu'on tolère d'affilée, la douceur de la fin de soirée. Il se réutilise — « mon cours du mardi », « ma soirée avancés » — et sert d'entrée au générateur.
L'assistant en langage naturel
On décrit la soirée en français — « soirée intermédiaires de deux heures, montée progressive, fin douce » — et le système règle les paramètres du profil, puis l'algorithme compose à partir de la bibliothèque réelle. Le modèle de langage ne choisit jamais un titre : c'est la garantie structurelle qu'aucun morceau inventé n'atterrit dans un set.
Le DJ garde la main : il verrouille un titre à une position précise, réordonne le reste, régénère autour. Un set peut être envoyé vers Spotify, et le système détecte les modifications faites des deux côtés avant d'écraser quoi que ce soit.

Le socle IA
Toutes les fonctions assistées passent par un point d'entrée unique. La composition de playlists s'en sert aujourd'hui ; la rédaction d'annonces ou le tri des messages s'y brancheront sans réécrire le quota, la traçabilité ni le traitement d'erreur.
- Modèle auto-hébergé — le fournisseur par défaut est un modèle qui tourne sur notre propre infrastructure. Aucune donnée de l'association ne part chez un éditeur d'IA américain.
- Fournisseurs interchangeables — les autres restent joignables et servent de repli. Les clés sont chiffrées en base et jamais réaffichées.
- Quota par compte et par jour — ces appels sont facturés ; rien ne justifie qu'un clic répété les multiplie.
- Trace systématique, y compris en échec — c'est précisément quand un appel échoue qu'on a besoin de savoir ce qui avait été envoyé. Rétention soixante jours.

Sécurité et traçabilité
- Droits par domaine, à deux niveaux — consultation et action sont distinctes. Un trésorier voit les inscriptions sans pouvoir les modifier ; un professeur accède à sa cagnotte et à rien d'autre.
- Révocation immédiate — la session est revalidée à chaque requête : désactiver un compte ou lui retirer un droit prend effet sur-le-champ, sans attendre l'expiration d'un jeton.
- Le navigateur ne parle jamais à l'API — le back-office relaie toutes les requêtes côté serveur. Une seule dérogation, assumée et bornée : le lecteur Spotify embarqué, qui ne reçoit qu'un jeton d'une heure.
- Journal d'audit automatique — toute opération qui modifie des données est enregistrée avec son auteur, sans que le développeur ait à y penser.
- Erreurs collectées et dédoublonnées — les incidents du site public comme ceux de l'API remontent au même endroit, regroupés par empreinte.
- Garde-fou administrateur — le dernier compte d'administration actif ne peut être ni rétrogradé, ni désactivé, ni supprimé.
Le site public
La vitrine consomme uniquement des points d'entrée publics et en lecture seule : événements, calendrier, équipe. Les tarifs affichés sont ceux de la grille saisie en back-office — une seule source, donc jamais de contradiction entre la page et le tunnel d'inscription.


Industrialisation
Trois images Docker construites et publiées à chaque intégration sur notre forge, puis déployées via un bastion — aucune clé d'administration ne circule dans la chaîne de livraison. Deux barrières bloquent la livraison avant toute construction : la suite de tests du back-end, exécutée contre une vraie base PostgreSQL éphémère, et l'analyse statique des deux interfaces.
Résultat
- Le bureau a cessé de recoller des tableurs — cotisations, inscriptions et encaissements vivent au même endroit, avec les exports comptables qui vont avec.
- Les règles sont tenues par le code — pas d'inscription sans adhésion, pas de prix réécrit après coup, pas de double encaissement sur un webhook rejoué.
- La conformité est démontrable — consentements horodatés, justificatifs détruits à la décision, journal d'audit complet.
- L'IA sert à quelque chose de précis — elle règle des paramètres, elle ne compose pas. Elle tourne sur notre infrastructure, sous quota et sous trace.
Conclusion
Une association n'a pas les moyens d'un progiciel de gestion, et les outils du marché ne connaissent ni la parité leaders/follows, ni la cagnotte d'un professeur, ni la courbe de tempo d'une soirée. West Coast Connexion montre qu'un métier de niche se modélise proprement quand on prend le temps de le comprendre — et qu'un logiciel sur mesure n'est pas réservé aux grandes structures.
C'est aussi la démonstration de notre approche de l'IA en application métier : un socle unique, un modèle souverain, un périmètre où la machine ne décide de rien qu'on ne puisse vérifier.
