Commit Graph
74 Commits
Author SHA1 Message Date
ClaudeandClaude Opus 5.5 1d5a565e9f Merge feature/terminplaner-tp2 (a629b25) in feature/oeffnungszeiten
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-05 04:42:31 +00:00
ClaudeandClaude Sonnet 5.5 6ec8885bfd Terminplaner: Hinweistexte nach Recherche, Storno nur bei Preis
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 04:29:32 +00:00
ClaudeandClaude Sonnet 5.5 722c686690 Gästetexte: Hinweis-Dokument ohne Entwurf-Wort, Archiv-Schutz
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 04:21:17 +00:00
ClaudeandClaude Sonnet 5.5 495d5ad9ca Gästetexte des Terminplaners: Entwurf-Kennzeichnung entfernt
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 04:08:46 +00:00
ClaudeandClaude Sonnet 5.5 c1266fcce7 Gästetexte des Terminplaners: Fassung 2026-10-05, Erinnerungs- und Abo-Ende-Satz, Archiv je Fassung
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 04:01:49 +00:00
ClaudeandClaude Sonnet 5.5 6b4cbb3204 Rechtstexte: Widerrufsbelehrung der Funktionen aus dem Gesetzesmuster
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 02:35:04 +00:00
ClaudeandClaude Sonnet 5.5 8fe14c2fe6 Funktionen: Freischalt-Hindernisse und Freigabe-Mail ausgelagert
freischaltHindernis (Abo zuerst, dann Einstellung; Abo-Lesefehler = abo_unbekannt)
und meldeFreigeschaltet (K16, Fehler geloggt, mit attachments) in
termine/freischaltung.js. Der Standardhaken freischaltbar fuer termine
delegiert an freischaltHindernis, runActivation an meldeFreigeschaltet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 00:56:35 +00:00
ClaudeandClaude Sonnet 5.5 2db3eca357 Terminplaner: Kurzfassung der Einbauanleitung fuer das Einrichtungs-Ticket, T16-Gesundheitsblock
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 00:45:56 +00:00
ClaudeandClaude Sonnet 5.5 90692b646b Terminplaner: Einbauanleitung als reiner Generator (Einbau bis Abrechnung, Warnungen)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 00:22:04 +00:00
ClaudeandClaude Sonnet 5.5 13bbadc729 Terminplaner: Einbauanleitung als reiner Generator (Modell bis Benachrichtigungen)
einbauanleitung({ feature, project, einstellung, fragebogen, version, now, updatedAt, kunde,
entwurf }) setzt die ersten sechs Abschnitte der Team-Anleitung zusammen (modell, leistungen,
ressourcen, regeln, gastfelder, benachrichtigungen, feste Reihenfolge, nicht kopierbar) plus
stand { version, updatedAt } und den Volltext. Rein: kein I/O, config nur beim Aufruf
(Portal-Adresse, Haltezeit); gleiche Eingabe und gleiches now ergeben gleiche Ausgabe, die
Eingabe bleibt unveraendert.

Feldweissliste statt Objektkopie: nie feedToken, keine Betriebs-E-Mail, keine
Leistungsbeschreibung, keine unbekannten Zusatzfelder. Kundentexte stehen unmaskiert als Text,
einzeilige Werte werden auf eine Zeile gebracht (keine vorgetaeuschte Ueberschrift).
Abwesenheiten und Sonderoeffnungen nur ab heute (Berliner Kalendertag), Listen ueber 20
Eintraege enden mit "und N weitere". Hilfen wochenplanText und kuerzeListe sind exportiert.

