Skip to content

Les cotisations entrent dans les comptes - #55

Merged
flocom merged 1 commit into
mainfrom
claude/remove-apel-sensitive-data-73l5iu
Sep 18, 2026
Merged

flocom merged 1 commit into
mainfrom
claude/remove-apel-sensitive-data-73l5iu

Conversation

@flocom

@flocom flocom commented Sep 18, 2026

Copy link
Copy Markdown
Owner

Le trou

Encaisser une cotisation dans l'onglet Adhérents ne créait aucune écriture :

  • accounting_entries a une clé vers un événement, mais aucune vers un adhérent ;
  • src/lib/services/adherents.ts n'importait rien de la comptabilité ;
  • getAccountingSummary() ne somme que accounting_entries.

Le trésorier était donc devant deux mauvais choix : ressaisir chaque cotisation à la main — l'argent compté deux fois, dans deux tables que rien ne réconcilie, et qui divergent dès la première correction — ou ne rien saisir, et laisser la principale recette récurrente de l'association absente du résultat présenté en assemblée générale.

Le modèle : des parts, pas une colonne

Une table de liaison membership_payments (entry_id, member_id, amount_cents), et non un member_id sur l'écriture. L'encaissement groupé est le cas courant et non l'exception : HelloAsso reverse en un seul virement les adhésions de plusieurs familles, exactement comme une remise de chèques. Une écriture couvre donc N adhérents, chacun pour sa part.

La somme des parts ne dépasse jamais le montant de l'écriture, mais peut rester en deçà : un même virement peut porter des cotisations, des billets de kermesse et un don, et seule la part « cotisations » se rattache ici.

Deux gestes

Pointer un encaissement — le cas HelloAsso. On choisit la recette, on coche les familles qu'elle couvre, et le total coché se compare en permanence à son montant : c'est le seul moyen de voir qu'il manque une famille, ou qu'on en a cochée une de trop.

Le remplissage automatique ne prend que des règlements reçus à la date de l'encaissement ou avant. Atteindre le bon total en piochant une famille qui n'a pas payé donnerait un bandeau vert mensonger — c'est précisément l'erreur qu'un pointage doit empêcher. (Première version prise en défaut là-dessus pendant les essais, puis corrigée.)

Reprise initiale — ce qui a été encaissé avant que ce rapprochement existe, en une écriture groupée ou une par adhérent, datée du règlement porté sur la fiche. Sans elle, la comptabilité démarre avec un trou sur l'année en cours.

Les garde-fous

Cas Réponse
Rattacher une cotisation à une dépense 400 Seule une recette peut couvrir des cotisations.
6 × 30 € sur une écriture de 150 € 400 Les parts totalisent 180,00 € pour une écriture de 150,00 €.
Même adhérent deux fois 400 Un adhérent ne peut apparaître deux fois sur la même écriture.
Adhérent inexistant 400
Part négative 400
Écriture inexistante 404

Les écritures de reprise naissent en brouillon : une reprise de masse validée d'emblée serait immuable, donc irrattrapable en cas d'erreur de sélection.

Un point qui mérite explication

Les affectations restent modifiables sur une écriture validée, alors que l'écriture elle-même est immuable. Ce n'est pas une entorse : rattacher une adhésion ne change ni le montant, ni la date, ni le compte. C'est la marque de rapprochement qu'on porte en face d'une ligne de relevé, une fois qu'on a compris à quoi elle correspond.

Et rien n'écrit jamais dans les fiches des adhérents — la comptabilité ne doit pas se remplir dans le dos du trésorier. La page Adhérents signale en revanche ce qui n'est pas encore passé aux comptes, sinon le décalage s'accumule en silence jusqu'à l'AG.

Vérifications

