/** * fix_dates_cible.mjs * Corrige les date_cible aberrantes (>2100) en recalculant date_souscription + duree_mois * et régénère les simul_remboursements correspondantes. * Usage : node fix_dates_cible.mjs */ import Database from 'better-sqlite3'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { generateSimul } from './src/utils/schedule.js'; const __dirname = path.dirname(fileURLToPath(import.meta.url)); const DB_PATH = process.env.DB_PATH || path.resolve(__dirname, 'data/crowdlending.db'); const db = new Database(DB_PATH); db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON'); function addMonths(isoDate, months) { const [y, m, d] = isoDate.split('-').map(Number); const dt = new Date(Date.UTC(y, m - 1 + months, d)); return dt.toISOString().slice(0, 10); } const rows = db.prepare(` SELECT i.id, i.nom_projet, p.nom AS plateforme, i.date_souscription, i.date_cible, i.duree_mois, i.montant_investi, i.taux_interet, i.type_remb, i.freq_interets, i.date_premiere_echeance, i.date_debut_simul, i.echeance_fin_de_mois FROM investissements i JOIN plateformes p ON p.id = i.plateforme_id WHERE i.statut IN ('en_cours','en_retard','procedure') AND i.type_remb = 'differe' AND i.date_cible > '2100-01-01' `).all(); console.log(`${rows.length} investissements à corriger\n`); const update = db.prepare(`UPDATE investissements SET date_cible=?, updated_at=datetime('now') WHERE id=?`); const fix = db.transaction(() => { for (const row of rows) { const newDate = addMonths(row.date_souscription, row.duree_mois); update.run(newDate, row.id); console.log(`[${row.id}] ${row.plateforme} — ${row.nom_projet}`); console.log(` ${row.date_cible} → ${newDate}`); generateSimul(db, { id: row.id, montant_investi: row.montant_investi, taux_interet: row.taux_interet, duree_mois: row.duree_mois, type_remb: row.type_remb, freq_interets: row.freq_interets, date_premiere_echeance: row.date_premiere_echeance, date_debut_simul: row.date_debut_simul, date_souscription: row.date_souscription, echeance_fin_de_mois: row.echeance_fin_de_mois ?? 0, }); console.log(` ✓ simulation régénérée`); } }); fix(); console.log('\nTerminé.'); db.close();