89 lines
4.0 KiB
JavaScript
89 lines
4.0 KiB
JavaScript
import { laufeFristenAb } from './ablauf.js'
|
|
import { config } from '../../config.js'
|
|
import { listDocuments, Query } from '../appwriteAdmin.js'
|
|
import { sendeHinweiseVorLoeschung } from './abschaltHinweis.js'
|
|
import { anonymisiere, loescheAbgeschaltete } from './aufbewahrung.js'
|
|
import { gleicheAlleAb } from './icalAbgleich.js'
|
|
import { unterkunftModus } from './schalter.js'
|
|
|
|
/**
|
|
* Jobs des Buchungskalenders (Registrierung in server/index.js: Minuten 80 s Start / 60 s, Viertelstunden 140 s / 15 min,
|
|
* taeglich 210 s / 24 h). Jeder Job laeuft hoechstens einmal gleichzeitig (ein Lauf, der noch haengt, ueberspringt den naechsten
|
|
* Takt), wirft nie und kehrt bei UNTERKUNFT_ENABLED=off sofort zurueck (der Tagesjob nur, solange es keine Buchungsdaten mehr gibt).
|
|
*/
|
|
|
|
const laufend = new Set()
|
|
|
|
async function einzeln(name, arbeit) {
|
|
if (laufend.has(name)) {
|
|
console.warn(`[unterkunft-jobs] ${name}: der vorige Lauf ist noch nicht fertig, dieser Takt wird übersprungen`)
|
|
return { uebersprungen: true }
|
|
}
|
|
laufend.add(name)
|
|
try {
|
|
return await arbeit()
|
|
} catch (err) {
|
|
console.error(`[unterkunft-jobs] ${name} fehlgeschlagen: ${err?.name} ${err?.status ?? ''}`)
|
|
return { fehler: true }
|
|
} finally {
|
|
laufend.delete(name)
|
|
}
|
|
}
|
|
|
|
/** Minutenjob: Fristen ablaufen lassen (Anfragen, Reservierungen). Bei UNTERKUNFT_ENABLED=off aus. */
|
|
export async function minutenJob(now = new Date()) {
|
|
if (unterkunftModus() === 'off') return { aus: true }
|
|
return einzeln('minutenJob', () => laufeFristenAb(now))
|
|
}
|
|
|
|
/** Viertelstundenjob: iCal-Importe abgleichen. Bei UNTERKUNFT_ENABLED=off aus. */
|
|
export async function viertelstundenJob(now = new Date()) {
|
|
if (unterkunftModus() === 'off') return { aus: true }
|
|
return einzeln('viertelstundenJob', () => gleicheAlleAb(now))
|
|
}
|
|
|
|
/** Gibt es irgendwelche Buchungsdaten? Die Fristen gelten auch bei UNTERKUNFT_ENABLED=off (fehlende Collections = nein). */
|
|
async function gibtDaten() {
|
|
for (const name of ['ukEinstellungen', 'ukAnfragen']) {
|
|
try {
|
|
if ((await listDocuments(config.collections[name], [Query.select(['$id']), Query.limit(1)])).length > 0) return true
|
|
} catch (err) {
|
|
if (err?.type !== 'collection_not_found' && err?.code !== 'collection_not_found') throw err
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
/**
|
|
* Tagesjob: Aufbewahrung (ipHash, Verfall von `neu`, Anonymisierung, Rechnungen nach 8 Jahren) und Loeschung abgeschalteter Funktionen
|
|
* (90 Tage; davor einmal die Hinweis-Mail K35). Gemeinsamer Deckel config.unterkunft.aufbewahrungDeckel (500) je Lauf (die Loeschung bekommt, was die Aufbewahrung uebrig laesst). Bei UNTERKUNFT_ENABLED=off nur, wenn es noch
|
|
* Buchungsdaten gibt (die Fristen gelten auch dann). Ein Teil, der scheitert, stoppt den anderen nicht.
|
|
*/
|
|
export async function taeglicherJob(now = new Date()) {
|
|
return einzeln('taeglicherJob', async () => {
|
|
if (unterkunftModus() === 'off' && !(await gibtDaten())) return { aus: true }
|
|
const deckel = config.unterkunft.aufbewahrungDeckel ?? 500
|
|
let anon = { anfragen: 0, gaeste: 0, fehler: 1 }
|
|
let weg = { funktionen: 0, dokumente: 0, fehler: 1, gedeckelt: false }
|
|
let rest = deckel
|
|
try {
|
|
anon = await anonymisiere(now, { deckel })
|
|
rest = Math.max(0, deckel - (anon.verbraucht ?? 0))
|
|
} catch (err) {
|
|
console.error(`[unterkunft-jobs] taeglicherJob: Aufbewahrung fehlgeschlagen: ${err?.name} ${err?.status ?? ''}`)
|
|
}
|
|
// Vor der Loeschung: einmaliger Hinweis K35 (Rechnungen sichern); ein Fehler stoppt die Loeschung nicht (Marker fehlt, naechster Lauf wiederholt)
|
|
try {
|
|
await sendeHinweiseVorLoeschung(now)
|
|
} catch (err) {
|
|
console.error(`[unterkunft-jobs] taeglicherJob: Hinweis vor der Löschung fehlgeschlagen: ${err?.name} ${err?.status ?? ''}`)
|
|
}
|
|
try {
|
|
weg = await loescheAbgeschaltete(now, { deckel: rest })
|
|
} catch (err) {
|
|
console.error(`[unterkunft-jobs] taeglicherJob: Löschung abgeschalteter Funktionen fehlgeschlagen: ${err?.name} ${err?.status ?? ''}`)
|
|
}
|
|
return { aufbewahrung: anon, abgeschaltet: weg }
|
|
})
|
|
}
|