Gestion des Thèmes

This commit is contained in:
ocroguennec committed 2026-09-06 18:59:09 +02:00
1 parent bab7a79b63
commit be3c93897b
24 files changed
+1041 -141

No files matched your search

+73 -7
View File
@@ -22,11 +22,11 @@ const PENDING_RESTORE = DB_PATH + '.pending-restore';
// générées côté dev (api_keys, y compris les clés internes auto-provisionnées
// pour l'assistant IA), écrase la configuration des fournisseurs IA propres
// à dev (ai_providers/ai_config) par celle de la source restaurée, et
// écraserait de la même façon l'étiquette d'environnement de cette instance
// (parametres_environnement — Admin > Général, cf. 05/09/26) par celle de la
// source restaurée. Ordre important : ai_config référence ai_providers (FK
// provider_defaut_id).
const ENV_LOCAL_TABLES = ['api_keys', 'ai_providers', 'ai_config', 'parametres_environnement'];
// écraserait de la même façon l'étiquette d'environnement (parametres_environnement)
// et le thème de couleur (parametres_theme — Admin > Général, cf. 05/09/26)
// de cette instance par ceux de la source restaurée. Ordre important :
// ai_config référence ai_providers (FK provider_defaut_id).
const ENV_LOCAL_TABLES = ['api_keys', 'ai_providers', 'ai_config', 'parametres_environnement', 'parametres_theme'];
let pendingRestorePreserve = null;
if (fs.existsSync(PENDING_RESTORE) && fs.existsSync(DB_PATH)) {
try {
@@ -42,7 +42,7 @@ if (fs.existsSync(PENDING_RESTORE) && fs.existsSync(DB_PATH)) {
}
oldDb.close();
} catch (e) {
console.error('[restore] Échec de la sauvegarde des tables locales (api_keys/ai_providers/ai_config/parametres_environnement) avant restauration :', e.message);
console.error('[restore] Échec de la sauvegarde des tables locales (api_keys/ai_providers/ai_config/parametres_environnement/parametres_theme) avant restauration :', e.message);
pendingRestorePreserve = null;
}
}
@@ -1847,6 +1847,72 @@ db.exec(`
`);
db.exec(`INSERT OR IGNORE INTO parametres_environnement (id) VALUES (1)`);
// ── Migration : thème de couleur de l'interface (Admin > Général) ───────────
// Demande Olivier 05/09/26 : teinte de l'interface (menus, boutons — distincte
// du mode clair/sombre existant, cf. ThemeContext.jsx) choisie parmi une
// liste de préréglages (frontend/src/styles.css, blocs [data-color-theme]),
// appliquée à TOUS les utilisateurs (contrairement au mode clair/sombre, une
// préférence par utilisateur). But d'Olivier : garder Production dans le
// bleu par défaut mais donner aux autres environnements une couleur
// différente, reconnaissable au premier coup d'œil. Table dédiée (même
// raisonnement que parametres_environnement ci-dessus) et ajoutée à
// ENV_LOCAL_TABLES : ne doit jamais être réécrite par une restauration.
//
// 05/09/26 (suite, même jour) : les 5 thèmes initiaux (bleu/vert/violet/
// orange/bordeaux, couleurs choisies librement) sont remplacés par 10,
// alignés sur les 10 palettes de graphiques de Settings > Apparence
// (cf. project_chart_colors.md) — chaque thème reprend la TEINTE de la
// couleur "Intérêts" de la palette correspondante (même méthode de rotation
// que les 5 thèmes initiaux : S/L de chaque jeton CSS inchangés, seule la
// teinte tourne). SQLite ne permet pas d'altérer un CHECK constraint : la
// table doit être recréée, même stratégie que les migrations perte_definitive/
// prolongation sur investissements plus loin dans ce fichier. Valeur existante
// migrée : 'violet' reste 'violet' (même nom, teinte recalculée depuis la
// palette) ; tout le reste (bleu/vert/orange/bordeaux) retombe sur 'classique'
// — décision explicite d'Olivier pour son propre 'bordeaux' actif, généralisée
// à toute valeur historique sans successeur direct parmi les 10 palettes.
{
const NEW_COLOR_THEMES = ['classique', 'indigo_teal', 'nuit', 'nature', 'coucher_de_soleil', 'violet', 'frais', 'contraste', 'pastel', 'moderne'];
const schemaTheme = db.prepare(
"SELECT sql FROM sqlite_master WHERE type='table' AND name='parametres_theme'"
).get()?.sql ?? '';
if (schemaTheme && !schemaTheme.includes("'classique'")) {
const oldValue = db.prepare('SELECT color_theme FROM parametres_theme WHERE id = 1').get()?.color_theme;
const migratedValue = NEW_COLOR_THEMES.includes(oldValue) ? oldValue : 'classique';
const tempName = '__repair_parametres_theme';
db.exec('PRAGMA foreign_keys = OFF');
db.exec(`DROP TABLE IF EXISTS "${tempName}"`);
db.exec(`
CREATE TABLE "${tempName}" (
id INTEGER PRIMARY KEY CHECK (id = 1),
color_theme TEXT NOT NULL DEFAULT 'classique'
CHECK (color_theme IN ('classique', 'indigo_teal', 'nuit', 'nature', 'coucher_de_soleil', 'violet', 'frais', 'contraste', 'pastel', 'moderne')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
)
`);
db.prepare(`INSERT INTO "${tempName}" (id, color_theme) VALUES (1, ?)`).run(migratedValue);
db.exec('DROP TABLE parametres_theme');
db.exec('PRAGMA legacy_alter_table = ON');
db.exec(`ALTER TABLE "${tempName}" RENAME TO parametres_theme`);
db.exec('PRAGMA legacy_alter_table = OFF');
db.exec('PRAGMA foreign_keys = ON');
console.log(`[DB] parametres_theme : migré vers les 10 thèmes basés sur les palettes de graphiques (valeur existante '${oldValue}' → '${migratedValue}')`);
} else {
db.exec(`
CREATE TABLE IF NOT EXISTS parametres_theme (
id INTEGER PRIMARY KEY CHECK (id = 1),
color_theme TEXT NOT NULL DEFAULT 'classique'
CHECK (color_theme IN ('classique', 'indigo_teal', 'nuit', 'nature', 'coucher_de_soleil', 'violet', 'frais', 'contraste', 'pastel', 'moderne')),
updated_at TEXT NOT NULL DEFAULT (datetime('now'))
)
`);
}
}
db.exec(`INSERT OR IGNORE INTO parametres_theme (id) VALUES (1)`);
// ── Migration : email_verified sur users ─────────────────────────────────────
{
const userCols = db.prepare('PRAGMA table_info(users)').all().map(c => c.name);
@@ -2881,7 +2947,7 @@ if (pendingRestorePreserve) {
}
});
restoreEnvLocal();
console.log('[restore] Tables locales (api_keys/ai_providers/ai_config/parametres_environnement) préservées et réappliquées après restauration.');
console.log('[restore] Tables locales (api_keys/ai_providers/ai_config/parametres_environnement/parametres_theme) préservées et réappliquées après restauration.');
} catch (e) {
console.error('[restore] Échec de la réapplication des tables locales préservées :', e.message);
}