This commit is contained in:
2026-03-23 02:09:14 +01:00
parent 705329d3c2
commit d8d46ed8e9
61 changed files with 6054 additions and 3116 deletions

View File

@@ -0,0 +1,86 @@
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, []),
);
}