Merge remote-tracking branch 'origin/main' into feature/oeffnungszeiten
Zusammenführung von TP2-Abschluss und Webshop (origin/main cab9c33) mit Öffnungszeiten live. Beide
Funktionen bleiben vollständig: jeder Konflikt ist als Vereinigung gelöst, Reihenfolge der Funktionsschlüssel
überall news, termine, shop, zeiten.
Konfliktdateien (28): public/app.js, dashboard.html, funktionen.js, widerrufen.html; scripts/stripe-products.mjs;
server/config.js, index.js, middleware/kundenansichtGuard.js, routes/abo.js, routes/admin/funktionenAdmin.js,
routes/funktionen.js, services/customerAdmin.js, customerViewLog.js, featureRegistry.js, retention.js,
siteFeatures.js, stripeBilling.js; test/customerViewLog, featureFreischaltung, featureRegistry, funktionenRoutes,
funktionenTermine, kundenansichtGuard, mailTemplates, publicForms, siteFeatures, stripeProductsScript (je
.test.js) und test/support/schema.js.
Entscheidungen: Mailvorlagen G01–G15, K01–K30, T01–T21 lückenlos (K24–K26 Webshop, K27–K30 Öffnungszeiten);
Stripe-Katalog mit shopSetup und zeitenSetup; Widerruf kennt shop und zeiten; ABO_FUNKTIONEN bleibt analyse
und termine (kein zeiten); activate() schreibt die Zeiten-Felder nur über extra; kein Halter von
feature-activate:<id> ruft disable() auf; die Aufbewahrungs-Löschung löscht Zeiten-Daten vor dem Abschalten und
hält den Kunden bei einem Fehler (held); die Admin-Antwort trägt ersatzTicket und warnung; Hash-Routen webshop
und zeiten, Ansichten view-webshop und view-zeiten; assertOwnProject behält die Meldung von main.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
commit
e87140e5ba
245 files changed
+38799
-1050
No files matched your search
@@ -198,7 +198,7 @@ export async function updateCustomerWithPortalAccess(customerId, payload) {
|
||||
portalPassword = normalizedPassword
|
||||
}
|
||||
} else if (normalizedPassword) {
|
||||
const error = new Error('Portal-Login fehlt � bitte E-Mail setzen und Passwort erneut speichern')
|
||||
const error = new Error('Portal-Login fehlt – bitte E-Mail setzen und Passwort erneut speichern')
|
||||
error.status = 400
|
||||
throw error
|
||||
}
|
||||
@@ -291,6 +291,22 @@ export async function deleteCustomerWithPortalAccess(customerId) {
|
||||
console.error(`[customerAdmin] Terminplaner von Kunde ${customerId} nicht abgeschaltet:`, err.message)
|
||||
}
|
||||
|
||||
// Webshop abschalten: Kaeufer koennen Bestellungen nicht mehr aufgeben, den Widerruf aber weiter erklaeren; die Shopdaten loescht der
|
||||
// Tagesjob 90 Tage nach disabledAt. Den Shop selbst schliessen wir sofort (geoeffnet=false) und leeren den Speicher der oeffentlichen
|
||||
// Schnittstelle. Jeder Teilschritt ist abgesichert: Fehler halten das Loeschen nicht auf (wie bei Analyse und Terminplaner).
|
||||
try {
|
||||
const { disableCustomerFeatures } = await import('./siteFeatures.js')
|
||||
await disableCustomerFeatures(customerId, 'shop', { adminNote: 'Kunde gelöscht', reason: 'kunde_geloescht' })
|
||||
} catch (err) {
|
||||
console.error(`[customerAdmin] Webshop von Kunde ${customerId} nicht abgeschaltet:`, err.message)
|
||||
}
|
||||
try {
|
||||
const { schliesseShopsVonKunde } = await import('./shop/kundenLoeschung.js')
|
||||
await schliesseShopsVonKunde(customerId)
|
||||
} catch (err) {
|
||||
console.error(`[customerAdmin] Webshop von Kunde ${customerId} nicht geschlossen:`, err.message)
|
||||
}
|
||||
|
||||
// Oeffnungszeiten live: wie der Terminplaner abschalten (die Antwort der Website ist sofort aktiv false: Kunde und Funktion fehlen/sind
|
||||
// disabled), danach Zeiten und Erinnerungsmerker sofort loeschen (Spec 5) und den Speicher der Antworten leeren. Beides fuer sich in
|
||||
// try/catch: ein Fehler haelt weder das Loeschen des Kunden noch den jeweils anderen Schritt auf. Geloggt wird nur die Kunden-ID.
|
||||
|
||||
Reference in new issue
Block a user