Checkout je Funktion: Vorpruefungen in der Reihenfolge der Spezifikation
POST /api/funktionen/:key/checkout ersetzt /news/checkout (der News-Pfad bleibt als key = news erhalten). Stufen ohne Seiteneffekt: 1 Kundenansicht (403), 2 Schluessel gegen das Register (404), 3 Zustimmung (400 zustimmung_fehlt, 409 fassung_veraltet mit der Serverfassung; News weiter mit consent: true), 4 Projekt (400/403; bei fortsetzen muss das Dokument ordered sein), 5 Schalter (409 nicht_verfuegbar), 5b Unterlagen (503 unterlagen_fehlen), 6 Bestellpruefung (409 bestellung_offen mit offen), 7 Wartungs-Abo (409 kein_abo | gekuendigt | nicht_aktiv, Lesefehler 500). fail() gibt err.body weiter. featureOrder.js: pruefeZustimmung, istFortsetzen, aboMeldung (einzige Quelle der Abo-Hinweistexte), ladeEntwurf, pruefeAbo, orderDeps. featureRegistry.js: featureSperre und die Standard-Haken verfuegbar, bestellpruefung (mitAbo: false, ohne abo) und unterlagenBereit des Terminplaners. Der Rest der Route (Sperre, Zustand, Sitzung, Nachweis) bleibt bis Task B7 nur fuer News; andere Funktionen enden mit 503. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
d568a3798d
commit
ded6bb2a77
5 files changed
+960
-11
No files matched your search
@@ -1,19 +1,42 @@
|
||||
import { config } from '../config.js'
|
||||
import { termineFuerKunde } from './termine/schalter.js'
|
||||
|
||||
// Helfer fuer das Funktionen-Register config.features (News-Pinnwand, Terminplaner; Daten in server/config.js).
|
||||
// Diese Datei wird von siteFeatures.js importiert und importiert selbst keine Dienste statisch: Standard-Haken
|
||||
// laden ihre Dienste per dynamischem import() innerhalb der Funktion (sonst entstuenden Importzyklen).
|
||||
// Diese Datei wird von siteFeatures.js importiert und importiert selbst keine Dienste statisch (einzige Ausnahme:
|
||||
// termine/schalter.js, das nur config liest): Standard-Haken laden ihre Dienste per dynamischem import()
|
||||
// innerhalb der Funktion (sonst entstuenden Importzyklen).
|
||||
|
||||
/** Namen der Haken, die ein Registereintrag hat (optional): Bestell-, Freischalt- und Unterlagenpruefungen. */
|
||||
const HAKEN_NAMEN = ['verfuegbar', 'bestellpruefung', 'unterlagenBereit', 'belehrung', 'freischaltbar']
|
||||
|
||||
/**
|
||||
* Standard-Haken je Funktion (Funktionen, nicht Daten). Leer in Task B1; es fuellen sie B6 (verfuegbar,
|
||||
* bestellpruefung, unterlagenBereit), B7 (belehrung) und B11 (freischaltbar). News hat keine Standard-Haken.
|
||||
* Bestellpruefung des Terminplaners im Checkout: die offenen Punkte des Entwurfs (Einstellung und Fragebogen aus
|
||||
* termineConfig; ohne Dokument beides null) nach termine/fragebogen.js. Ohne abo und mit mitAbo: false: den Abo-Punkt (h)
|
||||
* wendet der Checkout nicht an, die Abo-Stufe (7) der Route liefert kein_abo | gekuendigt | nicht_aktiv.
|
||||
*/
|
||||
async function termineBestellpruefung({ customerId, projectId, feature }) {
|
||||
const [{ getFeatureDoc }, { ladeEntwurf }, { bestellpruefung }] = await Promise.all([
|
||||
import('./siteFeatures.js'),
|
||||
import('./featureOrder.js'),
|
||||
import('./termine/fragebogen.js'),
|
||||
])
|
||||
const doc = await getFeatureDoc(customerId, projectId, 'termine')
|
||||
const { einstellung, fragebogen } = doc ? await ladeEntwurf(doc.$id) : { einstellung: null, fragebogen: null }
|
||||
return bestellpruefung({ einstellung, fragebogen, feature, mitAbo: false })
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard-Haken je Funktion (Funktionen, nicht Daten). B6 fuellt verfuegbar, bestellpruefung und unterlagenBereit
|
||||
* (Standard immer bereit; F8 haengt die Rechtsunterlagen ein), B7 belehrung und B11 freischaltbar. News hat keine
|
||||
* Standard-Haken. Feste Funktionen, damit featureHaken bei jedem Aufruf dieselben liefert.
|
||||
*/
|
||||
const STANDARD_HAKEN = {
|
||||
news: {},
|
||||
termine: {},
|
||||
termine: {
|
||||
verfuegbar: (email) => termineFuerKunde(email),
|
||||
bestellpruefung: termineBestellpruefung,
|
||||
unterlagenBereit: async () => true,
|
||||
},
|
||||
}
|
||||
|
||||
/** Registereintrag oder null; nur eigene Schluessel des Registers ('analyse', '__proto__', 'toString' => null). */
|
||||
@@ -43,6 +66,21 @@ export function featureHaken(key) {
|
||||
return haken
|
||||
}
|
||||
|
||||
const NICHT_VERFUEGBAR = 'Diese Funktion ist noch nicht verfügbar.'
|
||||
|
||||
/**
|
||||
* Pruefstufe 5 des Checkouts: Text, warum die Funktion diesem Kunden (noch) nicht angeboten wird, sonst null.
|
||||
* Gefragt wird der Haken verfuegbar(email) (Terminplaner: Schalter TERMINE_ENABLED und Pilotliste); Funktionen ohne
|
||||
* Haken (News) sind immer verfuegbar. Ein unbekannter Schluessel ist nicht verfuegbar (fail-closed).
|
||||
*/
|
||||
export function featureSperre(key, email) {
|
||||
const eintrag = featureConfig(key)
|
||||
if (!eintrag) return NICHT_VERFUEGBAR
|
||||
const { verfuegbar } = featureHaken(key)
|
||||
if (typeof verfuegbar !== 'function' || verfuegbar(email)) return null
|
||||
return eintrag.unavailableMessage || NICHT_VERFUEGBAR
|
||||
}
|
||||
|
||||
const fassung = (f) => (f ? { version: f.version, url: f.url ?? '' } : null)
|
||||
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user