path = "backend/src/db/index.js" with open(path, "r", encoding="utf-8") as f: content = f.read() # Liste des 12 lignes à corriger : (nom, ancien texte exact regime_fiscal, nouveau texte) FIXES = [ ('Compte courant rémunéré', 'Flat tax 30 %', 'Flat tax (PFU)'), ('Compte rémunéré nouvelle génération (fintech)', 'Flat tax 30 %', 'Flat tax (PFU)'), ('Livret bancaire non réglementé', 'Flat tax 30 % (ou option barème)', 'Flat tax (PFU) ou option barème'), ('Compte à terme (CAT)', 'Flat tax 30 % (ou option barème)', 'Flat tax (PFU) ou option barème'), ('Compte-titres ordinaire (CTO)', "Flat tax 30 % (ou option barème), pas d'avantage fiscal", "Flat tax (PFU) ou option barème, pas d'avantage fiscal"), ('Crowdfunding immobilier', 'Fiscalité classique sur les intérêts (flat tax 30 % ou barème)', 'Fiscalité classique sur les intérêts (flat tax / PFU, ou option barème)'), ('Compte crypto (exchange)', "Flat tax 30 % sur les plus-values de cession (particuliers), déclaration 2086", "Flat tax (PFU) sur les plus-values de cession (particuliers), déclaration 2086"), ('Wallet crypto (auto-conservation)', "Flat tax 30 % sur les plus-values de cession (particuliers), déclaration 2086", "Flat tax (PFU) sur les plus-values de cession (particuliers), déclaration 2086"), ('Métaux précieux physiques', "Taxe forfaitaire sur les métaux précieux (11 %), ou option pour le régime des plus-values sur biens meubles si justificatifs d'achat", "Taxe forfaitaire sur les métaux précieux, ou option pour le régime des plus-values sur biens meubles si justificatifs d'achat"), ('Objets de collection', "Taxe forfaitaire sur les objets d'art/collection/antiquité (6 %), ou option pour le régime des plus-values sur biens meubles si justificatifs d'achat", "Taxe forfaitaire sur les objets d'art/collection/antiquité, ou option pour le régime des plus-values sur biens meubles si justificatifs d'achat"), ('Participation directe non cotée (startups/PME)', "Flat tax 30 % sur les plus-values (ou barème) ; réduction d'IR à l'entrée possible sous conditions (IR-PME/Madelin)", "Flat tax (PFU) sur les plus-values (ou option barème) ; réduction d'IR à l'entrée possible sous conditions (IR-PME/Madelin)"), ('Wallet crypto (conservation par un tiers)', "Flat tax 30 % sur les plus-values de cession (particuliers), déclaration 2086", "Flat tax (PFU) sur les plus-values de cession (particuliers), déclaration 2086"), ] # 1) Réécriture du texte source, ligne par ligne (chaque ligne contient "nom: ''," ce qui la # rend unique même quand deux lignes partagent le même ancien texte regime_fiscal). lines = content.split("\n") touched = {nom: False for nom, _, _ in FIXES} for i, line in enumerate(lines): for nom, old_txt, new_txt in FIXES: needle_nom = f"nom: '{nom}'" if needle_nom in line and old_txt in line and not touched[nom]: assert line.count(old_txt) == 1, f"{nom}: old_txt found {line.count(old_txt)} times on its line" lines[i] = line.replace(old_txt, new_txt, 1) touched[nom] = True break missing = [nom for nom, ok in touched.items() if not ok] assert not missing, f"lignes non trouvées pour : {missing}" content = "\n".join(lines) # 2) Bloc de backfill toujours exécuté (INSERT OR IGNORE ne corrige pas le texte des lignes déjà # présentes) : UPDATE ... WHERE nom = ? AND regime_fiscal = '' — ne touche # jamais une ligne dont regime_fiscal a été modifié manuellement (le texte ne matchera plus). anchor = "\nexport default db;\n" assert content.count(anchor) == 1, f"anchor count={content.count(anchor)}" backfill_stmts = [] for nom, old_txt, new_txt in FIXES: nom_js = nom.replace("\\", "\\\\").replace("'", "\\'") old_js = old_txt.replace("\\", "\\\\").replace("'", "\\'") new_js = new_txt.replace("\\", "\\\\").replace("'", "\\'") backfill_stmts.append( " db.prepare(\n" " \"UPDATE enveloppes_referentiel SET regime_fiscal = ?, updated_at = datetime('now') \" +\n" " \"WHERE nom = ? AND regime_fiscal = ?\"\n" f" ).run('{new_js}', '{nom_js}', '{old_js}');" ) block = ( "\n" "// Correctif du 27/09/26 (demande Olivier : \"Tu alimente la description avec un flat tax à\n" "// 30%, mais ce n'est plus vrai en 2026... évite de mettre le taux actuel qui peut varier\") —\n" "// les taux d'imposition précis (flat tax 30 %, taxes forfaitaires 11 %/6 %...) changent dans\n" "// le temps et rien ici ne les tient à jour : les textes ci-dessus (SEED_ENVELOPPES /\n" "// EXTRA_ENVELOPPES) ont été réécrits pour décrire le MÉCANISME fiscal (flat tax/PFU, taxe\n" "// forfaitaire...) sans figer de pourcentage. Comme INSERT OR IGNORE ne corrige pas le texte\n" "// d'une ligne déjà présente, ce backfill patche les installations déjà seedées — toujours\n" "// exécuté, guardé par l'ancien texte exact pour ne jamais écraser une modification manuelle\n" "// faite depuis l'admin (même principe que le backfill des plafonds CEL/PEL).\n" "{\n" + "\n".join(backfill_stmts) + "\n" "}\n" "\nexport default db;\n" ) content = content.replace(anchor, block, 1) with open(path, "w", encoding="utf-8") as f: f.write(content) print("Regime fiscal genericization + backfill inserted OK, new length:", len(content))