Terminplaner: Kunden-Schnittstelle – Nachbesserungen
- GET /zeiten?ohne=<Buchung>: Leistung, Dauer und Person der Buchung wie beim Verschieben (verschiebeZeiten exportiert), unbekannte/fremde/Sperre 404 (R42) - Schreib-Begrenzung als gemeinsamer Baustein (writeLimiter.js) fuer News und Terminplaner statt kopierter Funktion (R43) - Unlesbares Einstellungs-JSON: Kontext traegt die echte Version, Speichern ueberschreibt den Schaden statt dauerhaft 409 - U+FEFF als Escape statt als rohes Zeichen - Tests: Mandantentrennung mit echtem zweitem Kunden, R42, Limiter, kaputtes JSON Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
e3e198fb1a
commit
bb45d35ec7
8 files changed
+319
-65
No files matched your search
@@ -15,7 +15,7 @@ import { pruefeNow, pruefeText } from './util.js'
|
||||
* feature portalFeatures-Dokument (featureKey 'termine')
|
||||
* project websiteProjects-Dokument oder null (Projekt fehlt)
|
||||
* einstellung gespeicherte Einstellung (Objekt) oder null (noch nie gespeichert / unlesbar)
|
||||
* version Zaehler fuer die optimistische Sperre (0 = noch nie gespeichert)
|
||||
* version Zaehler fuer die optimistische Sperre (0 = noch nie gespeichert; bei unlesbarem JSON die Version des Dokuments)
|
||||
* Ein ctx ist nur zum Lesen: kontextPerSiteKey gibt innerhalb von 30 Sekunden dasselbe Objekt zurueck.
|
||||
*
|
||||
* - kontextPerSiteKey (oeffentliche Schnittstelle): nur Funktionen im Zustand active und nur mit gespeicherter
|
||||
@@ -51,8 +51,11 @@ async function holeOderNull(collectionId, id) {
|
||||
}
|
||||
}
|
||||
|
||||
/** { einstellung, version } aus einem termineConfig-Dokument; unlesbares JSON gilt als nicht gespeichert (mit Log). */
|
||||
function liesEinstellung(doc) {
|
||||
/**
|
||||
* { einstellung, version } aus einem termineConfig-Dokument. Unlesbares JSON (mit Log) ergibt einstellung null, die Version
|
||||
* des Dokuments bleibt: wer die kaputte Einstellung ueberschreiben will, speichert mit genau dieser Version.
|
||||
*/
|
||||
function liesDokument(doc) {
|
||||
const version = Number.isInteger(doc.version) ? doc.version : 0
|
||||
try {
|
||||
const einstellung = JSON.parse(doc.einstellung)
|
||||
@@ -60,7 +63,7 @@ function liesEinstellung(doc) {
|
||||
return { einstellung, version }
|
||||
} catch (err) {
|
||||
console.error(`[termine-kontext] Einstellung ${doc.$id} ist unlesbar: ${err.message}`)
|
||||
return null
|
||||
return { einstellung: null, version }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,15 +75,17 @@ function liesEinstellung(doc) {
|
||||
export async function ladeEinstellung(featureId) {
|
||||
pruefeText(featureId, 'featureId')
|
||||
const doc = await holeOderNull(config.collections.termineConfig, featureId)
|
||||
return doc ? liesEinstellung(doc) : null
|
||||
const gelesen = doc ? liesDokument(doc) : null
|
||||
return gelesen?.einstellung ? gelesen : null
|
||||
}
|
||||
|
||||
async function baueKontext(feature) {
|
||||
const [project, gespeichert] = await Promise.all([
|
||||
const [project, doc] = await Promise.all([
|
||||
feature.projectId ? holeOderNull(config.collections.websiteProjects, feature.projectId) : null,
|
||||
ladeEinstellung(feature.$id),
|
||||
holeOderNull(config.collections.termineConfig, feature.$id),
|
||||
])
|
||||
return { feature, project, einstellung: gespeichert?.einstellung ?? null, version: gespeichert?.version ?? 0 }
|
||||
const gelesen = doc ? liesDokument(doc) : null
|
||||
return { feature, project, einstellung: gelesen?.einstellung ?? null, version: gelesen?.version ?? 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -160,7 +165,7 @@ export async function speichereEinstellung(feature, einstellungOderFn, { version
|
||||
const aktuell = vorhanden && Number.isInteger(vorhanden.version) ? vorhanden.version : 0
|
||||
if (version !== null && version !== aktuell) throw veraltet()
|
||||
|
||||
const einstellung = alsFunktion ? await einstellungOderFn(vorhanden ? (liesEinstellung(vorhanden)?.einstellung ?? null) : null) : einstellungOderFn
|
||||
const einstellung = alsFunktion ? await einstellungOderFn(vorhanden ? liesDokument(vorhanden).einstellung : null) : einstellungOderFn
|
||||
if (!istObjekt(einstellung)) throw new TypeError('einstellung fehlt')
|
||||
const json = JSON.stringify(einstellung)
|
||||
|
||||
|
||||
Reference in new issue
Block a user