Journal des modifications
Les évolutions de Cohez.io, de la plus récente à la plus ancienne.
93 versions correspondent à « inscription ».
Versions 71 à 80 sur 93
0.13.0.1 — 2026-05-21
Corrections
- Formulaire de prolongation d'acompte visible : le bouton « Prolonger le délai » n'apparaissait plus dans la fiche inscription suite à une comparaison TitleCase des statuts — corrigé en utilisant les valeurs sérialisées (
draft,pending_validation). - Dépôt nul ignoré : si la règle d'acompte ne correspond à aucune rubrique des prestations choisies, le calcul retourne 0 € — l'inscription suit désormais le chemin normal sans générer de flux dépôt fantôme.
- Prolongation active jusqu'en fin de journée : la nouvelle date-limite est enregistrée à 23:59:59 (fin de journée) plutôt qu'à minuit, évitant l'abandon immédiat par le cron si celui-ci tourne après minuit la même nuit.
- Cron dépôts expiré : schedule horaire effectif : le verrou
withoutOverlappingest désormais limité à 5 minutes (contre 24 h par défaut), garantissant que le cron tourne bien à chaque heure même après un éventuel blocage.
0.13.0.0 — 2026-05-20
Ajouts
- Règle d'acompte par campagne : les admins peuvent configurer sur chaque campagne une règle d'acompte (% global ou % / montant fixe par rubrique) avec une date-limite d'expiration et les méthodes de paiement déclenchantes.
- Settlement method : le mode de règlement du solde (HelloAsso, virement, chèque…) est distinct des méthodes déclenchantes. Permet le flux « paiement partiel HelloAsso + solde hors-ligne ».
- Checkout HelloAsso dépôt : si la méthode du payeur déclenche la règle et que le settlement est HelloAsso, un checkout HA est créé pour le montant du dépôt uniquement (pas le total).
payment.notescontientcheckout_type: depositpour identifier le retour. - Statut PendingValidation : les inscriptions offline avec règle d'acompte passent immédiatement en
PendingValidation(en attente de confirmation de paiement par l'admin). - Email de relance dépôt : si le retour HelloAsso arrive sans paiement confirmé, un email de relance (
DepositRelanceMail) est envoyé une seule fois (guarddeposit_relance_sent_atatomique vialockForUpdate). - Prolongation du délai : l'admin peut prolonger la date-limite d'acompte d'une inscription depuis la fiche inscription. L'adhérent reçoit un email
DepositDeadlineExtendedMail. - Notification admin paiement reçu : à chaque marquage « paiement reçu », l'admin reçoit un email
AdminPaymentReceivedMailsi le tenant a uncontact_email. - Abandon automatique des acomptes expirés : la commande cron abandonne désormais aussi les inscriptions en attente de validation (
PendingValidation) dont le délai est dépassé, en plus des brouillons — sans toucher aux inscriptions dont le dépôt a déjà été reçu. - Texte explicatif configurable : l'admin peut saisir un message libre (
explanation_text) visible dans l'email de confirmation et sur la page de succès publique, pour indiquer au payeur comment régler le solde (ex. coordonnées virement, adresse pour chèque).
Pour les contributeurs
CampaignDepositRule: nouveaux champssettlement_method(string nullable),explanation_text(text nullable).global_percentagedevient nullable. Nouveauconfig_type = rubrique_rulesavec colonnerubrique_rules(JSONB).registrations: nouveau champdeposit_relance_sent_at(timestamp nullable).DepositCalculatorService: gère les deuxconfig_type.rubrique_rules: calcul par rubrique avec modespercentageetfixed_per_item.- Webhook HelloAssoWebhookController :
checkout_typelu depuispayment.notes(stocké server-side) et non depuis le body du webhook (non fiable pour les transitions asynchrones). - Validation
rubrique_rules.*.rubrique_id: scopée tenant + campagne pour éviter l'injection cross-campagne qui produirait un dépôt€0.
0.12.0.0 — 2026-05-16
Ajouts
- Facture d'inscription : à la validation d'une inscription, un snapshot immuable est automatiquement créé. Il capture les lignes de propositions (nom, quantité, montant unitaire, sous-total), le total facturé, les remises appliquées et le contexte (membre, campagne, saison, payeur) figé au moment de la validation. La fiche inscription affiche désormais un encart « Facture d'inscription » avec toutes ces informations.
member_indexsur les inscriptions : indice de position du membre dans le foyer (0 = 1er, 1 = 2ème…), utilisé pour calculer les remises famille dans le snapshot.
Pour les contributeurs
- Table
registration_invoices: stocke le snapshot JSONB de chaque inscription validée. Contrainte unique sur(registration_id)garantissant l'idempotence. Les colonnessnapshotted_atetsnapshotted_bypermettent la traçabilité. RegistrationInvoice(Eloquent) : modèle avec cast JSONB automatique, relations versRegistrationetTenant.CreateRegistrationInvoiceListener: écoute l'événementRegistrationValidated. Résilient : si la création du snapshot échoue (indisponibilité DB…), la validation de l'inscription réussit quand même (erreur loguée sans propager l'exception).total_discountdérivé arithmétiquement :sum(lignes.subtotal) - adjustment_amount - amount_due, toujours cohérent sans re-calcul des règles de tarification.RegistrationStatussimplifié : les casPaidetPaidPartialsont supprimés. Le statut de paiement est désormais dérivé à la demande via l'accessorpayment_status.PaymentObserverréduit à des no-ops. Migration de backfill incluse (paid/paid_partial→validated).
0.11.0.0 — 2026-05-15
Ajouts
- Moyens de paiement configurables par association : chaque association peut désormais activer/désactiver et personnaliser ses moyens de paiement depuis Paramètres → Moyens de paiement. Les méthodes standard (HelloAsso, Chèque, Virement, Espèces, Carte bancaire, Autre) peuvent être désactivées individuellement. Des méthodes personnalisées (libellé libre) peuvent être créées, éditées et supprimées. HelloAsso est automatiquement masqué si l'association n'a pas configuré ses identifiants API.
Carte bancaireajoutée comme méthode standard par défaut pour tous les tenants existants.
Modifications
PaymentMethodenum : les casVacationVoucheretPassSportsont retirés de l'enum (chèques vacances / Pass Sport — spécifiques France). Les associations qui les utilisaient doivent les recréer comme méthodes personnalisées. Les paiements existants avec ces méthodes sont automatiquement reclassés enothervia migration.- Formulaire d'inscription public : les méthodes de paiement affichées sont désormais filtrées par la configuration du tenant (seules les méthodes activées apparaissent).
CreditCard(Carte bancaire) s'affiche correctement.
Pour les contributeurs
- Table
tenant_payment_methods: nouvelle table relationnelle stockant la configuration de chaque moyen de paiement par tenant, avec index unique partiel (PostgreSQL) garantissant l'unicité des méthodes standard par tenant. TenantPaymentMethod(Eloquent) : nouveau modèle gérant les méthodes standard et personnalisées, avec la relation inverse versPayment.- Page Filament
PaymentMethodResource: interface d'administration self-service pour la gestion des moyens de paiement, avec formulaire inline et actions de réordonnancement. - Migration de sécurité : les lignes
payments.methodcontenantvacation_voucheroupass_sportsont reclassées enotheravant la suppression des cas de l'enum, évitant touteValueErrordePaymentMethod::from()au chargement. - Vérification
is_enableddans le store public : la résolution d'une méthode personnalisée dansPublicRegistrationController::store()vérifie désormais que la méthode est bien activée (is_enabled = true).
0.10.1.0 — 2026-05-14
Modifications
- Wizard d'inscription public — activités en premier : l'ordre des étapes est désormais Activités → Identité (était Identité → Activités). L'adhérent choisit ses activités avant de remplir ses coordonnées, ce qui réduit la friction mentale à l'entrée du formulaire. La navigation multi-membres (Précédent/Suivant entre membres, édition depuis la transition, retour via le MembersStrip) est entièrement mise à jour pour refléter ce nouvel ordre.
0.10.0.0 — 2026-05-14
Ajouts
- Refonte du campaign builder : interface de construction de rubriques et propositions entièrement redessinée, avec drag-and-drop (vuedraggable v4) pour réordonner les rubriques et les propositions. Chaque rubrique est collapsible.
- QuotaChip : nouveau composant affichant le taux de remplissage d'un cours (inscrits / capacité) avec une barre colorée (vert → orange → rouge) et le nom du cours.
- PriceChip : nouveau composant badge pour l'affichage des tarifs (fixe, libre, personnalisé) dans la liste des propositions.
- PublicFormModal : modal de gestion du lien public d'inscription (générer, copier, révoquer le token) directement depuis le campaign builder.
- Page campagne plus rapide : les compteurs d'inscrits de tous les cours sont chargés en une seule requête, quelle que soit la taille de la campagne.
- Quota live dans l'éditeur de proposition : lors de l'édition d'une proposition, la sélection d'un cours affiche immédiatement son quota (barre + compteur) avant de sauvegarder.
Corrections
- Réordonnancement des propositions : nouvel endpoint
PATCH rubriques/{rubrique}/propositions/reordermanquant — la sauvegarde de l'ordre était ignorée côté serveur. - Champ
max_quantitymasqué : régression — le champ « Quantité max par personne » était caché dans le formulaire d'édition quand aucun cours n'était associé à la proposition. - Réponse des endpoints de réordonnancement :
RubriqueController::reorder()retournait uneJsonResponseincompatible avec Inertia ; changé enback(). - Limite
max:100sur les requêtes de réordonnancement (ReorderRubriquesRequest,ReorderPropositionsRequest) pour prévenir les payloads excessifs.
0.9.0.0 — 2026-05-13
Ajouts
- Contrôle de capacité des cours : les inscriptions (admin et publiques) sont désormais bloquées quand un cours est complet. Protection à deux niveaux : fast-fail UX dans le
FormRequest(withValidator()) + check atomique aveclockForUpdate()dans une transaction pour gérer la concurrence. - Badge « Complet » sur les propositions : dans le formulaire d'inscription public, les propositions rattachées à un cours complet affichent un badge
warning« Complet » et désactivent la sélection (radio/checkbox grisés). Course::enrolledCountCurrent(): compteur d'inscrits actifs excluant les statutscancelledetrefused(les inscriptionsdraftcomptent pour réserver la place lors d'un checkout HelloAsso en cours).Course::isFull(): expose l'état de complétude du cours, basé surenrolledCountCurrent()pour une sémantique cohérente avec le check transactionnel.
Corrections
- Incompatibilité PostgreSQL
FOR SHARE+ agrégat : suppression dusharedLock()deenrolledCountCurrent()—FOR SHAREest rejeté par PostgreSQL sur les requêtes avecCOUNT. La sérialisation atomique est garantie par lelockForUpdate()sur la ligneCoursedans la transaction du contrôleur. - Test
LegalGuardianControllerTestflaky :PersonFactorygénère des emails viasafeEmail()qui peut contenir le prénomjean; la recherche danssearchPersons()porte aussi sur l'email, produisant un résultat inattendu selonORDER BY last_name ASC. Corrigé avec des emails déterministes dans lebeforeEach.
0.8.0.0 — 2026-05-12
Ajouts
- Refonte de la liste des cours : liste verticale dense avec tri automatique par jour de la semaine (Lundi → Dimanche), badge « Complet » quand
enrolledCount >= capacity, filtre par label (pills cliquables, logique OR côté client), affichage du coach et du premier créneau (jour + heure) sur chaque ligne. - Page détail cours améliorée : mise en page 2 colonnes (créneaux + formulaires d'inscription à gauche, membres à droite), recherche par nom et filtre par statut dans la liste des membres, liste scrollable indépendante, export CSV des membres inscrits.
- Export CSV des membres : nouvel endpoint
GET /courses/{course}/export-members, StreamedResponse avec BOM UTF-8 pour compatibilité Excel, protection contre l'injection de formules CSV (préfixe'sur=,+,-,@,\t,|). DayOfWeek::sortOrder(): méthode de tri chronologique (0=Lundi → 6=Dimanche) sur l'enumDayOfWeek, nécessaire car les backing strings trient lexicalement (friday < monday).
Corrections
- Cohérence
enrolledCount: les inscriptions annulées, refusées et en brouillon sont désormais exclues du décompte d'inscrits dans les vues index et détail (précédemment comptées dans l'index viapropositions.sum('registrations_count')). - Tri des cours à heure égale : la clé de tri composite
sprintf('%d_%s', sortOrder, start_time)garantit un ordre stable lorsque plusieurs cours partagent le même jour.
Modifications
- Payload index des cours :
descriptionettimeSlotsCountretirés,coachetfirstSlotajoutés.
0.7.0.0 — 2026-05-12
Ajouts
- Flux d'invitation RGPD : les administrateurs peuvent inviter des membres et des employés par email. Le destinataire reçoit un lien signé (valide 72h) lui permettant de créer son compte (prénom, nom, email pré-remplis, mot de passe, consentement RGPD). L'invitation est marquée "utilisée" à l'issue de la création. Les employés ne voient pas le champ consentement (non applicable).
- Trois types d'invitation :
member(crée un nouveau member + person),member_linked(lie le compte à un adhérent existant sans doublon),employee(crée un compte sans member associé). - Pré-remplissage du formulaire d'inscription : prénom et nom de l'invité sont pré-remplis depuis l'invitation et rendus non-modifiables si renseignés.
- Test de couverture du flux réel : test d'intégration qui valide la chaîne complète GET-signed URL → POST → redirection, garantissant que l'ordre alphabétique des paramètres signés est préservé jusqu'à la validation HMAC.
Corrections
- 403 « Invalid Signature » à la soumission du formulaire d'invitation : le composant Vue reconstituait les paramètres de query string dans un ordre différent de celui du lien signé (alphabétique, imposé par Laravel
ksort()). La validation HMAC étant sensible à l'ordre, cela produisait un 403 systématique. Corrigé en passant directementwindow.location.searchsans reconstruction. - Sécurité et robustesse de l'InvitationController : l'
invitation_idest désormais vérifié en database plutôt qu'ignoré silencieusement ; les domaines d'email autorisés sont validés côté serveur pour les invitations employee. - Erreurs PHPStan : remplacement des opérateurs
?->sur la gauche d'un??par des guards explicites. - Doublons d'écouteurs d'événements : suppression des
Event::listen()manuels redondants qui dupliquaient les listeners déjà enregistrés via$listen.
Modifications
- Consolidation du use case d'inscription : les trois use cases distincts (
CreateMemberUserUseCase,CreateEmployeeUseCase,LinkMemberAccountUseCase) sont fusionnés en un seulRegisterUserFromInvitationUseCasequi gère les trois variantes via unmatchsuruser_type. Moins de duplication, traçabilité unifiée.
0.6.0.0 — 2026-05-08
Ajouts
- Inscription publique multi-adhérents : un même formulaire permet désormais d'inscrire plusieurs membres d'une famille en une seule opération. Un wizard en 5 étapes guide le responsable : identité de chaque adhérent, choix des activités, résumé intermédiaire (avec modification possible), sélection du payeur, puis récapitulatif et paiement. Jusqu'à 10 membres par soumission.
- Paiement HelloAsso partagé : pour les paiements HelloAsso, un unique checkout est créé pour l'ensemble des membres inscrits en une fois. Le montant total agrégé est transmis à HelloAsso ; la référence du checkout intent est stockée sur chaque paiement pour assurer la traçabilité.
- Sélection flexible du payeur : le responsable peut désigner comme payeur l'un des adhérents, l'un de leurs responsables légaux, ou renseigner manuellement les coordonnées d'un tiers.
- Responsables légaux (tuteurs) : chaque adhérent peut déclarer un ou plusieurs responsables légaux avec nom, email, téléphone et type de relation. Un tuteur peut être sélectionné directement comme payeur.
- Auto-sélection des rubriques à proposition unique : si une rubrique requise ne contient qu'une seule proposition, elle est pré-sélectionnée automatiquement.
- Validation client-side complète : chaque étape du wizard valide localement les champs obligatoires (identité, activités) avant de progresser, sans aller-retour serveur inutile.
Corrections
- Navigation retour depuis l'édition d'un adhérent : le bouton "← Précédent" dans l'étape identité d'un adhérent édité depuis la vue transition retournait correctement à la liste de transition plutôt que de ne rien faire.
Modifications
- Performance emails : les emails de confirmation sont maintenant envoyés en une seule passe, quel que soit le nombre de membres inscrits en un checkout — plus de ralentissement sur de grands lots.