Warnungen und Kurzfassung bleiben leer (kommen mit D3b und D4); ohne Einstellung entstehen
keine Abschnitte.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-05 00:07:38 +00:00
ClaudeandClaude Sonnet 5.5 ee454017b0 Terminplaner: Einbau-Snippet mit Knopf und Farbvorschlag nach WCAG verschoben
einbauSnippet und esc wandern aus routes/termine.js nach services/termine/einbauanleitung.js
(Parameter statt ctx/config). Neu: Modus knopf mit data-knopf (nur bei gesetztem Text, hoechstens
40 Zeichen, Zeilenumbrueche zu Leerzeichen, maskiert; unbekannter Modus gilt als inline), WCAG-
Helfer luminanz/kontrast/textFarbeAuf 1:1 aus dem Widget und cssVorschlag(farbe) mit Warnung,
wenn der Akzent gegen Weiss unter 3 : 1 liegt. VORGABE_FARBE wird exportiert. Die Kundenansicht
bleibt unveraendert (Modus inline). Farbparitaet Widget/Server ueber alle 4096 Farben im
17er-Raster getestet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 23:55:42 +00:00
ClaudeandClaude Sonnet 5.5 06ebcd1b0a Terminplaner: Datenschutz-Absatz als Rechtstext-Baustein
datenschutzAbsatz(einstellung, anrede) liefert den Absatz "Online-Terminbuchung" fuer die
Datenschutzerklaerung der Betriebs-Website als reinen Text (Sie- und Du-Fassung, fuenf bedingte
Saetze: Telefon-Feld, Nachricht/Zusatzfelder, Erinnerung, Widerruf ueber zeigtWiderruf, Telefon des
Betriebs). RECHTSTEXTE_ENTWURF = true. Test pinnt den Wortlaut gegen die Markdown-Quelle in allen
32 Bedingungskombinationen.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 23:47:58 +00:00
ClaudeandClaude Opus 5.5 2636ce60be Feiertage: Namen und Prüftage im Zeitraum
Neue Exporte feiertagName und feiertageImZeitraum (feiertagejs getHolidays je Jahr,
Namen per translate('de')). Heiligabend, Silvester, Mariä Himmelfahrt in BY und
Fronleichnam in SN/TH (Datum aus RP) sind 'pruefen'; istFeiertag bleibt unverändert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-04 23:36:44 +00:00
ClaudeandClaude Sonnet 5.5 91b1a3bcd8 Terminplaner TP2: Entwuerfe nach 90 Tagen und bei Kundenloeschung entfernen
Neu: server/services/termine/entwuerfe.js. Ein Terminplaner im Zustand off ist ein
Entwurf (Fragebogen, Einstellung). loescheEntwuerfe(now) im Tagesjob (nach den
abgeschalteten Funktionen, nur im vollen Lauf): letzte Aenderung = juengerer Zeitpunkt
aus $updatedAt des Funktionsdokuments und termineConfig.updatedAt, aelter als 90 Tage
=> Einstellung weg, das Funktionsdokument nur, wenn es nie in Betrieb oder bezahlt war
(sonst bleibt es wegen des siteKeys; ein von E8 zurueckgesetztes Dokument nie).
Vor jedem Loeschen unter feature-order, feature-admin und termine-cfg frisch lesen
(noch off, Frist, keine Buchung). Seiten zu 100 per cursorAfter, hoechstens 2000
geprueft und 100 geloescht je Lauf, der Rest folgt an Folgetagen; Einzelfehler zaehlen
in fehler. Tagesbericht: Segment "Entwuerfe n geloescht (m offen)".
loescheEntwuerfeVonKunde: Kundenloeschung entfernt alle off-Entwuerfe vollstaendig,
Fehler werden nur protokolliert.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 20:33:33 +00:00
ClaudeandClaude Sonnet 5.5 42a3befc5f Terminplaner TP2 C4a: Nachbesserung 1
Die Wahl des Live-Hosts steht jetzt nur noch in liveHost() (kontext.js);
websiteUrl() und der Betriebsvorschlag des Fragebogens (routes/termine.js)
nutzen dieselbe Funktion.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 19:34:37 +00:00
ClaudeandClaude Sonnet 5.5 31aa80affd Terminplaner TP2: Fragebogen im Kontext und Speicher
kontext.js: ctx.fragebogen (normalisiert; fehlt er oder ist er kaputt, der leere,
kaputt mit einer Logzeile und ohne Wurf), ladeEinstellung liefert zusaetzlich
fragebogen, neuer kontextFuerPortal(feature) fuer das Portal in jedem Zustand.
speichereFragebogen schreibt unter termine-cfg:<id> nur fragebogen, updatedAt und
updatedBy (ohne version; fehlt das Dokument: 409 keine_einstellung). Neue Option
fragebogen bei speichereEinstellung schreibt Einstellung und Fragebogen in
derselben Sperre. kontextPerSiteKey bleibt unveraendert (Entwurf nie oeffentlich),
Tests dazu fuer off, ordered, setup, disabled und nach activate. Der Test
ladeEntwurf in funktionenCheckout.test.js schaltet die neue Logzeile stumm.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 19:14:22 +00:00
ClaudeandClaude Sonnet 5.5 008ad4fb1e Terminplaner TP2: Bestell-Gate und Gesundheits-Stichwortpruefung
fragebogen.js ersetzt den Stub aus Block B: bestellpruefung (Kriterien (a) bis (h),
je Punkt ein Eintrag, nach Schrittfolge sortiert, Abo-Punkt nur bei mitAbo !== false),
SCHRITT_TITEL, gesundheitsWarnungen (Stichworte nur am Wortanfang, hoechstens 10
Meldungen) und bestellungAnsicht fuer die Bestellseite. einstellungen.js exportiert
sichtbareLeistungen und MELDUNG_PFLICHT. Testhelfer bestellbarerStand und entwurfDoc;
der Stub-Test entfaellt, die zwei B-Tests mit dem Stub laufen gegen das echte Gate.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 19:00:12 +00:00
ClaudeandClaude Sonnet 5.5 ab47fabcb2 Terminplaner TP2: Fragebogen-Attribut, Branchen, Schritte, Normalisierung
termineConfig bekommt das Attribut fragebogen (Text 20000, Inhalt bis
FRAGEBOGEN_MAX 16000). fragebogen.js: SCHRITTE, BRANCHEN (Vorlagen plus
Gesundheitsbereich), leerFragebogen und normalisiereFragebogen.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 18:49:06 +00:00
ClaudeandClaude Sonnet 5.5 c5009da570 Abo-Ende: Sofortpfad beim Widerruf des Wechsels, Team-Aktivierung nur mit laufendem Abo
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 18:19:48 +00:00
ClaudeandClaude Sonnet 5.5 6bd6aed7d5 Terminplaner TP2 E8: Nachbesserung 1 (offener Zahlungsfall bleibt sichtbar, R108)
setzeFunktionZurueck setzt ein Funktionsdokument mit offenem Zahlungsfall
(zahlungMeldung nicht leer und nicht 'gemeldet') nicht auf off zurueck: Warnung
ohne Kennungen, +1 in lauf.fehler, kein Wurf. Das Dokument bleibt disabled mit
seinen Markern, der Abo-Abgleich holt T19 weiter nach, nach 'gemeldet' setzt der
naechste Lauf zurueck. Buchungen und Einstellung werden wie bisher geloescht.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 18:08:54 +00:00
ClaudeandClaude Sonnet 5.5 30701ba277 Löschung nach 30 Tagen: Abo-Vorprüfung, Funktionsdokument danach auf off
Bei Grund abo_ende prüft die Löschung vor jedem unumkehrbaren Schritt frisch,
ob das Wartungs-Abo wieder läuft (Lesefehler: nichts löschen). Sind alle
Buchungen und die Einstellung weg, wird das Funktionsdokument unter
feature-admin und termine-cfg auf off zurückgesetzt (siteKey bleibt).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 17:57:41 +00:00
ClaudeandClaude Sonnet 5.5 91e7f7d8a3 Tagesjob: Abo-Abgleich vor der Löschung, auch bei TERMINE_ENABLED=off mit bezahlten Dokumenten
taeglicherJob ruft gleicheAboAb(now) nach den Löschfristen und vor der Löschung
abgeschalteter Funktionen auf (Schritt „Abo-Abgleich“, ein Fehler dort stoppt weder
Löschung noch Rest; die Fehler des Abgleichs zählen in fehler). Das Ergebnis trägt
aboAbgleich, tagesbericht hängt „Abo-Abgleich N geprüft / N abgeschaltet / N wieder ein /
N Mails / N ausgenommen“ vor „N Fehler“ an.

