import { mapEvent } from './mappers.js'; /** * Mehrere ATTACHMENT-DB-Zeilen pro Kalendertag (lokal) zu einem Listeneintrag zusammenführen. * @param {Array>} rows – SELECT * FROM events (bereits sortiert) * @param {Map>>} byEvent – event_id → ticket_attachments-Zeilen * @param {{ prepare: (sql: string) => { get: (a: unknown) => { d?: string } | undefined } }} db */ export function mergeAttachmentEventsForApi(rows, byEvent, db) { const dayKeyStmt = db.prepare(`SELECT date(?, 'localtime') AS d`); const nonAtt = []; /** @type {Map>>} */ const attByDay = new Map(); for (const r of rows) { if (r.type !== 'ATTACHMENT') { nonAtt.push(r); continue; } const dk = dayKeyStmt.get(r.created_at)?.d; const key = dk || String(r.created_at || '').slice(0, 10); if (!attByDay.has(key)) attByDay.set(key, []); attByDay.get(key).push(r); } /** @type {Array<{ row: Record; attachments: Array> }>} */ const mergedChunks = []; for (const [, group] of attByDay) { group.sort((a, b) => String(a.created_at).localeCompare(String(b.created_at)), ); const maxCreated = group.reduce((best, x) => String(x.created_at) > String(best) ? x.created_at : best, group[0].created_at, ); const descs = [ ...new Set( group .map((g) => String(g.description || '').trim()) .filter(Boolean), ), ]; const mergedRow = { ...group[0], id: group[0].id, created_at: maxCreated, description: descs.join('\n\n'), }; const allAtt = []; for (const ev of group) { const list = byEvent.get(ev.id); if (list) allAtt.push(...list); } allAtt.sort((a, b) => String(a.created_at).localeCompare(String(b.created_at)), ); mergedChunks.push({ row: mergedRow, attachments: allAtt }); } mergedChunks.sort((a, b) => String(b.row.created_at).localeCompare(String(a.row.created_at)), ); nonAtt.sort((a, b) => String(b.created_at).localeCompare(String(a.created_at)), ); const out = [ ...nonAtt, ...mergedChunks.map((c) => c.row), ]; const mergedByEventId = new Map( mergedChunks.map((c) => [c.row.id, c.attachments]), ); return out.map((r) => r.type === 'ATTACHMENT' ? mapEvent(r, mergedByEventId.get(r.id) || []) : mapEvent(r, []), ); }