Règles — Budget
BR-BUDGET-001 — Plan budget de référence unique [DB]
BudgetPlan @@unique([userId, month])
La contrainte est une paire (userId, month). Dans l'implémentation actuelle, month est la constante "reference" — il n'y a donc qu'un seul plan budget par utilisateur.
Ce plan est un budget de référence mensuel (revenus et dépenses cibles), pas un budget par mois calendaire. La comparaison avec les transactions réelles se fait côté interface via le Sankey.
Si l'utilisateur n'a pas encore de plan, il est créé automatiquement à la première visite de la page Budget (getBudget() fait un create si aucun plan n'existe).
BR-BUDGET-002 — Synchronisation automatique de totalIncomeExpected [APP]
À chaque création, modification ou suppression d'une BudgetIncomeSource, la fonction syncTotalIncome() recalcule et met à jour BudgetPlan.totalIncomeExpected :
totalIncomeExpected = Σ incomeSources.expectedMonthly
Ce champ est donc toujours cohérent avec les sources de revenus — il n'est jamais saisi directement.
BR-BUDGET-003 — Calcul de targetPercent [CALC]
Lors de la création ou modification d'une BudgetAllocation, targetPercent est calculé automatiquement :
targetPercent = (targetAmount / totalIncomeExpected) × 100
Si totalIncomeExpected = 0, alors targetPercent = 0 (pas de division par zéro).
Ce pourcentage est utilisé dans le diagramme Sankey pour dimensionner les flux visuels.
BR-BUDGET-004 — Types de revenus [DB]
L'enum IncomeType définit les sources de revenus possibles :
| Valeur | Usage |
|---|---|
SALARY | Salaire fixe |
FREELANCE | Revenus freelance / indépendant |
REIMBURSEMENT | Remboursements (notes de frais, sécu…) |
INVESTMENT | Dividendes, intérêts, loyers |
OTHER | Autres revenus |
BR-BUDGET-005 — Types d'allocation [DB]
L'enum AllocationType définit les catégories de dépenses / épargne :
| Valeur | Usage |
|---|---|
FIXED_EXPENSE | Loyer, abonnements, charges fixes |
VARIABLE_EXPENSE | Courses, sorties, dépenses courantes |
SAVINGS | Versements épargne (Livret A, LEP…) |
INVESTMENT | Versements investissement (PEA, CTO, crypto…) |
BR-BUDGET-006 — Ownership du plan [APP]
Toute lecture ou écriture sur un BudgetPlan, BudgetIncomeSource ou BudgetAllocation vérifie que le plan appartient à l'utilisateur courant via prisma.budgetPlan.findFirst({ where: { id, userId } }).
BR-BUDGET-007 — Allocation liée à un compte [DB]
Une BudgetAllocation peut pointer vers un compte réel via linkedAccountId (optionnel). Ce lien est utilisé pour associer visuellement un flux du Sankey à un compte spécifique (ex. : l'allocation "Livret A" pointe vers le compte Livret A). La suppression du compte met linkedAccountId = null (onDelete: SetNull).