Terminplaner: CSV-Export seitenweise gestreamt

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-04 09:32:14 +00:00
1 parent a1732613c9
commit d040a55f89
3 files changed
+187 -23

No files matched your search

+22
View File
@@ -222,6 +222,28 @@ export async function ersteBuchungen(featureId, limit = LOESCH_SEITE) {
return listDocuments(col(), [Query.equal('featureId', featureId), Query.limit(limit), Query.select(['$id'])])
}
/** Zeilen je Seite des CSV-Exports (exportSeite). */
export const EXPORT_SEITE = 500
/**
* Eine Seite Buchungen einer Funktion fuer den CSV-Export (jeder Status, auch Sperren; die filtert der Aufrufer je Seite
* heraus): hoechstens `limit` (Standard 500), nach Beginn (startsAt) aufsteigend, ab dem Dokument `nach` (dessen ID, null =
* erste Seite). Der Cursor ist immer die letzte Zeile der ungefilterten Seite. Sortiert wird nur nach startsAt (Index
* idx_feature_start; Appwrite haengt die interne Reihenfolge fuer gleiche Beginne selbst an), nie nach $id.
* Ohne Funktion, mit ungueltigem Cursor oder ungueltiger Grenze: TypeError (nie eine Abfrage ohne Funktionsfilter: Gastdaten).
*/
export async function exportSeite(featureId, { nach = null, limit = EXPORT_SEITE } = {}) {
if (typeof featureId !== 'string' || featureId === '') throw new TypeError('exportSeite: featureId muss ein nicht leerer Text sein')
if (nach !== null && (typeof nach !== 'string' || nach === '')) throw new TypeError('exportSeite: nach muss null oder eine Dokument-ID sein')
if (!Number.isInteger(limit) || limit < 1) throw new TypeError(`exportSeite: limit muss eine ganze Zahl ab 1 sein, nicht ${limit}`)
return listDocuments(col(), [
Query.equal('featureId', featureId),
Query.orderAsc('startsAt'),
Query.limit(limit),
...(nach === null ? [] : [Query.cursorAfter(nach)]),
])
}
/** Zahl der offenen Anfragen (Status angefragt) einer Funktion. */
export async function zaehleAnfragen(featureId) {
return (await listAllDocuments(col(), [Query.equal('featureId', featureId), Query.equal('status', 'angefragt')])).length