const { query } = require('../../utils/db') async function getAll() { return query('SELECT `key`, value, updated_at FROM settings ORDER BY `key`') } async function get(key) { const rows = await query('SELECT value FROM settings WHERE `key` = ? LIMIT 1', [key]) return rows[0] ? rows[0].value : null } async function set(key, value, updatedBy = null) { await query( 'INSERT INTO settings (`key`, value, updated_by) VALUES (?, ?, ?) ' + 'ON DUPLICATE KEY UPDATE value = VALUES(value), updated_by = VALUES(updated_by)', [key, value, updatedBy], ) } // One row WITH its provenance. `updated_by`/`updated_at` are already stored for // every key; this is the only reader that needs them, because TEAMS.md §5.5.5 // makes the uploads acknowledgement a RECORDED consent rather than a displayed // one, and "which admin accepted it, and when" is the question that has to be // answerable afterwards. async function getRow(key) { const rows = await query( 'SELECT s.`key`, s.value, s.updated_by, s.updated_at, u.username AS updated_by_username ' + 'FROM settings s LEFT JOIN users u ON u.id = s.updated_by WHERE s.`key` = ? LIMIT 1', [key], ) return rows[0] || null } // Insert a default only if the key does not already exist. async function seedDefault(key, value) { await query('INSERT IGNORE INTO settings (`key`, value) VALUES (?, ?)', [key, value]) } // Delete a settings row. "Reset to defaults" for the theming/nav keys is the // *absence* of a row, not a stored copy of the defaults — see // docs/website/THEMING_AND_NAV.md §2. Deleting a key that was never set is a // no-op, so reset is idempotent. async function remove(key) { await query('DELETE FROM settings WHERE `key` = ?', [key]) } module.exports = { getAll, get, getRow, set, seedDefault, remove }