Reclasser une transaction répartie laisse sa ligne de compensation dans l’ancienne catégorie #454

Open
opened 2026-10-17 11:37:16 +00:00 by maximus · 0 comments
Owner

Constat

Relevé par la revue de la PR #452 (commentaire 24129), hors de son diff, et confirmé à la lecture du code sur main 065f580 :

  • updateTransactionCategory (src/services/transactionService.ts:301-315) ne met à jour que la ligne parente (UPDATE transactions SET category_id = $1 … WHERE id = $3) ;
  • saveSplitAdjustment (l. 447-461) crée la ligne de compensation avec parent.category_id, c'est-à-dire la catégorie du parent au moment où la répartition est enregistrée, et le montant -offsetTotal.

Reclasser ensuite le parent laisse donc la compensation dans l'ancienne catégorie.

Reproduction

Rejouée par le relecteur en SQLite sur consolidated_schema.sql :

  1. Une transaction de −120 en catégorie A, avec une répartition de −50 vers B : A affiche −70 (−120 et la compensation de +50), B affiche −50.
  2. La transaction est reclassée en C : A affiche +50 (la compensation seule), B −50 et C −120. Le tableau de bord et les rapports comptent ces chiffres tels quels.
  3. À la réouverture, SplitAdjustmentModal (l. 49-52) ne reconnaît la compensation que par « même catégorie que le parent, signe opposé » : elle s'affiche comme une entrée ordinaire (A, 50).

Pourquoi ça compte davantage depuis #369

En Base, on répare en rouvrant la répartition, en retirant cette entrée puis en enregistrant. Depuis #369 (PR #452), la fenêtre de répartition est verrouillée en Gratuite, alors que le reclassement reste libre. Un utilisateur Gratuit qui reclasse une transaction déjà répartie (répartie avant cette release, ou avec une clé retirée depuis) crée l'écart sans pouvoir le réparer. Le cas est rare, mais l'écart est silencieux.

Pistes, à trancher à l'analyse

  • Propager la catégorie à la compensation dans updateTransactionCategory quand le parent est réparti, dans une même transaction (withTransaction).
  • Ou identifier la compensation explicitement plutôt que par sa catégorie (une colonne ou un rôle, donc une migration v18), et la faire lire ainsi par SplitAdjustmentModal.
  • Réparer ou signaler les bases où l'écart existe déjà : une compensation dont la catégorie diffère de celle de son parent.

Critères d'acceptation proposés

  • Reclasser une transaction répartie de A vers C déplace sa compensation avec elle : A ne garde rien de cette transaction, B garde −50 et C porte −70.
  • Un test de régression, rouge sur le code actuel, rejoue ce scénario.
  • Les bases déjà touchées sont réparées ou signalées.
## Constat Relevé par la revue de la PR #452 (commentaire 24129), hors de son diff, et confirmé à la lecture du code sur `main` `065f580` : - `updateTransactionCategory` (`src/services/transactionService.ts:301-315`) ne met à jour que la ligne parente (`UPDATE transactions SET category_id = $1 … WHERE id = $3`) ; - `saveSplitAdjustment` (l. 447-461) crée la ligne de compensation avec `parent.category_id`, c'est-à-dire la catégorie du parent au moment où la répartition est enregistrée, et le montant `-offsetTotal`. Reclasser ensuite le parent laisse donc la compensation dans l'ancienne catégorie. ## Reproduction Rejouée par le relecteur en SQLite sur `consolidated_schema.sql` : 1. Une transaction de −120 en catégorie A, avec une répartition de −50 vers B : A affiche −70 (−120 et la compensation de +50), B affiche −50. 2. La transaction est reclassée en C : A affiche +50 (la compensation seule), B −50 et C −120. Le tableau de bord et les rapports comptent ces chiffres tels quels. 3. À la réouverture, `SplitAdjustmentModal` (l. 49-52) ne reconnaît la compensation que par « même catégorie que le parent, signe opposé » : elle s'affiche comme une entrée ordinaire (A, 50). ## Pourquoi ça compte davantage depuis #369 En Base, on répare en rouvrant la répartition, en retirant cette entrée puis en enregistrant. Depuis #369 (PR #452), la fenêtre de répartition est verrouillée en Gratuite, alors que le reclassement reste libre. Un utilisateur Gratuit qui reclasse une transaction déjà répartie (répartie avant cette release, ou avec une clé retirée depuis) crée l'écart sans pouvoir le réparer. Le cas est rare, mais l'écart est silencieux. ## Pistes, à trancher à l'analyse - Propager la catégorie à la compensation dans `updateTransactionCategory` quand le parent est réparti, dans une même transaction (`withTransaction`). - Ou identifier la compensation explicitement plutôt que par sa catégorie (une colonne ou un rôle, donc une migration v18), et la faire lire ainsi par `SplitAdjustmentModal`. - Réparer ou signaler les bases où l'écart existe déjà : une compensation dont la catégorie diffère de celle de son parent. ## Critères d'acceptation proposés - [ ] Reclasser une transaction répartie de A vers C déplace sa compensation avec elle : A ne garde rien de cette transaction, B garde −50 et C porte −70. - [ ] Un test de régression, rouge sur le code actuel, rejoue ce scénario. - [ ] Les bases déjà touchées sont réparées ou signalées.
maximus added the
status:triage
type:bug
source:human
labels 2026-10-17 11:37:16 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#454
No description provided.