Implémentation de la feature "suivi des objectifs"
This commit is contained in:
1 parent
6e03195d3a
commit
1060bfe2be
14 files changed
+1844
-192
No files matched your search
+46
-5
@@ -2227,23 +2227,64 @@ console.log('[DB] Migrations 2FA OK');
|
||||
}
|
||||
|
||||
// ── Migration : table objectifs ──────────────────────────────────────────
|
||||
// Objectifs annuels par investisseur. `type` permet de réutiliser la table
|
||||
// pour d'autres natures d'objectifs plus tard (ex: 'rendement_annuel') —
|
||||
// pour l'instant seul 'versement_annuel' (objectif de dépôts nets) est utilisé.
|
||||
// Objectifs annuels. `type` permet plusieurs natures d'objectifs dans la même
|
||||
// table : 'versement_annuel' (enveloppe globale de dépôts, par investisseur,
|
||||
// plateforme_id NULL) et 'capital_investi' (cible de capital investi pour une
|
||||
// plateforme donnée, par investisseur + plateforme). plateforme_id est NULL
|
||||
// pour 'versement_annuel', renseigné pour 'capital_investi'. Deux index
|
||||
// uniques partiels (au lieu d'un seul UNIQUE inline) car SQLite considère
|
||||
// deux NULL comme distincts : un UNIQUE(investisseur_id,type,annee) global
|
||||
// n'empêcherait pas plusieurs lignes capital_investi (une par plateforme)
|
||||
// pour le même investisseur/année — cf. section Paramétrage > Fixation des
|
||||
// objectifs.
|
||||
db.exec(`
|
||||
CREATE TABLE IF NOT EXISTS objectifs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
investisseur_id INTEGER NOT NULL REFERENCES investisseurs(id) ON DELETE CASCADE,
|
||||
plateforme_id INTEGER REFERENCES plateformes(id) ON DELETE CASCADE,
|
||||
type TEXT NOT NULL DEFAULT 'versement_annuel',
|
||||
annee INTEGER NOT NULL,
|
||||
montant REAL NOT NULL,
|
||||
notes TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
UNIQUE(investisseur_id, type, annee)
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
)
|
||||
`);
|
||||
|
||||
// Migration pour les bases existantes créées avant plateforme_id : recrée la
|
||||
// table (ALTER TABLE ne permet pas de changer une contrainte UNIQUE inline).
|
||||
{
|
||||
const objCols = db.prepare('PRAGMA table_info(objectifs)').all().map(c => c.name);
|
||||
if (!objCols.includes('plateforme_id')) {
|
||||
db.exec('PRAGMA foreign_keys = OFF');
|
||||
db.exec('ALTER TABLE objectifs RENAME TO objectifs_old_migration');
|
||||
db.exec(`
|
||||
CREATE TABLE objectifs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
investisseur_id INTEGER NOT NULL REFERENCES investisseurs(id) ON DELETE CASCADE,
|
||||
plateforme_id INTEGER REFERENCES plateformes(id) ON DELETE CASCADE,
|
||||
type TEXT NOT NULL DEFAULT 'versement_annuel',
|
||||
annee INTEGER NOT NULL,
|
||||
montant REAL NOT NULL,
|
||||
notes TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
|
||||
)
|
||||
`);
|
||||
db.exec(`
|
||||
INSERT INTO objectifs (id, investisseur_id, plateforme_id, type, annee, montant, notes, created_at, updated_at)
|
||||
SELECT id, investisseur_id, NULL, type, annee, montant, notes, created_at, updated_at
|
||||
FROM objectifs_old_migration
|
||||
`);
|
||||
db.exec('DROP TABLE objectifs_old_migration');
|
||||
db.exec('PRAGMA foreign_keys = ON');
|
||||
}
|
||||
}
|
||||
|
||||
db.exec('CREATE INDEX IF NOT EXISTS idx_objectifs_investisseur ON objectifs(investisseur_id, type, annee)');
|
||||
db.exec('CREATE INDEX IF NOT EXISTS idx_objectifs_plateforme ON objectifs(plateforme_id, type, annee)');
|
||||
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_objectifs_global_uniq ON objectifs(investisseur_id, type, annee) WHERE plateforme_id IS NULL');
|
||||
db.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_objectifs_plateforme_uniq ON objectifs(plateforme_id, type, annee) WHERE plateforme_id IS NOT NULL');
|
||||
|
||||
// ── Migration : suivi anti-doublon des notifications "données incomplètes" ──
|
||||
// Stocke la signature (liste triée des champs essentiels manquants) au moment
|
||||
|
||||
Reference in new issue
Block a user