Files
Webklar-Kundenbereich/scripts/kundenansicht-setup.mjs
T

89 lines
4.0 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env node
/**
* Kundenansicht neu (Paket P5, Abo-Modell Kern): legt die neuen Attribute an. Der Code schreibt sie nur, wenn ein
* Aufrufer die zugehoerigen Parameter uebergibt; ohne dieses Skript bleibt die alte Ansicht unberuehrt.
* - featureConsents.kundenart: Kundenart zum Klickzeitpunkt im Nachweis ('privat' | 'unternehmen')
* - workorders.einrichtungFuer: Schluessel der Funktion, die das Einrichtungs-Ticket betrifft (laengster: 'unterkunft')
* - workorders.einrichtungAbrechnung: 'abo' | 'projekt' | '' (Abrechnung der Einrichtung am Ticket)
* - portalFeatures.einrichtungAbrechnung: dieselbe Abrechnung am Funktionsdokument (Nachlegen und Heilen setzen
* den Marker am Ticket erneut)
* - portalFeatures.unlockedBy: 'kauf' | 'abo' | 'team' | 'projekt' (steht schon im Zeiten-Schema; fehlt es, legt
* dieses Skript es an)
* Idempotent: Vorhandenes wird uebersprungen. Das Skript loescht nichts und laeuft in Entwicklung und Tests nie
* gegen Produktion; dort nur auf Anweisung des Controllers nach OK des Inhabers, vorher immer mit --pruefen.
* scripts/setup-abo-collections.mjs, feature-setup.mjs und zeiten-setup.mjs bleiben unveraendert.
* Usage:
* node scripts/kundenansicht-setup.mjs --pruefen (Alias --check; nur melden, nichts anlegen; Exit 1 bei Luecken)
* node scripts/kundenansicht-setup.mjs (Fehlendes anlegen)
*
* config.js und der Appwrite-Client werden erst in main() geladen: test/support/schema.js importiert die
* Attributlisten, bevor die Tests ihre Umgebung (useTestEnv) setzen koennen.
*/
import { pathToFileURL } from 'node:url'
import { ZEITEN_FEATURE_ATTRIBUTES } from '../server/services/zeiten/schema.js'
const str = (key, size) => ({ key, type: 'string', size, required: false })
const unlockedBy = ZEITEN_FEATURE_ATTRIBUTES.find((a) => a.key === 'unlockedBy')
export const KUNDENANSICHT_ATTRIBUTE = {
featureConsents: [str('kundenart', 12)],
workorders: [str('einrichtungFuer', 16), str('einrichtungAbrechnung', 8)],
portalFeatures: [unlockedBy, str('einrichtungAbrechnung', 8)],
}
export async function main({ pruefen = false, client, log = console.log } = {}) {
const { config } = await import('../server/config.js')
let api = client
if (!api) {
const { createAppwriteClient } = await import('./analyse-setup.mjs')
api = createAppwriteClient()
}
const missing = []
const plan = []
// Erst alles pruefen, dann (ohne --pruefen) anlegen, damit --pruefen garantiert nichts veraendert
for (const [name, attributes] of Object.entries(KUNDENANSICHT_ATTRIBUTE)) {
const id = config.collections[name]
const exists = await api.collectionExists(id)
if (!exists && !pruefen) throw new Error(`Collection ${id} fehlt – zuerst das jeweilige Setup-Skript ausfuehren`)
if (!exists) log(`- ${id} FEHLT`)
const have = exists ? new Set((await api.listAttributes(id)).map((a) => a.key)) : new Set()
for (const attr of attributes) {
if (have.has(attr.key)) log(`= ${id}.${attr.key} (existiert)`)
else if (pruefen) log(`- ${id}.${attr.key} FEHLT`)
}
const absent = attributes.filter((a) => !have.has(a.key))
absent.forEach((a) => missing.push({ ...a, collection: id }))
plan.push({ id, absent })
}
const result = { missing }
if (pruefen) {
log(missing.length ? `${missing.length} Eintrag/Eintraege fehlen.` : 'Alles vorhanden.')
return result
}
for (const { id, absent } of plan) {
for (const attr of absent) {
await api.createAttribute(id, attr)
log(`+ Attribut ${id}.${attr.key}`)
}
}
for (const { id, absent } of plan) {
for (const attr of absent) await api.waitForAttribute(id, attr.key)
}
log('Fertig.')
return result
}
const invokedDirectly = process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href
if (invokedDirectly) {
const pruefen = process.argv.includes('--pruefen') || process.argv.includes('--check')
main({ pruefen })
.then(({ missing }) => process.exit(pruefen && missing.length ? 1 : 0))
.catch((e) => {
console.error(e.message)
process.exit(1)
})
}