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:
ClaudeandClaude Opus 5.5 committed 2026-10-06 06:12:23 +00:00
commit e87140e5ba
245 files changed
+38799 -1050

No files matched your search

+26 -3
View File
@@ -1,10 +1,11 @@
import { config } from '../config.js'
import { termineFuerKunde } from './termine/schalter.js'
import { shopFuerKunde } from './shop/schalter.js'
import { zeitenFuerKunde } from './zeiten/schalter.js'
// Helfer fuer das Funktionen-Register config.features (News-Pinnwand, Terminplaner, Oeffnungszeiten live; Daten in server/config.js).
// Diese Datei wird von siteFeatures.js importiert und importiert selbst keine Dienste statisch (einzige Ausnahme:
// termine/schalter.js und zeiten/schalter.js, die nur config lesen): Standard-Haken laden ihre Dienste per dynamischem import()
// Helfer fuer das Funktionen-Register config.features (News-Pinnwand, Terminplaner, Webshop, Oeffnungszeiten live; Daten in server/config.js).
// Diese Datei wird von siteFeatures.js importiert und importiert selbst keine Dienste statisch (einzige Ausnahmen:
// termine/schalter.js, shop/schalter.js und zeiten/schalter.js, die nur config lesen): 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, dazu nachFreischaltung. */
@@ -89,6 +90,21 @@ async function termineBelehrung() {
return widerrufsbelehrungFunktion()
}
/**
* Bestellpruefung des Webshops im Checkout: die Anfrage des Projekts muss vom Team angenommen sein (shop/anfrage.js,
* Block B). Geladen werden die Dienste erst beim Aufruf.
*/
async function shopBestellpruefung({ customerId, projectId }) {
const { anfrageOffenePunkte } = await import('./shop/anfrage.js')
return anfrageOffenePunkte({ customerId, projectId })
}
/** Vertragsunterlagen des Webshops abrufbar? (Stufe 5b des Checkouts; legalDocs.featureLegalReady, fail-closed, wirft nie.) */
async function shopUnterlagenBereit() {
const { featureLegalReady } = await import('./legalDocs.js')
return featureLegalReady('shop')
}
/**
* Standard-Haken je Funktion (Funktionen, nicht Daten). B6 fuellt verfuegbar, bestellpruefung und unterlagenBereit
* (Terminplaner: featureLegalReady, F8), B7 belehrung (Text der Belehrung, der vor dem Knopf steht
@@ -104,6 +120,13 @@ const STANDARD_HAKEN = {
belehrung: termineBelehrung,
freischaltbar: termineFreischaltbar,
},
// Webshop: kein freischaltbar (ein geschlossenes Ticket genuegt); Belehrung aus derselben Quelle wie beim Terminplaner
shop: {
verfuegbar: (email) => shopFuerKunde(email),
bestellpruefung: shopBestellpruefung,
unterlagenBereit: shopUnterlagenBereit,
belehrung: termineBelehrung,
},
// Oeffnungszeiten live: keine Bestellpruefung (die Einstellung entsteht erst im Editor); belehrung wie beim Terminplaner,
// unterlagenBereit immer (die Oeffnungszeiten haben nur die Leistungsbeschreibung als Seite, keine PDFs); freischaltbar: erst mit
// eingetragenen Zeiten; nachFreischaltung: Ersatz-Hash merken