/** * Modul: Haushalt-Einstellungen (Preferences) * Zweck: REST-API fuer haushaltweite Praeferenzen (via sync_config-Tabelle) * Abhängigkeiten: express, server/db.js */ import { createLogger } from '../logger.js'; import express from 'express'; import * as db from '../db.js'; const log = createLogger('Preferences'); const router = express.Router(); const VALID_MEAL_TYPES = ['breakfast', 'lunch', 'dinner', 'snack']; const DEFAULT_MEAL_TYPES = VALID_MEAL_TYPES.join(','); const VALID_CURRENCIES = ['EUR', 'USD', 'GBP', 'SEK', 'NOK', 'DKK', 'CHF', 'CNY', 'PLN', 'CZK', 'HUF', 'JPY', 'AUD', 'CAD', 'TRY', 'RUB']; const DEFAULT_CURRENCY = 'EUR'; // -------------------------------------------------------- // Hilfsfunktionen // -------------------------------------------------------- function cfgGet(key) { const row = db.get().prepare('SELECT value FROM sync_config WHERE key = ?').get(key); return row ? row.value : null; } function cfgSet(key, value) { db.get().prepare(` INSERT INTO sync_config (key, value) VALUES (?, ?) ON CONFLICT(key) DO UPDATE SET value = excluded.value, updated_at = strftime('%Y-%m-%dT%H:%M:%SZ', 'now') `).run(key, value); } // -------------------------------------------------------- // GET /api/v1/preferences // Alle Haushalt-Praeferenzen lesen. // Response: { data: { visible_meal_types: string[] } } // -------------------------------------------------------- router.get('/', (req, res) => { try { const raw = cfgGet('visible_meal_types') ?? DEFAULT_MEAL_TYPES; const visibleMealTypes = raw.split(',').filter((t) => VALID_MEAL_TYPES.includes(t)); const currency = cfgGet('currency') ?? DEFAULT_CURRENCY; res.json({ data: { visible_meal_types: visibleMealTypes, currency, }, }); } catch (err) { log.error('GET /', err); res.status(500).json({ error: 'Interner Fehler', code: 500 }); } }); // -------------------------------------------------------- // PUT /api/v1/preferences // Haushalt-Praeferenzen aktualisieren. // Body: { visible_meal_types: string[] } // Response: { data: { visible_meal_types: string[] } } // -------------------------------------------------------- router.put('/', (req, res) => { try { const { visible_meal_types, currency } = req.body; if (visible_meal_types !== undefined) { if (!Array.isArray(visible_meal_types)) { return res.status(400).json({ error: 'visible_meal_types muss ein Array sein', code: 400 }); } const filtered = visible_meal_types.filter((t) => VALID_MEAL_TYPES.includes(t)); if (filtered.length === 0) { return res.status(400).json({ error: 'Mindestens ein Mahlzeit-Typ muss aktiv sein', code: 400 }); } cfgSet('visible_meal_types', filtered.join(',')); } if (currency !== undefined) { if (!VALID_CURRENCIES.includes(currency)) { return res.status(400).json({ error: `Ungültige Währung. Erlaubt: ${VALID_CURRENCIES.join(', ')}`, code: 400 }); } cfgSet('currency', currency); } const rawMealTypes = cfgGet('visible_meal_types') ?? DEFAULT_MEAL_TYPES; const savedMealTypes = rawMealTypes.split(',').filter((t) => VALID_MEAL_TYPES.includes(t)); const savedCurrency = cfgGet('currency') ?? DEFAULT_CURRENCY; res.json({ data: { visible_meal_types: savedMealTypes, currency: savedCurrency, }, }); } catch (err) { log.error('PUT /', err); res.status(500).json({ error: 'Interner Fehler', code: 500 }); } }); export default router;