60 lines
2.6 KiB
JavaScript
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()
|