fuehreAus nimmt trotzAus: Im Modus off läuft der Tagesjob nur, wenn es ein vom Kauf
freigeschaltetes Termine-Dokument gibt (eine Abfrage, limit 1; bei einem Lesefehler
Warnung und { aus: true }). Dann läuft ein eingeschränkter Lauf (eingeschraenkt: true,
gleiche Überlappungssperre): nur Abo-Abgleich und Löschung abgeschalteter Funktionen,
mit eigener Berichtszeile und den Feldern, die meldeTagesjob und die Statusroute lesen.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 17:45:48 +00:00
ClaudeandClaude Sonnet 5.5 1c74c89feb Terminplaner: Erstattungsmeldung unabhaengig vom Abo nachholen (R107)
Der taegliche Abo-Abgleich holt T19 fuer jedes bezahlte, abgeschaltete Dokument mit
Grund abo_ende_vor_einrichtung und zahlungMeldung ungleich gemeldet nach, auch wenn das
Wartungs-Abo wieder laeuft oder nicht lesbar ist (der Nachlauf liest das Abo nie).
Reihenfolge wie bisher: T19, dann K22 (nur wenn aboEndeMailAt leer), dann Marker.
meldeAboEnde sendet bei gesetztem K22-Marker und offener Erstattung nur T19.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 17:31:54 +00:00
ClaudeandClaude Sonnet 5.5 13523ca5e2 Abo-Abgleich: Rückkehr innerhalb der Frist schaltet wieder ein (K23)
Schritt 3 von gleicheAboAb: Ein abgeschaltetes Dokument mit Grund abo_ende,
dessen Wartungs-Abo wieder läuft, wird unter feature-admin:<projectId> nach
frischem Lesen von Dokument und Abo und mit vorhandener Einstellung über
activate wieder eingeschaltet (Daten und Einstellungen bleiben). K23 geht
nur, wenn K22 ging (aboEndeMailAt vor dem activate gelesen); scheitert K23,
bleibt die Reaktivierung bestehen. Nicht automatisch: off nach der Löschung,
abo_ende_vor_einrichtung, team, kunde_geloescht, Altbestand ohne Grund.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:44:47 +00:00
ClaudeandClaude Sonnet 5.5 addb88d5fd Abo-Abgleich: Abo endet vor der Einrichtung ⇒ abgeschaltet, T19 und K22
Terminplaner TP2 E5. Schritt 1b in gleicheAboAb: Dokumente im Zustand ordered
oder setup werden bei fehlendem Wartungs-Abo unter feature-admin:<projectId> nach
frischem Lesen von Dokument und Abo mit Grund abo_ende_vor_einrichtung abgeschaltet.
Die Meldelogik liegt in meldeAboEnde (auch für den Sofortpfad E9): bei bezahlter
Einrichtung zuerst T19 über meldeErstattung (außerhalb jeder feature-admin-Sperre),
dann K22 mit Block vor_einrichtung, dann der Marker aboEndeMailAt; scheitert T19,
folgen weder K22 noch Marker und der nächste Tag wiederholt beides. Ein unbezahltes
ordered-Dokument wird nur abgeschaltet. Schritt 2 holt auch abo_ende_vor_einrichtung
nach. Die Stripe-Sitzung und das Ticket bleiben unangetastet.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:32:14 +00:00
ClaudeandClaude Sonnet 5.5 17f933dbc7 Abo-Abgleich: aktive Terminplaner ohne Wartungs-Abo abschalten, K22 nachholen
gleicheAboAb(now) liest alle nicht abgeschalteten Terminplaner-Funktionen einmal,
bewertet je Kunde die Abo-Lage (aboMemo) und schaltet aktive, bezahlte Funktionen
ohne laufendes Wartungs-Abo ab (disabledReason abo_ende). Geschrieben wird nur
unter feature-admin:<projectId> nach frischem Lesen von Dokument und Abo; bei
Lesefehlern bleibt alles aktiv. Pilot- und Kulanz-Dokumente zaehlen als
ausgenommen. meldeAboEnde sendet K22 und setzt aboEndeMailAt erst nach Erfolg.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 14:20:57 +00:00
ClaudeandClaude Sonnet 5.5 35c9800856 Abschaltgrund und Loeschfrist in der Funktionsansicht (featureView, frist.js)
featureView liefert zusaetzlich disabledReason, disabledAt und loeschungAm (Berliner
Tag, 30 Tage nach disabledAt); alle drei nur im Zustand disabled, sonst null.
Neu termine/frist.js mit LOESCHFRIST_TAGE, loeschzeit und loeschTag (nur zeit.js/util.js).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 13:58:06 +00:00
ClaudeandClaude Sonnet 5.5 9dd0244537 Funktions-Ticket: Text aus dem Register, Laengendeckel, Notfall-Details und gezielte Wiederholung
markPaid holt Betreff und Details des Einrichtungs-Tickets aus dem Register (ticketTexte), createFeatureTicket
bleibt die einzige Stelle, die das Ticket anlegt. Betreff auf 128, Details auf 7000 Zeichen gekuerzt (surrogatsicher,
Schnitt an der Zeilengrenze, einheitliche Schlusszeile). Wirft die Details-Funktion oder liefert sie keinen Text,
gelten die Notfall-Details (Kopfzeilen und Verweis ins WOMS). Nach einem 400 bei langen Details gibt es genau einen
zweiten Versuch mit den Notfall-Details und derselben woid; 5xx, Netzfehler und kurze Details werden ohne
Wiederholung weitergereicht. Stub termine/ticketDetails.js bis Task D4.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 12:48:02 +00:00
ClaudeandClaude Sonnet 5.5 1f6ae0f7e0 Terminplaner TP2 B6: Nachbesserung 1
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 12:30:44 +00:00
ClaudeandClaude Sonnet 5.5 d568a3798d Abo-Baustein (Kernversion) und Platzhalter fuer die Bestellpruefung
aboStatus.js: laeuft(customerId) (Wartungs-Abo, productKey || 'wartung', Status in
ACTIVE_STATUSES), bestellbar(customerId) mit den Gruenden kein_abo, gekuendigt,
nicht_aktiv in dieser Pruefreihenfolge und aboMemo() (je Aufruf und Kunde nur eine
Lesung). Fail-closed: ein Lesefehler wirft, nie false oder ok:false.

