87 lines
2.5 KiB
JavaScript
87 lines
2.5 KiB
JavaScript
import { mapEvent } from './mappers.js';
|
||
|
||
/**
|
||
* Mehrere ATTACHMENT-DB-Zeilen pro Kalendertag (lokal) zu einem Listeneintrag zusammenführen.
|
||
* @param {Array<Record<string, unknown>>} rows – SELECT * FROM events (bereits sortiert)
|
||
* @param {Map<string, Array<Record<string, unknown>>>} 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<string, Array<Record<string, unknown>>>} */
|
||
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<string, unknown>; attachments: Array<Record<string, unknown>> }>} */
|
||
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, []),
|
||
);
|
||
}
|