import { Router } from 'express'; import db from '../db/index.js'; const router = Router(); // Clés autorisées — liste blanche pour éviter les injections de clés arbitraires const ALLOWED_KEYS = new Set([ 'chart_interets', 'chart_capital', 'chart_cashback', // Extensible : ajouter ici les futures prefs (theme, font_scale, langue, devise, display_mode…) ]); /** * GET /api/preferences * Retourne toutes les préférences de l'utilisateur connecté sous forme d'objet plat. * Les clés absentes ne sont pas retournées (le frontend utilise ses valeurs par défaut). */ router.get('/', (req, res) => { const rows = db .prepare('SELECT key, value FROM user_preferences WHERE user_id = ?') .all(req.user.id); const result = {}; for (const { key, value } of rows) result[key] = value; res.json(result); }); /** * PATCH /api/preferences * Upsert d'un ou plusieurs couples { key: value }. * Seules les clés de ALLOWED_KEYS sont acceptées. */ router.patch('/', (req, res) => { const payload = req.body; if (!payload || typeof payload !== 'object' || Array.isArray(payload)) { return res.status(400).json({ error: 'Corps invalide — objet { clé: valeur } attendu' }); } const upsert = db.prepare(` INSERT INTO user_preferences (user_id, key, value, updated_at) VALUES (?, ?, ?, datetime('now')) ON CONFLICT (user_id, key) DO UPDATE SET value = excluded.value, updated_at = excluded.updated_at `); const unknown = Object.keys(payload).filter(k => !ALLOWED_KEYS.has(k)); if (unknown.length) { return res.status(400).json({ error: `Clés inconnues : ${unknown.join(', ')}` }); } const persist = db.transaction(() => { for (const [key, value] of Object.entries(payload)) { upsert.run(req.user.id, key, String(value)); } }); persist(); res.json({ ok: true }); }); export default router;