---
name: Fonctionnalité réinvestissements
description: Ajout de capital complémentaire sur un prêt en cours — architecture complète DB/backend/frontend
type: project
originSessionId: 680bfd99-577f-454e-b5b8-ea58460277f9
---
## Fonctionnalité : réinvestissements sur un investissement existant

Implémentée en mai 2026. Permet d'ajouter une ou plusieurs sommes complémentaires à un prêt en cours.

### Base de données
- Nouvelle table `reinvestissements` : `id`, `investissement_id` (FK cascade), `montant`, `date_reinvestissement`, `note`, `created_at`
- Index : `idx_reinv_inv ON reinvestissements(investissement_id, date_reinvestissement)`
- Migration dans `backend/src/db/index.js` (pattern habituel `CREATE TABLE IF NOT EXISTS`)
- `montant_investi` dans `investissements` reste l'initial — ne jamais le modifier pour un réinvestissement

### Backend
- Route : `backend/src/routes/reinvestissements.js` — GET (liste par investissement_id), POST, DELETE
- Montée dans `server.js` : `app.use('/api/reinvestissements', requireAuth, reinvestissementsRouter)`
- GET `/api/investissements/:id` retourne maintenant `reinvestissements`, `reinvestissements_total`, `capital_total`
- GET `/api/investissements/` retourne `reinvestissements_total` et `capital_total` (subqueries SQL)

### Logique de simulation (`backend/src/utils/schedule.js`)
- Nouvelle fonction exportée : `generateSimulWithReinvestissements(db, investissementId)`
  - Génère le planning complet en appliquant le capital cumulatif période par période
  - Appelée à chaque POST/DELETE sur `/api/reinvestissements`
- `adjustSimulForActuals` **modifiée** pour tenir compte des réinvestissements :
  - Calcule `capitalAtLastDate = montant_investi + reinvestissements jusqu'à la date du dernier remb`
  - Les réinvestissements futurs (après dernière date remb) gonflent progressivement les périodes suivantes
  - Si aucun capital remboursé → bifurque vers `generateSimulWithReinvestissements` si des reinvests existent

**Why:** `adjustSimulForActuals` est appelée après chaque saisie de remboursement. Sans cette modification, elle recalculait la projection sur `montant_investi` seul, ignorant les réinvestissements.

### `remboursements.js` — `syncInvestissementStatut`
- Corrigé pour utiliser `capitalTotal = montant_investi + SUM(reinvestissements)` au lieu de `montant_investi` seul
- Évite de passer le statut à "rembourse" trop tôt quand du capital réinvesti reste dû

### Frontend (`InvestissementDetail.jsx`)
- Bouton "Réinvestir" dans la topbar (même style qu'Exporter)
- Modal de saisie : montant + date + note optionnelle
- Tableau récapitulatif conditionnel (affiché uniquement si reinvests > 0) avec colonne "capital cumulé" et suppression inline
- KPI "Montant investi" → "Capital total investi" si reinvests, avec sous-libellé "Initial X + Y réinvesti"
- XIRR : chaque réinvestissement est un flux sortant supplémentaire `{ amount: -montant, date }`

### `Investissements.jsx` (liste)
- Remplace `r.montant_investi` par `(r.capital_total ?? r.montant_investi)` dans les agrégats KPI, par-plateforme, tableau et export Excel
- Rétro-compatible : fallback sur `montant_investi` si pas de reinvests

**How to apply:** Toute future page affichant le capital d'un investissement doit utiliser `capital_total` (depuis l'API) plutôt que `montant_investi` brut.
