20 KiB
20 KiB
MEMORY.md — Crowdlending App
- Profil utilisateur — Olivier, propriétaire de l'app crowdlending, développeur qui pilote les évolutions
- Modèle plateforme — détenteur & logo — Champs investisseur_id, date_ouverture, logo_filename ajoutés aux plateformes ; contrainte UNIQUE modifiée
- Pattern investisseurForPlat — Helper à créer dans chaque page formulaire pour synchroniser le détenteur avec la plateforme choisie
- Fonctionnalité réinvestissements — Table reinvestissements, route /api/reinvestissements, capital_total, generateSimulWithReinvestissements, adjustSimulForActuals modifiée
- adjustSimulForActuals — règles complètes — Capital effectif, capital soldé (DELETE futures), reprocess doit appeler adjustSimulForActuals après transaction
- Calcul solde porte-monnaie — Formule complète : dépôts − retraits_manuels + net_recu_portefeuille + bonus − capital_investi ; implémentée backend (dashboard.js) et frontend (DepotsRetraits.jsx)
- Pattern multiDetenteur — Le détenteur ne s'affiche dans les selects plateforme que si plusieurs détenteurs distincts existent (
new Set(plats.map(p => p.investisseur_id)).size > 1) - Fonctionnalité corrections de solde — Table corrections_solde, route /api/corrections, CorrectionModal dans DepotsRetraits, badge dans Remboursements, intégration fiscal2778
- Troncature et corruption fichiers — toujours passer par Python — Edit/Write et sed -i tronquent les fichiers volumineux ; jamais sed, toujours python3 + vérifier tail/hex
- Composant ConfirmModal et suppressions — ConfirmModal.jsx créé ; pattern standard pour toute future suppression ; 6 fichiers déjà migrés
- Correction intérêts nets — Investissements — interets_nets_total ajouté au backend ; net_recu_total ≠ intérêts nets (inclut capital+cashback)
- Fiscalité locale sur remboursements — Champs interets_bruts_avant_local et taxe_locale ajoutés (DB + backend + 2 formulaires + tableau détail)
- Page Centre d'aide — Route /aide, layout Settings, FAQ accordéon ; bouton dans UserMenu
- Menus ⋮ actions sur les tableaux et blocs — Pattern menu contextuel fixe (position: fixed + backdrop + icônes SVG) ; scroll ferme les menus ; AdminPlateformes ajouté
- Format menu ⋮ — règle obligatoire — Tout nouveau tableau doit utiliser le menu ⋮ avec icônes SVG + label, jamais de boutons inline
- Logo plateforme topbar InvestissementDetail — logo remplace le nom si disponible ; plateforme_logo retourné par le backend ; classe logo-plateforme pour dark mode
- onClick direct avec paramètre par défaut — onClick={fn} passe l'event comme arg1, écrase les defaults ; toujours utiliser onClick={() => fn()}
- Réinvestissement automatique des intérêts — auto_reinvest sur investissements, source sur reinvestissements, déclencheur POST remboursement, tabs Manuel/Auto dans la modale
- Panneau détail unifié DepotsRetraits — DetailPanel unifié dépôts/retraits/corrections ; libellé bouton adapté au type ; props { row, onEdit, onDeleteCorrection }
- Menu ⋮ carte Informations du projet — cardMenu state séparé ; Modifier/Réinvestir/Exporter/Supprimer + Désactiver auto-reinvest ; utiliser ConfirmModal pas confirmingInvDelete
- Méthode de remboursement sur investissements — methode_remboursement + nom_compte_courant sur investissements ; champ conditionnel si plateforme=choix_investisseur ; retrait auto depots_retraits ; affichage fiche détail
- Override fiscalité par investissement — fiscalite_override='exonere' ; badge + menu ⋮ + modale confirmation ; prelev indicatifs (pas forcés à 0) ; voir project_istaxindicatif
- Règle isTaxIndicatif + route reprocess — prelev toujours calculés, net_recu = brut si indicatif ; POST /api/remboursements/reprocess ; bouton dans MonCompte?section=nettoyage
- Fallback methode remboursement formulaire — openRembFromSimul/openNewRemb : utiliser inv.methode_remboursement si plateforme=choix_investisseur, jamais 'portefeuille' en dur
- Formulaires remboursement refactorisés — Grille 3 col / 900px, sections Remboursement/Imposition/Versement, Total prélèvements, commentaire Montant versé, isIndicatif aligné
- Tableau Remboursements enregistrés — Fusion PS+IR→Imposition, tooltip CSS instantané (.cell-tooltip), remb-table CSS, clic ligne → modale édition
- Graphiques Dashboard — barres + donut — InteretsMensuelsChart (barres empilées) + InteretsDonutChart (donut caps arrondis) + InteretsChartContext partagé ; mode TOUT (vue multi-années) ; layout 2/3+1/3 stretch
- Donut interactif — tooltip, clic, mémoire, légende — Tooltip SVG, clic isole un type ou Reçu/Projeté, retour arrière via centre (↩), légende cliquable, ordre Intérêts→Capital→Cashback
- YearSelectorKpi — sélecteur année Dashboard — Card violet/indigo sur la ligne KPI, dropdown custom années croissant + "Depuis le début", sync bidirectionnelle avec InteretsChartContext
- Couleurs personnalisables des graphiques — UiContext : cl_chart_interets/capital/cashback ; Settings > Apparence : palette MD2, PaletteSelector, ChartColorPicker, preview Reçu/Projeté (lightenColor 72%)
- Préférences utilisateur en DB — Table user_preferences (user_id, key, value) ; route /api/preferences GET+PATCH ; UiContext sync DB→localStorage au montage, PATCH asynchrone
- Bibliothèque d'icônes — Tables app_icons + history, route /api/icons, section Admin, nettoyage fond SVG, composant AppIcon dans Settings
- InvestissementDetail — nouvelles fonctionnalités — Menu simulMenu : modifier DPE + traitement en masse remboursements ; correction ConfirmModal rowDeleteConfirm manquant dans le JSX
- PUT investissements — payload minimal — Ne jamais spread
inv; construire le payload champ par champ selon le schéma Zod backend - KPIs Dashboard — TrendBadge, logique M vs M-1 — 5 KPIs refaits ; année N = mois courant vs M-1 ; année N-x = annuel vs N-1 ; modeGlobal = cumul sans badge
- Tableau intérêts par plateforme — TableauInteretsPlateforme.jsx dans Dashboard ; endpoint /api/dashboard/interets-par-plateforme ; synchronisé InteretsChartContext
- Capital investi — formule unifiée — montant_investi + reinvests(≤date) − capital_remboursé(≤date) ; dashboard.js + Investissements.jsx + InvChart
- Timezone — ne pas utiliser .toISOString() pour dates locales —
.toISOString().split('T')[0]décale d'un jour en UTC+1 ; toujours getFullYear/getMonth/getDate - Vision mensuelle — capital par plateforme/mois — CapitalMensuelTable.jsx, onglet entre Plateformes et Investissements, calcul frontend, classes tip-table
- Exonération fiscale sur comptes — Colonne exoneration_fiscale (aucune/pfnl_5ans) sur table comptes ; DB+backend+frontend Settings
- Vision mensuelle — dépôts/retraits par plateforme/mois — DepotsMensuelTable.jsx, onglet entre Plateformes et Mouvements dans DepotsRetraits, filtres icônes dépôt/retrait
- UX formulaires Investissement & Remboursement — Pas de présélection plateforme/investissement ; détenteur masqué (auto) ; taux/durée/DPE requis
- UserMenu — portail React obligatoire — Popup et sous-panel via createPortal(…, document.body) pour échapper au stacking context de la sidebar sticky
- TableauInteretsPlateforme — padding wrapper — Envelopper dans
<div style={{ padding: '0 24px' }}>dans chaque page (Dashboard, Remboursements) - Toggle Détaillé/Consolidé tableaux mensuels — Bouton dans th Plateforme, clé localStorage
cl_tip_group_by_nom, sur 4 composants ; mergeMaps pour TableauInteretsPlateforme - Icônes bibliothèque — sidebar & titres pages — NavIcon dans Layout.jsx (24px, fallback SVG) ; PageIcon inline dans h2 (40px, cache module-level) ; 5 pages équipées
- Règle icônes topbar — ne pas modifier flex — Toujours insérer PageIcon comme img inline dans le h2, jamais de wrapper div ni display:flex sur le h2
- Pagination listes — Hook usePagination + composant Pagination ; 15/25/50/100 items, localStorage par page, reset sur filtre
- Export Excel SheetJS — xlsx installé dans frontend/ ; pattern json_to_sheet → book_append_sheet → write type:array ; MIME xlsx
- TrendBadge KPIs Investissements — TrendBadge sur les 5 KPIs ; platYear initialisé à l'année courante ; effectiveYear pour badges en vue "Toutes les années"
- TrendBadge KPIs DepotsRetraits + Remboursements — Même pattern déployé sur DepotsRetraits (4 KPIs) et Remboursements (3 KPIs)
- Page Fiscalité — refonte TaxReport — Fiscal2778→TaxReport, route /taxreport, onglets dr-tabs, pagination détail, YearSelector violet autonome
- Simulation CERFA 2561 — Cerfa2561Preview.jsx, onglet inline TaxReport, cases 2TT/2TR/2BH/2CK/2TY, type_produit_fiscal sur plateformes, impression PDF
- FK compte_id sur investissements et remboursements — DB+backend+4 formulaires frontend ; resolvedMethode depuis plateforme ; auto-sélection premier compte_courant ; colonne Versement dans Remboursements
- Déclaration 2778-SD et PFO — Onglet TaxReport conditionné par pfoAssujetti ; matrice mensuelle par plateforme étrangère ; simulation CERFA cases BA/IA/PQ/PV/PF1/PG1/QR ; report 2042 (2TR/2BH/2CK) ; taux dynamiques depuis taux_pfu (csg/crds/solidarite)
- Architecture onglets fiscaux — 2042 / 2561 / 2778-SD — Cerfa2042Preview (nouveau) + refonte 2561 et 2778-SD : sidebar 3 vues, suivi mensuel combiné, données 2042 mixtes avec badges auto/à déclarer, fullName helper, route /taxreport/2778 reconstruite
- Référentiel taux crédit d'impôt 2047 — Table taux_credit_impot (124 pays), route /api/taux-credit-impot, section Admin "Référentiels" avec TciModal, TciImportBlock, TciPromptBlock
- Pièges CSS — fieldset min-width et checkbox width — fieldset : toujours minWidth:0 ; input[type=checkbox] : toujours width:'auto'
- Référentiel plateformes — architecture complète — Tables referentiel + categories + notation, HERITABLE_FIELDS, routes push/reset/lier/importer, similarité Levenshtein 80%, frontend Settings + Admin
- Bibliothèque logos référentiel — Section Admin "Logos des plateformes" (id: logos-ref) ; POST/DELETE /api/referentiel/:id/logo ; auto-push logo_filename ; placeholder croix si logo manquant ; useRef pas React.useRef dans Admin.jsx
- Recherche/filtres/pagination référentiel — Recherche nom + filtre domiciliation + filtre catégorie + pagination dans ReferentielSection ; icone_filename prioritaire sur logo_filename, tous deux servis via /api/logos/
- Catégories & secteurs d'investissement — Tables categories_inv/secteurs_inv, routes ref-categories/ref-secteurs, fusion, chips dans PlatformeProfile et RefModal, filtre référentiel via ?filterCat=
- Catégories/secteurs utilisateur — deux niveaux — user_id sur categories_inv/secteurs_inv, tables jonction plateforme+investissement, routes /api/categories-inv et /api/secteurs-inv, push admin étendu, sync auto investissements, chips formulaires, filtres liste
- Domiciliation → codes ISO pays — Migration complète : Zod string libre, DB 'france'→'FR', sentinel partout, CountrySelect intégré, DOMICILIATION_LABELS supprimé, badges hérité + ConfirmModal reset
- ResultBanner — règle bannières succès/erreur — Toujours utiliser ResultBanner (× à droite, auto-dismiss 4s) ; result toujours { ok, msg } ; redirect via onDismiss si besoin
- Tags suggérés admin — catégories/secteurs — Section inv-suggestions dans /admin/plateformes ; 6 routes backend ; bouton compteur dans RefListSection ; promouvoir/supprimer
- ProfilImportBlock — import IA avec tags inconnus — Flow 3 étapes (json→creation→diff) ; resolveTags Levenshtein≤2 ; création tags approuvés avant PUT ; categories_inv_ids/secteurs_inv_ids dans payload
- Sauvegarde ZIP référentiel — zip.js pur Node (no deps) ; 3 routes export/import ; api.blob() ; boutons ReferentielSection ; images incluses ; tags résolus par nom
- Express — ordre des routes statiques vs /:id — Routes statiques (/export, /import-zip) TOUJOURS avant /:id ; vérifier avec grep après toute insertion
- Héritage catégories/secteurs — merge — Tags référentiel fusionnés dans les plateformes (is_inherited) ; InvSelect.inheritedIds ; associations-inv.js re-ajoute les inherited IDs au PUT ; compteur bandeau séparé des scalaires
- Admin sous-pages — structure — AdminPlateformes (garanties + notation référentiel) ; AdminFiscalite (PfuSection + TauxCreditImpotSection) ; pattern account-layout
- Settings NAV — structure actuelle — 4 groupes : Interface / Mon paramétrage / Mes tags / Mes données ; membres+nettoyage déplacés de MonCompte vers Settings ; MonCompte réduit à profil+securite
- Refactorisation Settings.jsx + Admin.jsx — Découpés en composants autonomes (pages/settings/ et pages/admin/) ; imports manquants fréquents ; bugs d'extraction documentés
- Page Plateformes — /plateformes : vue par plateforme, 4 onglets, simul/all endpoint, sélecteurs TIP identiques, grisage tip-td-closed
- Grisage cellules hors-période tip-table — .tip-td-closed pour mois avant souscription ou après dernier remb (rembourse) ; tip-col-current prioritaire
- Anti-doublon projection mois courant —
real === 0requis avant d'ajouter projAmt dans buildCellValue ; corrigé dans Plateformes + TableauInteretsPlateforme - DrillCellPanel Dashboard + navigation croisée — Panel permanent mois courant sur Dashboard ; clic ligne → Remboursements (URL params) + auto-ouverture modal + retour Dashboard avec drill restauré
- Déploiement Docker — pièges et corrections — DATA_DIR env, fallthrough:false logos, nginx upstream name, Traefik @file, volume seed icons, deploy.sh
- Sidebar overlay — couleur parasite au survol —
background: transparent !important+ appearance:none sur .sidebar-expand-overlay et ses états hover/focus/active ; effet visuel via filter:brightness sur le logo uniquement - Safari mobile — viewport et dvh — Toujours doubler height:100vh + height:100dvh ; utiliser visualViewport.height au lieu de innerHeight en JS ; écouter visualViewport resize+scroll pour les menus fixed
- Auth email — vérification, reset, pages layout — smtp_config table, email_verified sur users, tokens vérification/reset, pages ForgotPassword/ResetPassword/VerifyEmail, MonCompte badges
- 2FA — TOTP + email OTP + appareils de confiance — totp_secret/totp_enabled sur users, tables two_fa_*, routes /2fa/setup|confirm-setup|disable|send-email-code|verify, trusted-devices CRUD, Login 3 étapes, TwoFASection + TrustedDevicesSection dans MonCompte
- otplib ESM — API fonctionnelle uniquement — Pas d'export
authenticator; utilisergenerateSecret,generateURI,verifySyncimportés nommément depuis 'otplib' - db/index.js — export default en double — Un
export default dbexiste en milieu de fichier (~ligne 942) ; toujours vérifier avec grep avant d'ajouter des migrations en fin de fichier - Suppression détenteur — réassignation au principal — DELETE investisseur réassigne investissements/depots_retraits/plateformes/comptes au principal avant delete ; toute nouvelle table CASCADE doit être ajoutée à la transaction
- Export / Restore prod→dev — ZIP DB+assets, stockage serveur max 10, upload externe, restauration pending-restore+process.exit, job 3h00 (autoExport.js), ExportSection.jsx
- SQLITE_CORRUPT — VACUUM INTO obligatoire — db.backup() produit un fichier WAL-mode incomplet → toujours VACUUM INTO ; valider avec integrity_check avant d'écrire le pending-restore
- Formule montant versé + style champs calculés — montantRembourse conditionnel isIndicatif (bruts si étranger/exonéré, netRecu si flat_tax) ; champs readonly : var(--surface-2)+var(--text-muted), jamais var(--bg-input-readonly)
- Affichage projections — montants barrés & échéances non tenues — matchRembsAll somme tous les rembs du mois ; barré+réel si différence >0,01€ ; "✗ Échéance non tenue" rouge si passé sans paiement
- Bug prêt différé — recalcul date_premiere_echeance — Passage à 'differe' doit toujours recalculer DPE si duree_mois présent ; validation dans submit ; label dynamique du champ
- DrillCellPanel — filtrage lignes à 0 — recusVisible/projetesVisible filtrent les lignes à 0 selon critères actifs ; compteur X/Y si lignes cachées
- CSS tip-table + DrillCell mode consolidé — tip-th-name violet comme year ; bug consolidé : _ids[] dans merge, platIds dans onCellClick, plateforme_ids CSV au backend
- Système de notifications — Table notifications, 8 types (system/ticket_reply/info/team/success/warning/security/announcement), cloche topbar polling 30s, page /notifications, event notif:refresh pour rechargement immédiat
- Audience des notifications — règle obligatoire — Toujours demander si la notif doit être vue par tous les admins (notifyAdmins) ou un utilisateur spécifique (notifyUser) avant d'implémenter
- Page Communication — tickets & notifications — Architecture 3 volets, filtres chips multi-select, dropdowns portal, droits, jobs autoCleanNotifs + autoTicketStatus, pièges React (is_admin=0, msg-img-wrap)