import { pool } from '../pool.js'; import { recordAudit } from './audit_stub.js'; import { triggerEmbed } from '../../jobs/triggers.js'; async function snapshot(client, page_id, body_md, edited_by) { await client.query( `INSERT INTO page_revisions(page_id, body_md, edited_by) VALUES($1,$2,$3)`, [page_id, body_md, edited_by || null] ); } export async function create({ space_id, slug, title, body_md = '', parent_id }, actor) { const client = await pool.connect(); try { await client.query('BEGIN'); const { rows: [r] } = await client.query( `INSERT INTO pages(space_id, slug, title, body_md, parent_id) VALUES($1,$2,$3,$4,$5) RETURNING *`, [space_id, slug, title, body_md, parent_id || null] ); await snapshot(client, r.id, body_md, actor?.kind); await client.query('COMMIT'); await recordAudit(actor, 'create', 'page', r.id, null, r); await triggerEmbed('page', r.id); return r; } catch (e) { await client.query('ROLLBACK'); throw e; } finally { client.release(); } } export async function getById(id) { const { rows: [r] } = await pool.query(`SELECT * FROM pages WHERE id=$1`, [id]); return r; } export async function getBySlug(space_id, slug) { const { rows: [r] } = await pool.query( `SELECT * FROM pages WHERE space_id=$1 AND slug=$2`, [space_id, slug] ); return r; } export async function listBySpace(space_id) { const { rows } = await pool.query( `SELECT id, space_id, slug, title, parent_id, updated_at FROM pages WHERE space_id=$1 ORDER BY title`, [space_id] ); return rows; } export async function listRevisions(page_id) { const { rows } = await pool.query( `SELECT * FROM page_revisions WHERE page_id=$1 ORDER BY created_at DESC`, [page_id] ); return rows; } export async function update(id, patch, actor) { const before = await getById(id); const client = await pool.connect(); try { await client.query('BEGIN'); const fields = ['slug','title','body_md','body_html','parent_id','embedding']; const sets = [], vals = []; let i = 1; for (const f of fields) { if (patch[f] !== undefined) { sets.push(`${f}=$${i++}`); vals.push(patch[f]); } } sets.push(`updated_at=now()`); vals.push(id); const { rows: [r] } = await client.query( `UPDATE pages SET ${sets.join(', ')} WHERE id=$${i} RETURNING *`, vals ); if (patch.body_md !== undefined && patch.body_md !== before.body_md) { await snapshot(client, id, patch.body_md, actor?.kind); } await client.query('COMMIT'); await recordAudit(actor, 'update', 'page', id, before, r); if (patch.embedding === undefined) await triggerEmbed('page', id); return r; } catch (e) { await client.query('ROLLBACK'); throw e; } finally { client.release(); } } export async function del(id, actor) { const before = await getById(id); await pool.query(`DELETE FROM pages WHERE id=$1`, [id]); await recordAudit(actor, 'delete', 'page', id, before, null); }