termine/fragebogen.js: Platzhalter bestellpruefung() mit der endgueltigen Signatur,
liefert []; Block C ersetzt ihn.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 12:12:09 +00:00
ClaudeandClaude Sonnet 5.5 e2f50407a0 Terminplaner: Minutenjob in Verfall und Mailversand getrennt geschuetzt
fuehreAus nimmt { teil } und sperrt je job:teil; minutenJob startet Verfall
und Mailversand (Warteschlange plus Betriebspruefung) gemeinsam mit
Promise.all. Haengt ein Teil, laeuft der andere im naechsten Takt weiter
(verfallUebersprungen bzw. mailUebersprungen); uebersprungen gilt nur, wenn
beide Teile uebersprungen werden. Die Ueberlappungswarnung nennt den Teil,
das Fehlerlog behaelt minutenJob.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 11:41:00 +00:00
ClaudeandClaude Sonnet 5.5 39225594e5 Terminplaner: Status-Route fuer das Team
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 11:24:02 +00:00
ClaudeandClaude Sonnet 5.5 4601c5ef3b Terminplaner: Tagesjob-Meldung, Betriebe-Zaehlung und Bericht
meldeTagesjob meldet am Ende des Tagesjobs ueber den Melder aus A10a2 die Vorfaelle
tagesjob (Fehler oder Abbruch), deckel (Loeschdeckel an 3 Tagesjobs in Folge) und
betriebe (ab 20 aktiven Betrieben, D8) und merkt letzterTagesjob (nur Zaehlungen).
taeglicherJob liefert geloescht und aktiveBetriebe, tagesbericht haengt
"n aktive Betriebe" an.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 11:17:07 +00:00
ClaudeandClaude Sonnet 5.5 689a21f9ac Terminplaner: Betriebspruefung mit Abkuehlzeit fuer die Team-Mail
pruefeBetrieb (neu: termine/betrieb.js) prueft am Ende jedes Minutenjobs
Mailbudget (ab 70 %), Warteschlange (aeltester faelliger Eintrag > 10 Min
ueberfaellig, neu outbox.warteschlangeAlter) und Anmeldepause
(pausiertBis). Der gemeinsame Melder meldeVorfall schreibt je Schluessel
hoechstens stuendlich ein Warnlog und schickt die Team-Mail T20 beim
Beginn und danach fruehestens nach 6 Stunden; Lesefehler und Mailfehler
stehen nur im Log. T20 steht jetzt auch im Test der Team-Fusszeile.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 11:01:16 +00:00
ClaudeandClaude Sonnet 5.5 43b3caddde Terminplaner: veraltete G01 verworfen, Index bookingId
Eine G01, die erst nach holdMinutes + 1 Minute faellig wird, ist mit verfallenem Link
nutzlos: sie wird nicht mehr gesendet, sondern verworfen (kein Transportaufruf, kein
Budgetplatz, Felder geleert, kein Zustellfehler, raeumeAuf loescht sie nach 48 Stunden).
Neuer Index idx_booking auf termineOutbox fuer zustellFehler und verwerfeWartende;
verworfeneG01() zaehlt seit Prozessstart.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 10:21:25 +00:00
ClaudeandClaude Sonnet 5.5 36b94c3035 Terminplaner: Mail-Warteschlange begrenzt und nach Vorrang geordnet
verarbeite liest nicht mehr alle wartenden Eintraege, sondern je Klasse
(vorrang, normal, nachrangig) eine begrenzte Liste (config.termine.mailListe,
Standard 100) mit select und orderAsc(naechsterVersuch). Bei Pause oder
leerem Gesamtbudget endet der Lauf ohne Abfrage, bei erreichter Reserve
entfaellt die nachrangige Klasse. Funktionen mit ausgeschoepftem Kontingent
kommen in eine Ausschlussliste (hoechstens 90 Werte); hoechstens vier weitere
Runden je Klasse, damit keine Funktion hinter einer vollen verhungert.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 10:13:26 +00:00
ClaudeandClaude Sonnet 5.5 4d96565240 Terminplaner: Empfaenger-Kappe ueber Betriebe (G01, Freitext in G04/G06)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 10:03:39 +00:00
ClaudeandClaude Sonnet 5.5 c35711caad Terminplaner: Mailkontingent je Funktion, Vorrang-Reserve und kleinere Haltungsgrenze
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 09:54:11 +00:00
ClaudeandClaude Sonnet 5.5 978722023f Terminplaner: Zellen-Sweep seitenweise ueber idx_bis mit Deckel
raeumeVerwaisteZellen(now, { deckel = config.termine.zellenDeckel }) liest
Zellen mit bis < jetzt - 1 Tag in Seiten zu 100 ueber idx_bis (aelteste
zuerst, ohne Cursor neu gelesen), gruppiert je Ressourcensperre mit Map und
loescht unter der Sperre nur, was dort noch dieselbe Buchung hat und noch alt
ist. Die Buchungen werden nicht gelesen. Der Lauf endet am Deckel (5000,
gedeckelt wird im Tagesjob gezaehlt und im Log gewarnt), bei einer leeren
Seite oder einer Seite ohne Erfolg; der erste Fehler wird am Ende geworfen.
ungueltigeZellen prueft zuerst das Zeitfenster (auch fuer belegeZellen).
verwaisteZellen, alleZellen und ALLE_ZELLEN_MAX entfallen.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 09:44:47 +00:00
ClaudeandClaude Sonnet 5.5 d040a55f89 Terminplaner: CSV-Export seitenweise gestreamt
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 09:32:14 +00:00
ClaudeandClaude Sonnet 5.5 a1732613c9 Terminplaner: Loeschung abgeschalteter Funktionen seitenweise, Rest an Folgetagen
loescheAbgeschaltete liest je abgeschalteter Funktion (disabledAt vor 30 Tagen) Seiten zu 100
(neu buchungen.ersteBuchungen: nur $id, limit, nie Gastfelder) und loescht sie ueber arbeiteSeiten
samt Zellen, bis die Seite leer ist. Die Funktion wird nach jedem Lesen einer Seite und alle 50
Buchungen frisch geprueft (nochAbgeschaltet); wird sie wieder eingeschaltet, endet die Loeschung
fuer sie sofort. Deckel config.termine.loeschDeckel je Funktion: am Deckel bleibt die Funktion
disabled mit altem disabledAt, eine Warnung ohne Kennungen steht im Log, der naechste Tag macht
weiter, die uebrigen Funktionen kommen im selben Lauf dran. Die Einstellung (termineConfig) wird
nur nach leerer Seite ohne Fehler und mit letzter Pruefung unter termine-cfg:<id> geloescht.
loescheAbgeschalteteFunktionen liefert { funktionen, buchungen, gedeckelt }; taeglicherJob traegt
gedeckelt.abgeschaltet getrennt vom Loeschzaehler ein (Tagesbericht: Loeschlaeufe am Deckel).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 09:24:33 +00:00
ClaudeandClaude Sonnet 5.5 9b4305e5de Terminplaner: Aufbewahrungs-Loeschung je Funktion mit Deckel, Sicherheitsnetz und Bericht
erledigt/nichterschienen werden jetzt je Funktion (portalFeatures termine, active|disabled)
nach deren aufbewahrungTage seitenweise geloescht; beide Status teilen sich den Deckel
loeschDeckel der Funktion, alle Schritte eines Laufs zusammen loeschDeckelGesamt (neu,
Standard 20000). Ein Sicherheitsnetz loescht erledigt/nichterschienen ohne Funktionsfilter
nach 365 Tagen (Buchungen ohne Funktionsdokument, unlesbare Einstellung). Der Tagesbericht
nennt "Loeschlaeufe am Deckel: n, Rest folgt an den nächsten Tagen" nur bei gedeckelt > 0.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 09:09:48 +00:00
ClaudeandClaude Sonnet 5.5 5c95dfc322 Terminplaner: Aufbewahrungs-Loeschung seitenweise (Grundlagen, verfallen/abgesagt/abgelehnt)
loeschKandidaten liest eine Seite (Standard 100, aelteste Bezugszeit zuerst, optional je Funktion)
ohne Gastfelder; die Frist steht in der Abfrage. arbeiteSeiten (Seite lesen, bearbeiten, neu lesen)
endet bei leerer Seite, am Deckel (config.termine.loeschDeckel, 2000 je Status und Lauf, Rest an den
Folgetagen, gezaehlt als gedeckelt) oder bei einer Seite ohne Fortschritt. verfallen, abgesagt und
abgelehnt laufen darueber, unter der Buchungssperre werden Status und Bezugszeit frisch geprueft.
taeglicherJob liefert gedeckelt getrennt vom Loeschzaehler. Neue Indizes idx_status_ends und
idx_status_updated auf termineBookings (scripts/termine-setup.mjs legt sie an).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-04 08:55:32 +00:00
ClaudeandClaude Opus 5.5 3a0b0089dd Terminplaner: eigener Betreff fuer die Ablehnung einer Anfrage (G04)
Eingang (G03) und Ablehnung (G04) hatten denselben Betreff "Ihre Terminanfrage bei {betrieb}".
G04 heisst jetzt "Ihre/Deine Terminanfrage bei {betrieb} – leider abgelehnt".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 17:40:52 +00:00
ClaudeandClaude Opus 5.5 5bd8ee8457 Terminplaner: Abschluss – kein "null" in abgeschalteten Einstellungen, Kommentar zu disabledAt
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-03 08:17:44 +00:00
ClaudeandClaude Sonnet 5.5 bd65c9dc58 Terminplaner: Abschluss – Server (Widerruf auch bei Anfragen, Gastdaten löschen vollständig, formMinSekunden)
- R55: Widerrufsbelehrung, Anschrift-Pflicht und Knopf "Vertrag widerrufen" gelten für jede
  Verbraucher-Buchung mit sichtbarer Leistung, auch Anfragen (zeigtWiderruf); der Nachweis
  hält die Belehrung auch bei Anfragen fest. Damit bleibt die Annahme einer Anfrage nie mehr
  still ohne G02.
