Toutes les modifications notables de AgoraGestion sont documentées ici. Format inspiré de Keep a Changelog.
- Environnement démo public sur
demo.agoragestion.org(sous-domaine O2Switch dédié, DB MySQL dédiée,.env.demo.exampleversionné (template —.envréel posé manuellement côté serveur, jamais committé)) - Bandeau
/loginlistant les comptes démo (admin@demo.fr / demo,jean@demo.fr / demo) — visible ssiAPP_ENV=demo, absent en prod - Bridage des sorties externes en
APP_ENV=demo: mails routés vers le log (MAIL_MAILER=log) avec flash UI "Email enregistré (mode démo)", webhook HelloAsso retourne 200 no-op, commandehelloasso:syncno-op,incoming-mail:fetchno-op, OCR factures partenaires retourne un payload stub statique - Lecture seule sur paramètres sensibles : écrans Livewire SMTP + HelloAsso affichent un bandeau d'information, inputs
disabled, bouton "Enregistrer" absent ; middlewareEnforceDemoReadOnlyrefuse les requêtes d'écriture HTTP sur ces routes (403) - Refus des opérations destructives : suppression et archivage d'association en démo lèvent
DemoOperationBlockedException - Commande
demo:capture: extrait toutes les tables tenant-scopées dansdatabase/demo/snapshot.yamlversionné, convertit les dates en deltas relatifs (-13d,-3M), écrase les hash mots de passe endemo, refuse si > 1 association ou siAPP_ENV=production - Commande
demo:reset: rejoue le snapshot YAML (dates rehydratées par rapport ànow()), restaure les fichiers depuisdatabase/demo/files/, garantitphp artisan upenfinally - Workflow
deploy-demo.ymldéclenché surpush main, en parallèle du workflow prod (clone strict) : pull → composer → config:cache → migrate:fresh → demo:reset → up - Cron O2Switch
0 4 * * *— réinitialisation automatique chaque nuit, log dansstorage/logs/demo-reset.log - Helper
App\Support\Demo::isActive()— point de bascule unique pour tous les comportements démo (délègue àapp()->environment('demo')) - Documentation :
docs/runbook-demo.md— guide opérateur complet (installation, snapshot, charte, recette manuelle, dépannage)
App\Support\Demo(helper statique)App\Support\FlashMessages::emailSent()(message conditionnel démo/normal)App\Http\Middleware\EnforceDemoReadOnly— aliasdemo.read-only, liste des routes protégées en constante de classeApp\Exceptions\DemoOperationBlockedException(extendsRuntimeException)App\Console\Commands\DemoCaptureCommand+App\Support\Demo\SnapshotConfig+App\Support\Demo\DateDeltaApp\Console\Commands\DemoResetCommand+App\Support\Demo\SnapshotLoader- Composant Blade
<x-demo-readonly-banner />(réutilisé SMTP + HelloAsso) - Composant Blade
<x-demo-login-banner />(bandeau/login) .github/workflows/deploy-demo.yml
- Transformation Devis Accepté → Facture brouillon — bouton "Transformer en facture" sur la fiche devis ; lignes recopiées en
MontantManuel/Texte;factures.devis_idrenseigné ; bouton désactivé si une facture existe déjà - Création directe — bouton "Nouvelle facture" sur la liste des factures ; modale sélecteur de tiers ; aucun devis source requis
- 3 types de lignes facture :
Montant(ref vers transaction existante) /MontantManuel(manuelle, génère une transaction à la validation) /Texte(information, sans impact comptable) — mix autorisé sur la même facture - Génération automatique d'une
Transactionrecette à la validation d'une facture portant des lignesMontantManuel: 1 transaction recette + NTransactionLignes(1 par ligne manuelle) ; statut "à recevoir" ; mode =facture.mode_paiement_prevu - Champ
mode_paiement_prevu(énumModePaiement) sur la facture, visible et requis à la validation ssi ≥ 1 ligneMontantManuel - Édition inline PU / Qté sur les lignes
MontantManuelen mode brouillon : inputswire:blurdirectement dans le tableau de lignes - Encaissement inchangé : le flow Créances v2.4.3 traite la transaction générée comme n'importe quelle créance — bouton "Encaisser" existant
- ADR-002 : décision architecturale invoice-first à 3 types de lignes (
docs/adr/ADR-002-facture-libre-invoice-first.md)
- PDF devis : les lignes
Texten'affichent plus0,00 €dans les colonnes PU / Qté / Montant (bug préexistant S1 — cellules vides désormais)
- PDF facture : colonnes PU / Qté / Montant rendues selon le type de ligne (option α "asymétrie honnête") :
MontantManuelaffiche 4 colonnes,Montantref affiche libellé + montant total uniquement,Texteaffiche libellé seul
- Enum
App\Enums\TypeLigneFacture: 3e valeurMontantManuel = 'montant_manuel'+ helpersgenereTransactionLigne(),aImpactComptable() factures+=devis_id(FK nullable, ON DELETE RESTRICT),mode_paiement_prevu(enumModePaiementnullable), index(association_id, devis_id)facture_lignes+=prix_unitaire,quantite,sous_categorie_id,operation_id,seance(toutes nullables)FactureService+=creerManuelleVierge(),ajouterLigneManuelle(),ajouterLigneTexteManuelle(),majPrixUnitaireLigneManuelle(),majQuantiteLigneManuelle();valider()étenduDevisService+=transformerEnFacture()- Routes
/devis-manuels/(ex/devis-libres/) — classes et vues renommées en conséquence - Migrations up + down réversibles, aucun backfill
- Suite de tests : 3171 tests verts, 0 failed
- Devis libre autonome — création, édition et cycle de vie d'un devis adressé à un
Tiersquelconque, sans rattachement à uneOperationou à desParticipants - 5 statuts tracés :
brouillon → validé → accepté | refusé | annuléavec utilisateur + date sur chaque transition ; annulation possible depuis tout statut - Numérotation séquence dédiée
D-{exercice}-NNNattribuée à la première validation, immuable ensuite, avec lock pessimiste anti-doublon concurrent - Lignes libres : libellé, prix unitaire, quantité, sous-catégorie optionnelle ; recalcul automatique
montant_total - Modification d'un validé re-bascule en brouillon (numéro conservé) ; statuts
accepté|refusé|annuléverrouillent l'édition - Export PDF : filigrane "BROUILLON" et sans numéro pour brouillon ; numéroté pour
validé+; footer unifiéPdfFooterRenderer - Envoi email avec PJ PDF, tracé dans
email_logs; refusé pour brouillon ou devis vide - Duplication depuis tout statut → nouveau brouillon, lignes recopiées, dates recalculées
- Vue 360° tiers : bloc "Devis libres" avec count par statut et total des
accepté - Sidebar : entrée "Devis libres" sous le groupe Facturation
- Création rapide : clic "Nouveau devis" → modal de sélection du tiers → création et redirection directe
- Isolation multi-tenant fail-closed (
Devis extends TenantModel) ; tests d'intrusion dédiés - Seeders dev : 4 devis libres d'exemples (brouillon, validé, accepté, refusé) sur l'asso démo
- Suite Pest : 0 failed, 0 errored
- Modèle
App\Models\Devis+App\Models\DevisLigne(softDeletes, TenantModel) - Enum
App\Enums\StatutDevisavec helperspeutEtreModifie(),peutEtreDuplique(),peutPasserEnvoye() - Service
App\Services\DevisService(toutes mutations enDB::transaction()) - Composants Livewire
DevisList+DevisEdit; routes/devis-libres+/devis-libres/{devis} - Mailable
App\Mail\DevisLibreMail - Migrations :
devis,devis_lignes,associations.devis_validite_jours
- Refonte du modèle
comptes_bancaires— suppression de la notion bancaleest_systeme, introduction du flag orthogonalsaisie_automatiseepour les comptes alimentés par intégration externe (HelloAsso aujourd'hui, Stripe/SumUp demain) - Compte HelloAsso non sélectionnable dans les formulaires de saisie manuelle (transactions, factures, remises, virements)
- Transactions HelloAsso existantes — champs source (compte, date, montant, mode de paiement, tiers) verrouillés en édition ; seuls libellé, notes, ventilation et pièce jointe restent modifiables. Bandeau d'information dans le formulaire.
- Comptes legacy « Créances à recevoir » et « Remises en banque » supprimés définitivement (audit prod vérifié : zéro transaction liée)
- Colonne
comptes_bancaires.est_systemedroppée - Section « Comptes système » du rapport Flux de trésorerie (builder + vues + PDF + export Excel)
- Nouveau scope Eloquent
CompteBancaire::saisieManuelle()— source de vérité unique pour les sélecteurs de saisie (actif_recettes_depenses=true AND saisie_automatisee=false) - Migration atomique
2026_04_21_100000_refonte_comptes_bancaires_saisieavec garde FK bloquante (9 tables vérifiées) - Guards serveur + readonly UI sur
TransactionFormpour l'édition des transactions HelloAsso - Suite de tests : 2385 tests verts, 0 failed
- Facturation — Enregistrer règlement — bouton fonctionnel sur la fiche facture : coche les transactions sélectionnées comme « reçues » (statut_reglement = recu). Filtre corrigé pour utiliser statut_reglement plutôt que les colonnes supprimées date_reglement/reference_reglement. Suppression du garde-fou est_systeme devenu obsolète en v3.
- Paramètres Association — Informations — mise en page en deux colonnes avec cartes (Identité, Coordonnées, Logo, Cachet), style harmonisé avec l'écran type-opération
- Paramètres — Dirty state — protection « modifications non enregistrées » sur les 5 écrans Paramètres (Association, HelloAsso, HelloAsso Sync, Réception mail, SMTP) : modale Bootstrap « Enregistrer et quitter / Abandonner » identique à l'écran type-opération
- Paramètres — Aide contextuelle — cachet : mention attestations ; onglet Facturation : mention factures ; Réception mail : « Ingestion active » renommé « Relève activée », aide crontab avec commande complète calculée dynamiquement, aide expéditeurs autorisés (rôle sécurité + libellé)
- Paramètres — Onglets élargis — suppression des contraintes max-width sur les onglets Facturation, OCR/IA et Communication
- Expéditeur email — repli association — si un type d'opération n'a pas d'adresse d'expédition configurée, l'adresse paramétrée dans Paramètres > Association > Communication est utilisée automatiquement (AttestationModal, ParticipantShow, ParticipantTable, ReglementTable, OperationCommunication, FactureShow). Méthodes
effectiveEmailFrom()/effectiveEmailFromName()sur le modèle TypeOperation. - Paramètres Association — Communication — harmonisation avec l'écran type-opération : layout 3 colonnes (nom / email / bouton Tester), mini-modale de test identique. La description mentionne le repli pour les types d'opération.
- Type-opération — onglet Emails — note sous l'adresse d'expédition : lien vers Paramètres > Association si le champ est vide.
- PDFs — footer unifié — tous les PDFs (rapprochement bancaire, remise bancaire, émargement, matrice présences, participants liste/annuaire, fiche participant, droit image, attestation présence, rapports compte-résultat/opérations/flux trésorerie) partagent le même pied de page : logo association à gauche (selon contexte), pagination centrée « Page X / Y » correcte sur toutes les pages, « AgoraGestion · date » + logo à droite
- PDF émargement — remplissage dynamique de la dernière page avec des lignes vides en mode formation (pour accueillir des participants de dernière minute). Pas de lignes vides en parcours thérapeutique (liste fermée).
- Modale d'ajout de participant — message d'erreur « déjà inscrit » s'efface correctement au changement ou à la suppression de la sélection de tiers
- Import tiers — le message d'erreur pour email invalide inclut maintenant l'adresse fautive
- Anonymizer — dates générées au format ISO Y-m-d (cohérent avec la prod) pour éviter les erreurs de parsing Carbon en préprod
- PDF émargement — pied de page structuré : logo association à gauche, pagination centrée, « AgoraGestion · date » + logo à droite
- Seeder — correction enum
facture→documentdans EmailTemplateSeeder
- AgoraGestion — renommage complet du projet (SVS Accounting → AgoraGestion) : layouts, scripts de déploiement, docker-compose, seeders, tests, README
- Logo SVG — remplacement du logo PNG par le logo vectoriel
agora-gestion.svg - CSS — renommage des classes
.navbar-svs→.navbar-app, fonctionsvsParseFlatpickrDate→parseFlatpickrDate
- Footer — numéro de version —
app:version-stamplit désormais le fichierVERSIONcommité dans le repo au lieu degit describe --tags. Élimine la dépendance au fetch des tags git lors du déploiement. Le fichierVERSIONest la source de vérité.
- Deploy — ajout de
git fetch --tagsdansdeploy.shpour queapp:version-stamprésolve le tag semver viagit describe(correctif partiel, remplacé par v1.2.9)
- Uniformisation des en-têtes — le titre de page est affiché à l'intérieur du composant
TransactionUniversellesur tous les écrans, sur la même ligne que les boutons de filtre : Toutes les transactions, Transactions par tiers, Transactions par compte, Dons, Cotisations
- Footer production —
APP_ENVcorrigé àproductionsur O2Switch (étaitlocal→ footer orange, version affichée comme SHA git)
- Page Recettes & dépenses — réduction de 5 à 2 lignes dans l'en-tête : ligne 1 = titre + filtres Toutes/DÉP/REC + boutons Import ; ligne 2 = bouton Nouvelle transaction
- Accès contextuel aux transactions par compte — suppression de l'item « Transactions » du menu Banques au profit d'une icône après chaque solde sur le dashboard et d'un bouton dans la liste des comptes bancaires (Paramètres). La route
/comptes-bancaires/{compte}/transactionsfiltre automatiquement sur le compte sélectionné.
- Navigation — l'entrée « Virements » déplacée du menu Transactions vers le menu Banques (un virement interne est un mouvement entre comptes bancaires, pas une transaction comptable)
- Pipeline de déploiement — ajout d'un délai de 30s après le whitelisting IP cPanel pour laisser CSF/iptables appliquer la règle avant la connexion SSH (timeout exit 255)
- Date vide à l'ouverture d'un formulaire de modification —
parseFlatpickrDatene gérait pas le format ISOaaaa-mm-jjstocké dans le champ caché. Corrigé pour tous les formulaires utilisantx-date-input(virements, dépenses, recettes, dons, cotisations)
- Formulaire cotisation — paramètre
tiersId(camelCase) aligné sur la convention Livewire 4 (open-cotisation-for-tiersrecevaittiers_iden snake_case → valeur null)
- Transaction Universelle — composant unifié remplaçant les cinq listes existantes (TransactionList, TransactionCompteList, TiersTransactions, DonList, CotisationList)
- Table UNION SQL sur 6 branches (dépenses, recettes, dons, cotisations, virements entrants/sortants)
- Filtres QBE par colonne (date, libellé, tiers, compte, mode de paiement, sous-catégorie, montant)
- Loupe rouge + badge sous le libellé de colonne quand un filtre est actif
- Boutons de filtre par type : Toutes / DÉP / REC / DON / COT / VIR
- Ligne dépliable (▶/▼) avec mini-tableau (sous-catégorie, opération, séance, notes, montant)
- Icône
bi-chat-left-textdans la colonne libellé quand des notes existent
- Remplacement des vues (Lots 3–7) —
/transactions,/comptes-bancaires/transactions,/tiers/{id}/transactions,/dons,/cotisations - Navigation — renommage « Transactions » → « Recettes & dépenses », ajout « Toutes les transactions »
- Infrastructure staging NAS — environnement Docker sur Synology, hook post-receive, script clone-prod
- Harmonisation visuelle des listes (en-têtes tableaux fond bleu foncé)
- Colonne Pointé avec icônes Bootstrap sur DonList, CotisationList, MembreList
- Notes en tooltip sur TransactionList et VirementInterneList
- Navigation inter-écrans depuis MembreList
- Formulaires modaux autonomes DonForm, CotisationForm, VirementInterneForm
- Mémorisation des derniers choix (poste, mode, compte) dans les formulaires