feat(gating): réserver le fractionnement de transactions à l’édition Base #369
Labels
No labels
autopilot:pending-human
source:analyste
source:defenseur
source:human
source:medic
status:approved
status:blocked
status:in-progress
status:needs-clarification
status:needs-fix
status:ready
status:review
status:triage
type:bug
type:feature
type:infra
type:refactor
type:schema
type:security
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: maximus/Simpl-Resultat#369
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Contexte
Décision de Max du 2026-10-03, prise pendant l'analyse de la-compagnie-maximus#180 (tableau comparatif des éditions sur la page produit) : le fractionnement de transactions (« Répartition » dans l'interface) fait partie de l'édition Base, avec les ajustements.
Aujourd'hui l'app ne le verrouille pas sur la page Transactions, alors que le texte d'incitation à l'achat le promet déjà dans Base :
upsell.features.adjustments, « Ajoutez des écritures manuelles et fractionnez des transactions sur plusieurs catégories » (fr.json:1240,en.json:1240). L'issue aligne donc le code sur une promesse existante ; elle ne change pas l'offre.Analyse (
/analyze, 2026-10-03,main0e4fef5)Prémisse confirmée, avec ces précisions :
TransactionsPage.tsx:102→TransactionTable.tsx:72,216,306-314→useTransactions.ts:318,336,351, non verrouillé ; etAdjustmentsPage.tsx:9-17,57-80, qui ouvre la mêmeSplitAdjustmentModalmais est déjà verrouillée par sa route (App.tsx:120). Aucun autre écran ne crée de fractionnement.transactions(parent_transaction_id,is_split, ligne enfant de compensation,transactionService.ts:386-458). Les rapports, le tableau de bord et le budget ne filtrent jamais sur ces colonnes : les fractionnements existants restent comptés quelle que soit l'édition. C'est conforme à l'ADR 0017 (L88 : « le gating bloque l'accès, jamais les données »).dataExportService.ts) conserveis_splitetparent_transaction_id: à laisser tel quel (Gratuite).docs/guide-utilisateur.md:13,150,160etfr.json/en.json:784,901décrivent la Répartition sans mention d'édition.Décision de Max (2026-10-03) : incitation pour toute ligne, icône gardée. En Gratuite, le bouton Répartition porte un cadenas et ouvre l'incitation à l'achat (« Obtenir Base ») au lieu de la fenêtre, que la ligne soit déjà fractionnée ou non. L'icône orange continue de signaler une ligne fractionnée. Les fractionnements existants restent en base et comptés. Écartés : une lecture seule de la fenêtre, et l'annulation permise en Gratuite.
Travail à faire
splitGate/isSplitLocked, sur le modèle desrc/shared/profileGate.ts) : verrouillé seulement siready && !allowedpouradjustments, viauseEntitlement(src/hooks/useEntitlement.ts:13). Pendant le chargement de l'édition, ni verrou ni fenêtre (commeRequireFeature).TransactionTable.tsx: en Gratuite, le bouton affiche un cadenas (motif « verrouillé, jamais masqué » deProfileFormModal.tsx:173-197) et ouvre une fenêtre qui enveloppe<UpsellGate feature="adjustments" requiredTier={requiredTierFor("adjustments")} onNavigate={close} />(modèleProfileSwitcher.tsx:148-165). La couleur orange derow.is_splitest conservée.docs/guide-utilisateur.md, sections Transactions et éditions) et docs intégrées (docs.*, FR et EN) : la Répartition est une fonction Base.CHANGELOG.mdetCHANGELOG.fr.md(Changed/Modifié) : la Répartition quitte l'édition gratuite, les répartitions existantes restent comptées.Surface de test
src/shared/profileGate.test.ts,src/shared/upsellCta.test.ts,src/services/entitlements.test.ts,src/components/shared/UpsellCtas.render.test.tsx(renderToStaticMarkup, environnement node, sans jsdom) ;src/__integration__/transactions-transfer-icon.test.tslit la source deTransactionTable.tsx. Aucun test deSplitAdjustmentModal.ready.SplitAdjustmentModal. Sinon, une vérification manuelle et une ligne dans la PR.Critères d'acceptation
npm testet la CI verts.Complexité estimée
Simple.
Liens
la-compagnie-maximus#180 (bloquée par cette issue et sa release) ; ADR 0017 ; #346 (
UpsellGate,onNavigate).