- "Gastdaten löschen" leert auch absageGrund und löscht noch nicht versandte Mails der Buchung
  (neu: verwerfeWartende in der Warteschlange).
- R53: GET /:siteKey/config nennt formMinSekunden.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 08:17:44 +00:00
ClaudeandClaude Sonnet 5.5 4465ac7b94 Terminplaner: Einbau-Skript – Nachbesserungen
429 ohne Schleife (Meldung und Erneut-versuchen-Knopf, Formulare bleiben stehen), Schriftfarbe
auf der Betriebsfarbe mit mindestens 4,5 : 1, AGB-Link aus der oeffentlichen Konfiguration
(betrieb.agbUrl), Haken starten bei geaenderter Auswahl ohne Haken, Fehler ohne Feld nicht
verschluckt, Konfiguration fail closed, ladeNeu fuer Neuladen und neu_laden, Tastatur und
Fokus (Modifikatoren, Monatspfeile, Belehrungstext), Aufraeumen. UI-Testserver: Timer,
offene Verbindungen, Hinweis auf sessionCookie.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 08:17:44 +00:00
ClaudeandClaude Sonnet 5.5 bb45d35ec7 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>
2026-10-03 08:17:43 +00:00
ClaudeandClaude Sonnet 5.5 e3e198fb1a Terminplaner: Kunden-Schnittstelle
/api/termine: Einstellungen (Vorlage, PATCH mit Version, Feed-Link), Buchungen
(Liste, Zeiten, von Hand, Sperre, Aktionen), CSV-Export, Protokoll der
Kundenansicht. Pflichtangaben fuer Gaeste (Telefon immer, Anschrift bei
Widerrufsbelehrung) in normalisiereEinstellung, Entwurf aus Vorlagen,
kontextPerSiteKey ohne Pflichtangaben nicht buchbar; speichereEinstellung
nimmt eine Funktion unter der Sperre.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 08:17:43 +00:00
ClaudeandClaude Sonnet 5.5 9e8fd33713 Funktionen: Terminplaner als zweite Funktion (Team-Route, Kundenansicht)
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-03 08:17:43 +00:00