Files
SDS-CRM/server/lib/ticket-events-merge.js
2026-03-23 02:09:14 +01:00

87 lines
2.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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, []),
);
}