const { query } = require('../../utils/db') const { parseJson } = require('./engagementRules.db') const hydrate = (row) => row && { ...row, expression: parseJson(row.expression, null) } const list = async () => (await query('SELECT * FROM engagement_audience_segments ORDER BY name, id')).map(hydrate) const getById = async (id) => { const [row] = await query('SELECT * FROM engagement_audience_segments WHERE id = ?', [id]) return hydrate(row) } /** * `ceiling` is written by the caller from `segments.deriveCeiling`, never taken * from an operator. It is a stored column rather than a runtime computation so * an audit can read what a rule was ALLOWED to reach without re-resolving it, * and so a module that later widens its own audience's ceiling cannot * retroactively widen a segment that was saved under the old one. */ const insert = async (segment) => { const result = await query( 'INSERT INTO engagement_audience_segments (name, expression, ceiling, updated_by) VALUES (?, ?, ?, ?)', [segment.name, JSON.stringify(segment.expression), segment.ceiling, segment.updated_by ?? null], ) return result.insertId } const update = (id, segment) => query( 'UPDATE engagement_audience_segments SET name = ?, expression = ?, ceiling = ?, updated_by = ? WHERE id = ?', [segment.name, JSON.stringify(segment.expression), segment.ceiling, segment.updated_by ?? null, id], ) const remove = (id) => query('DELETE FROM engagement_audience_segments WHERE id = ?', [id]) module.exports = { list, getById, insert, update, remove }