Aller au contenu
Candidater

Journal des modifications

Les évolutions de Cohez.io, de la plus récente à la plus ancienne.

174 versions publiées.

Versions 131 à 140 sur 174

0.12.1.0 — 2026-05-18

Corrections

  • Règles de tarification invisibles : les cartes PricingRuleCard étaient masquées par un <template> sans directive Vue qui se rendait en élément HTML natif (display: none). Les règles sont désormais visibles sur la page de paramétrage de campagne.
  • Lisibilité mobile des rubriques : en vue mobile (375–393 px), le nom de rubrique était tronqué à 3–4 caractères à cause de la compétition horizontale avec le badge et le compteur. Le nom occupe maintenant toute la largeur (ligne 1), le badge et le compteur passent en ligne 2.
  • Lisibilité mobile des propositions : le nom, le prix et l'information de cours se chevauchaient sur une seule ligne étroite. La mise en page adopte désormais le même principe deux lignes : nom seul en ligne 1, prix et cours/quota en ligne 2.

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_index sur 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 colonnes snapshotted_at et snapshotted_by permettent la traçabilité.
  • RegistrationInvoice (Eloquent) : modèle avec cast JSONB automatique, relations vers Registration et Tenant.
  • CreateRegistrationInvoiceListener : écoute l'événement RegistrationValidated. 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_discount dérivé arithmétiquement : sum(lignes.subtotal) - adjustment_amount - amount_due, toujours cohérent sans re-calcul des règles de tarification.
  • RegistrationStatus simplifié : les cas Paid et PaidPartial sont supprimés. Le statut de paiement est désormais dérivé à la demande via l'accessor payment_status. PaymentObserver ré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 bancaire ajoutée comme méthode standard par défaut pour tous les tenants existants.

Modifications

  • PaymentMethod enum : les cas VacationVoucher et PassSport sont 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 en other via 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 vers Payment.
  • 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.method contenant vacation_voucher ou pass_sport sont reclassées en other avant la suppression des cas de l'enum, évitant toute ValueError de PaymentMethod::from() au chargement.
  • Vérification is_enabled dans le store public : la résolution d'une méthode personnalisée dans PublicRegistrationController::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/reorder manquant — la sauvegarde de l'ordre était ignorée côté serveur.
  • Champ max_quantity masqué : 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 une JsonResponse incompatible avec Inertia ; changé en back().
  • Limite max:100 sur 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 avec lockForUpdate() 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 statuts cancelled et refused (les inscriptions draft comptent pour réserver la place lors d'un checkout HelloAsso en cours).
  • Course::isFull() : expose l'état de complétude du cours, basé sur enrolledCountCurrent() pour une sémantique cohérente avec le check transactionnel.

Corrections

  • Incompatibilité PostgreSQL FOR SHARE + agrégat : suppression du sharedLock() de enrolledCountCurrent() — FOR SHARE est rejeté par PostgreSQL sur les requêtes avec COUNT. La sérialisation atomique est garantie par le lockForUpdate() sur la ligne Course dans la transaction du contrôleur.
  • Test LegalGuardianControllerTest flaky : PersonFactory génère des emails via safeEmail() qui peut contenir le prénom jean ; la recherche dans searchPersons() porte aussi sur l'email, produisant un résultat inattendu selon ORDER BY last_name ASC. Corrigé avec des emails déterministes dans le beforeEach.

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'enum DayOfWeek, 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 via propositions.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 : description et timeSlotsCount retirés, coach et firstSlot ajouté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 directement window.location.search sans reconstruction.
  • Sécurité et robustesse de l'InvitationController : l'invitation_id est 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 seul RegisterUserFromInvitationUseCase qui gère les trois variantes via un match sur user_type. Moins de duplication, traçabilité unifiée.

0.6.1.0 — 2026-05-11

Ajouts

  • Liaison compte utilisateur ↔ adhérent existant : vous pouvez maintenant créer un compte utilisateur directement lié à un adhérent déjà présent dans la base — sans recréer de doublon. Le formulaire affiche un sélecteur de recherche qui liste uniquement les adhérents sans compte, scoped au tenant.
  • Picker adhérent accessible : le sélecteur (MemberPickerForm) est un combobox conforme ARIA (role="combobox", role="listbox", aria-expanded) avec auto-complétion, badge de sélection avec bouton de désélection, et pré-remplissage automatique de l'email depuis la fiche adhérent.
  • Filtre "Sans compte" sur la liste des membres : un nouveau filtre permet d'afficher uniquement les adhérents qui n'ont pas encore de compte utilisateur — utile pour piloter le déploiement progressif des accès.

Corrections

  • Doublons Person/Member à la création de compte : la création d'un compte utilisateur réutilise désormais une personne et un membre existants (même email, même tenant) au lieu d'en créer de nouveaux. Aucune donnée orpheline.
  • Erreur de chargement silencieuse : si l'endpoint /settings/users/available-members est inaccessible (réseau, 403, 500), le picker affiche maintenant un message d'erreur visible plutôt qu'une liste vide sans explication.

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.