Journal des modifications
Les évolutions de Cohez.io, de la plus récente à la plus ancienne.
93 versions correspondent à « inscription ».
Versions 81 à 90 sur 93
0.5.1.1 — 2026-04-28
Ajouts
- Responsables légaux dans les fiches enfants : les 60 enfants mineurs seedés (familles Cas1 et Cas2 du ClubAssoSeeder) ont désormais un responsable légal rattaché — père ou mère selon la parité, non-membre pour Cas2. Le tab "Responsables légaux" de PersonIdentityTab n'est plus vide en démo.
- Exceptions de créneaux : le calendrier du ClubAssoSeeder inclut maintenant deux exceptions — une annulation passée (Judo Loisir lundi, il y a 3 semaines, travaux électriques) et un report futur (Judo Enfant mercredi → jeudi dans 2 semaines, salle modifiée). La feature de gestion des exceptions est visible dès le premier démarrage de la démo.
- Diversité des statuts d'inscription : parmi les 56 adultes solo du ClubAssoSeeder, 3 inscriptions illustrent désormais des statuts distincts :
PendingValidation(en attente de validation),Cancelled(annulée) etDraft(brouillon non soumis). Le cycle de vie complet d'une inscription est maintenant représenté. - Réunions enrichies : les trois seeders de démo (ClubAsso, DemoLigue56, AssoCultureSeeder) alignent leurs réunions sur le cycle complet v0.5 — statuts, participants, compte-rendus validés, actions assignées,
next_meeting_at, et transcription Voxtral pour ClubAsso.
Corrections
- Dates Carbon des exceptions de créneaux :
next('Monday')remplacé parprevious('Monday')pour garantir une date passée même quand aujourd'hui est un lundi. La date de report (mercredi → jeudi) utilise désormais une variable partagée pour éviter toute divergence si le seeder s'exécute en chevauchement de minuit.
0.4.4.0 - 2026-04-17
Ajouts
- Reçus de paiement PDF : téléchargement et envoi par email depuis la fiche inscription. Le reçu inclut les coordonnées de l'association, les informations de l'adhérent et du payeur, le détail des paiements reçus et les informations réglementaires (RNA, SIRET).
- Email "Votre reçu de paiement" : l'adhérent (ou le payeur s'il est renseigné) reçoit le reçu en pièce jointe avec un message récapitulatif.
- Adresse postale de l'association : les champs adresse, code postal et ville sont maintenant configurables dans les paramètres de l'association et utilisés dans les reçus PDF.
0.4.3.0 - 2026-04-16
Ajouts
- Fiche membre — onglet Activités — nouvel onglet listant les inscriptions du membre, groupées par saison. Chaque inscription affiche le nom de l'activité, les créneaux horaires (jour, heure, durée, salle) et le statut de l'inscription. Un lien vers la fiche cours est disponible pour les utilisateurs ayant accès aux paramètres.
- Fiche membre — onglet Payeur (modifier) — deux boutons d'édition permettent désormais de modifier directement l'adresse de facturation et la méthode de paiement préférée via des dialogues modaux, sans quitter la fiche membre.
Corrections
- Payeur — effacement des champs adresse — lors de la mise à jour de l'adresse de facturation, envoyer une valeur
nullvide un champ nullable (ligne 2, région…). Auparavant, la logique?? ancienne_valeurempêchait de vider ces champs. - Activités — clés de créneaux horaires — les clés de rendu Vue pour les créneaux utilisent désormais
dayOfWeek-startTimeau lieu dedayOfWeekseul, évitant les doublons lorsqu'un cours a deux plages horaires le même jour.
0.4.0.0 - 2026-04-14
Ajouts
- Formulaire d'inscription public — consentements RGPD — les inscriptions publiques collectent désormais les consentements newsletter, partage de données et droit à l'image. Si la personne existe déjà en base, ses consentements sont mis à jour en mode opt-in uniquement (jamais de rétrogradation). La date de consentement est enregistrée lors de toute acceptation.
- Formulaire d'inscription public — acceptation des documents — le formulaire recueille l'acceptation des statuts et du règlement intérieur. Ces acceptations sont obligatoires pour valider la soumission et sont stockées sur l'adhésion créée.
- Formulaire d'inscription public — responsables légaux (tuteurs) — les membres mineurs peuvent désormais avoir un ou plusieurs responsables légaux renseignés directement depuis le formulaire public. Le premier tuteur est automatiquement marqué comme contact principal (
is_primary_contact). L'interface permet d'ajouter le premier responsable en un seul clic. - Formulaire d'inscription public — adresse ligne 2 — le champ adresse ligne 2 est maintenant disponible dans le formulaire public, mappé vers la Person créée ou mise à jour.
Corrections
- Normalisation des données — emails des tuteurs — les emails des responsables légaux sont normalisés (minuscules + trim) lors de la préparation de la requête, cohérent avec le traitement des emails du membre et du payeur. Prévient les doublons liés à la casse.
- is_primary_contact — premier tuteur — le premier responsable légal est automatiquement désigné contact principal (index 0), les suivants ne le sont pas.
- DRY — calcul de la minorité — la logique de détection d'un membre mineur (age < 18 ou présence de tuteurs) était dupliquée dans
PersonDeduplicationService. Extraite dans une méthode privéeresolveIsMinor(). - Design — polices et composants design system — activation de
font-displaypour Fraunces sur lePublicLayout, attributcrossoriginsur le lien stylesheet Bunny Fonts, suppression des astérisques redondants sur les champs, alignement des composantsSelectetButtonsur le design system. - UX — ouverture automatique du premier tuteur — lorsqu'on clique sur le bouton d'ajout de tuteur, le formulaire s'ouvre directement au lieu d'afficher un accordéon vide.
Modifications
- Couverture de tests : ajout de la validation du chemin opt-in RGPD pour les personnes existantes (33 tests, 106 assertions).
0.3.2.3 - 2026-04-13
Corrections
- Sécurité — validation serveur du montant unitaire — le contrôleur d'inscription publique acceptait n'importe quel
unit_amountsans vérification, permettant à un utilisateur malveillant de soumettre 0 € pour une proposition à prix fixe. LaFormRequestimpose maintenant que leunit_amountcorresponde exactement auamountde la proposition pour les typesfixed, et soit nul pour les typesfree. Les propositionscustom(montant libre) acceptent tout montant ≥ 0. - Bug — propositions gratuites bloquaient le formulaire — dans
CampaignPropositionSelector.vue, les propositions de typefreen'initialisaient pasunit_amountlors de la sélection (radio ou checkbox). Le JSON envoyé ne contenait pas la cléunit_amount, déclenchant l'erreur de validationrequiredcôté serveur et laissant l'utilisateur bloqué à l'étape 2 avec une erreur impossible à corriger. Le champunit_amountest maintenant systématiquement initialisé à0pour tous les types non-fixed. - UX — navigation automatique vers l'étape en erreur — après une soumission rejetée par le serveur, l'utilisateur restait bloqué à l'étape 4 (récapitulatif) sans voir les erreurs de validation sur les étapes précédentes. Des watchers Vue naviguent maintenant automatiquement vers l'étape 1, 2 ou 3 dès qu'une erreur serveur est détectée sur les champs correspondants. Le watcher de l'étape 1 inclut désormais un guard
currentStep.value > 1pour éviter une navigation intempestive.
0.3.2.2 - 2026-04-13
Corrections
- Redirection HelloAsso — TypeError corrigé en production — le formulaire d'inscription publique retournait
RedirectResponsemaisInertia::location()retourneSymfonyResponselors d'une requête XHR Inertia. Sans ce correctif, la redirection vers HelloAsso déclenchait unTypeErrorPHP 8 en production dès qu'un tenant avait ses identifiants HelloAsso configurés, empêchant tout paiement via HelloAsso. Le type de retour destore()est maintenantSymfonyResponse(compatible avec tous les chemins de retour existants). - Champ montant libre — affichage en euros et stockage en centimes — dans le sélecteur de propositions, les champs de montant libre (type
custom) affichaient les centimes bruts (ex :5000au lieu de50,00 €) et sauvegardaient la valeur en euros au lieu des centimes. Le correctif divise par 100 à l'affichage et multiplie par 100 à la saisie, alignant le comportement avec le reste du système. Un attributmax="999999.99"est ajouté pour bloquer les valeurs aberrantes côté client. - Tests HelloAsso — compatibilité environnement sandbox — les fakes
Http::fake()dans les tests de retour et d'erreur HelloAsso utilisaient le domaine de production (api.helloasso.com) en dur. AvecHELLOASSO_SANDBOX=true, ces tests tentaient une vraie requête réseau. Les patterns sont alignés sur*.helloasso*pour couvrir production et sandbox de manière identique aux helpers existants.
0.3.2.1 - 2026-04-10
Corrections
- Page de succès HelloAsso — message affiché selon l'état du paiement — après un paiement HelloAsso, les utilisateurs dont le paiement est encore en cours de traitement voyaient à tort le message "Un email de confirmation vous a été envoyé". La page affiche maintenant une icône horloge et un message "Votre paiement est en cours de traitement" quand le paiement n'est pas encore confirmé, et ne bascule vers le message de confirmation qu'une fois le paiement validé. Le titre de la page s'adapte également (
Paiement en cours de traitementouInscription confirmée).
0.3.2.0 - 2026-04-10
Corrections
- Crash 500 sur la liste des membres — les numéros de téléphone invalides en base (hérités de données importées ou saisies avant validation) provoquaient une
InvalidPhoneNumberExceptionlors de la reconstruction du domaine. Un mécanisme de quarantaine (hydratePhone()) isole maintenant ces valeurs sans bloquer l'affichage. - Normalisation des formats de téléphone à la saisie — les utilisateurs peuvent saisir
06 12 34 56 78,06.12.34.56.78,+33612345678,0033612345678ou un numéro mobile à 9 chiffres sans le 0 initial ; le numéro est automatiquement converti au format canonique0XXXXXXXXXavant validation. Concerne les formulaires membre, tuteur légal, inscription admin et inscription publique. - Regex de validation plus stricte — l'ancre
\zremplace$dans le pattern/^0\d{9}\z/pour rejeter les valeurs avec caractère de fin de ligne masqué.
Ajouts
- Migration de nettoyage des téléphones — normalise ou nullifie les numéros existants en base qui ne respectent pas le format
0XXXXXXXXX, avec logwarningpour chaque valeur supprimée.
0.3.1.0 - 2026-04-09
Ajouts
- Paiement HelloAsso en ligne — depuis le formulaire public d'inscription, les visiteurs peuvent désormais payer directement via HelloAsso Checkout. L'association configure ses identifiants OAuth2 et son slug dans les settings, et le bouton "Payer en ligne" apparaît automatiquement sur le wizard.
- Page Intégrations (
/settings/integrations) — les administrateurs saisissent leur Client ID, Client Secret, slug HelloAsso et secret webhook depuis une interface dédiée. Les secrets ne sont jamais réexposés en frontend après enregistrement. - Webhook HelloAsso (
POST /webhook/helloasso/{tenantId}) — endpoint vérifié par signature HMAC-SHA256. Marque le paiement comme reçu, fait passer l'inscription enPaid, et envoie le mail de confirmation exactement une fois (idempotence viaconfirmation_email_sent_at). - URL de retour HelloAsso (
/register/{token}/helloasso/return) — après paiement, vérifie l'état du checkout intent via l'API HelloAsso. Si payé, confirme l'inscription immédiatement. Si l'API est indisponible, affiche un message "en cours de traitement" et laisse le webhook finaliser. - Page d'erreur HelloAsso (
/register/{token}/helloasso/error) — affichée si le paiement échoue ou si l'API HelloAsso retourne une erreur. L'inscription orpheline est supprimée automatiquement pour permettre une nouvelle tentative. - Service
HelloAssoClient— client HTTP OAuth2 avec cache du token (25 min), support sandbox viaHELLOASSO_SANDBOX=true, deux méthodes :createCheckoutIntent()etgetCheckoutIntent(). - Index
payments_reference_index— index standalone surpayments.referencepour les requêtes de fallback du webhook (la contrainte uniqueUNIQUE(reference, method)existante ne suffit pas pour les lookups parreferenceseul).
Sécurité
- La valeur
redirectUrlretournée par HelloAsso est validée contre une liste d'origines autorisées (helloasso.com/helloasso-sandbox.com) avantredirect()->away()pour se prémunir d'une compromission de l'API côté HelloAsso. - Le webhook est exclu du CSRF Laravel et vérifié par HMAC-SHA256 à la place (
X-Helloasso-Signature). - Rate limiter du webhook keyé sur
tenantId(120 req/h) plutôt que sur l'IP (HelloAsso partage un pool IP entre toutes les organisations).
0.3.0.0 - 2026-04-08
Ajouts
- Formulaire public d'inscription — les associations peuvent générer un lien public (token signé, expirable) depuis les paramètres d'une campagne. Ce lien donne accès à un wizard en 4 étapes (informations membre, chargement des propositions, sélection + payeur, récapitulatif) accessible sans compte. Aucun compte HelloAsso requis.
- Token public de campagne (
CampaignPublicToken) — modèle avec expiration configurable, génération viaStr::uuid()->toString()(UUID v4, colchar(36)), révocation instantanée depuis les settings. Un token révoqué retourne 410. - Déduplication silencieuse — si l'email soumis correspond à une
Personexistante dans le tenant, le service réutilise le membre ou crée unMemberlié sans jamais révéler au visiteur si son compte existait. - Détection des doublons d'inscription — si le même membre tente de s'inscrire deux fois à la même campagne, une erreur de validation claire est retournée sur le champ
member_email. Contrainte unique(member_id, campaign_id)ajoutée en base. - Mail de confirmation (
PublicRegistrationConfirmationMail) — envoyé en queue après inscription réussie si un email est fourni, avec récapitulatif des propositions sélectionnées et du mode de paiement. - Page de confirmation (
/register/{token}/success) — page dédiée après soumission réussie, protégée par le même middleware token. - Branding dans le layout public — le nom de l'association est affiché au-dessus du titre de la page pour que le visiteur sache à quelle organisation il s'inscrit.
- Throttling — les routes publiques d'inscription sont limitées à 10 req/min par IP pour limiter l'abus.
Modifications
- Middleware
ResolveCampaignPublicToken— vérifie désormais que la campagne est en statutOpen(en plus du contrôle d'expiration du token). Une campagneDraftouClosedretourne 410. PersonDeduplicationService—is_minorcalculé dynamiquement depuisdateNaissance(Carbon::age < 18) au lieu d'être codé àfalse.
Corrections
- Migration
add_unique_member_campaign_to_registrations: guard contre les doublons existants avant d'appliquer la contrainte unique (évite un crash silencieux en production si des données corrompues sont présentes).