Files
Webklar-Kundenbereich/server/routes/unterkunftWebhook.js
T

60 lines
2.6 KiB
JavaScript

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<number>} 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()