Sur une instance réelle, migration 0024 appliquée, jeu de 12 familles à 30 € (5 réglées le 05/09, 3 le 12/09, 1 le 15/09, 3 impayées) :

  1. état de départ — attendu 360 €, encaissé 270 €, dans les comptes 0 € ;
  2. virement HelloAsso de 150 € du 08/09 → le pointage automatique retient exactement les 5 règlements du 05/09, « Le compte y est », et laisse ceux du 12 et du 15 pour le reversement suivant ;
  3. reprise initiale → un brouillon groupé de 120 € couvrant les 4 restants ;
  4. après rafraîchissement — 270 € encaissés pour 270 € comptabilisés, 0 hors comptes, et l'onglet reprise affiche « Rien à reprendre » ;
  5. les six garde-fous répondent, et l'écriture visée reste intacte après un refus ;
  6. supprimer un brouillon emporte ses parts (9 → 5) sans toucher aux fiches (9 toujours marquées réglées) ;
  7. aucun débordement horizontal de 320 à 1280 px ;
  8. npx tsc --noEmit, npx eslint src --max-warnings=0, npm run build : verts.

Un outil MCP en lecture, get_membership_reconciliation, expose le même rapprochement.

🤖 Generated with Claude Code

https://claude.ai/code/session_014SfQYBU4xXTeSEHKhHQXdD


Generated by Claude Code

Encaisser une cotisation dans l'onglet Adhérents ne créait aucune
écriture : accounting_entries n'avait aucune clé vers un adhérent, et le
service des adhérents n'importait rien de la comptabilité. Le trésorier
était donc devant deux mauvais choix — ressaisir chaque cotisation à la
main, dans deux tables que rien ne réconcilie et qui divergent dès la
première correction, ou ne rien saisir, et laisser la principale recette
récurrente de l'association absente du résultat présenté en assemblée.

Le rapprochement se fait par parts, dans une table de liaison, et non par
une colonne member_id sur l'écriture. Un encaissement groupé est le cas
courant et non l'exception : HelloAsso reverse en un seul virement les
adhésions de plusieurs familles, comme une remise de chèques en banque.
Une écriture couvre donc N adhérents, chacun pour sa part.

Deux gestes, les deux qui se présentent dans l'année :

- POINTER un encaissement déjà enregistré. On choisit la recette, on
  coche les familles qu'elle couvre, et le total coché se compare en
  permanence à son montant : c'est le seul moyen de voir qu'il manque une
  famille, ou qu'on en a cochée une de trop. Le remplissage automatique
  ne prend que des règlements reçus à la date de l'encaissement ou avant
  — atteindre le bon total en piochant une famille qui n'a pas payé
  donnerait un bandeau vert mensonger.

- REPRENDRE ce qui a été encaissé avant que ce rapprochement existe, en
  une écriture groupée ou une par adhérent, datée du règlement porté sur
  la fiche. Sans cette reprise, la comptabilité démarre avec un trou sur
  l'année en cours.

Les garde-fous : seule une recette peut couvrir des cotisations, la somme
des parts ne dépasse jamais le montant de l'écriture — mais peut rester
en deçà, un virement portant aussi des billets ou un don — un adhérent
n'apparaît qu'une fois par écriture, et les écritures de reprise naissent
en brouillon, à relire puis valider.

Les affectations restent modifiables sur une écriture validée, alors que
l'écriture elle-même est immuable. Ce n'est pas une entorse : rattacher
une adhésion ne change ni le montant, ni la date, ni le compte. C'est la
marque de rapprochement qu'on porte en face d'une ligne de relevé.

Rien n'écrit jamais dans les fiches des adhérents. La page Adhérents
signale en revanche ce qui n'est pas encore passé aux comptes, sinon le
décalage s'accumule en silence jusqu'à l'assemblée générale.

Vérifié sur une instance réelle, sur un jeu de 12 familles à 30 € : le
virement HelloAsso de 150 € du 8 septembre se pointe sur les 5 règlements
du 5, et laisse ceux du 12 et du 15 pour le reversement suivant ; la
reprise porte les 4 restants en un brouillon groupé de 120 € ; le
rapprochement retombe alors à 270 € encaissés pour 270 € comptabilisés.
Les six garde-fous répondent, la suppression d'un brouillon emporte ses
parts sans toucher aux fiches, et aucun débordement de 320 à 1280 px.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014SfQYBU4xXTeSEHKhHQXdD
@flocom
flocom force-pushed the claude/remove-apel-sensitive-data-73l5iu branch from c73a44e to e20c537 Compare September 18, 2026 08:23
@flocom
flocom merged commit 15b3d33 into main Sep 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants