import { Router } from 'express' import { config } from '../config.js' import { getDocument, listDocuments, Query, updateDocument } from '../services/appwriteAdmin.js' import { withLocks } from '../services/keyedLock.js' import { statusAusKonto } from '../services/shop/connect.js' import { unterkunftModus } from '../services/unterkunft/schalter.js' /** * Stripe-Ereignisse des Buchungskalenders. Kein eigener Endpunkt: routes/shopWebhook.js (Connect-Webhook, ein Endpunkt je Konto) * leitet Ereignisse mit metadata.wkUk === '1' (Checkout-Sitzungen) oder metadata.webklar === 'unterkunft' (Erstattungen) hierher * und ruft bei account.updated zusaetzlich kontoAktualisiertUk. Alles idempotent; Fehler => 500 (Stripe wiederholt). */ const ACCOUNT_RE = /^acct_[A-Za-z0-9]+$/ /** * Checkout- und Erstattungsereignisse des Buchungskalenders verarbeiten. Geruest (Task 5): Task 8/9 fuellen es (Zahlung eingegangen, * Sitzung abgelaufen, Erstattung gebucht). Bis dahin ohne Wirkung. * @param {object} event Stripe-Ereignis (signiert und geprueft) * @param {Date} [now] */ export async function verarbeiteUkEreignis(event, now = new Date()) { return ereignisHandler(event, now) } // Austauschbar nur fuer Tests (Weiche in shopWebhook.js pruefen); Task 8/9 ersetzen den Standard durch die echte Verarbeitung let ereignisHandler = async () => {} export function setzeUkEreignisHandlerFuerTests(fn) { ereignisHandler = fn ?? (async () => {}) } /** * account.updated: Bereitschaftsstatus (stripeStatus) aller Einstellungen mit diesem Konto neu speichern. Bei UNTERKUNFT_ENABLED=off * und solange die Collection fehlt (Setup-Skript noch nicht gelaufen) ohne Wirkung. * @returns {Promise} Zahl aktualisierter Einstellungen */ export async function kontoAktualisiertUk(accountId, konto, now = new Date()) { if (unterkunftModus() === 'off' || !ACCOUNT_RE.test(accountId || '')) return 0 let dokumente try { dokumente = await listDocuments(config.collections.ukEinstellungen, [Query.equal('stripeAccountId', accountId), Query.limit(25)]) } catch (err) { if (err?.status === 404) return 0 throw err } let n = 0 for (const doc of dokumente) { await withLocks([`uk-stripe:${doc.$id}`], async () => { const frisch = await getDocument(config.collections.ukEinstellungen, doc.$id) if (frisch.stripeAccountId !== accountId) return await updateDocument(config.collections.ukEinstellungen, doc.$id, { stripeStatus: JSON.stringify(statusAusKonto(konto, now)) }) n++ }) } return n } // Kein Endpunkt: die Datei haengt nur Funktionen an. Der leere Router erlaubt ein spaeteres Einhaengen ohne Aenderung am Import. export default Router()