From c7cd436ec2e8a38f0f6f769b7026bf467e08d9bb Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 6 Oct 2026 06:00:17 +0000 Subject: [PATCH] =?UTF-8?q?=C3=96ffnungszeiten:=20Mails=20K24=E2=80=93K27?= =?UTF-8?q?=20hei=C3=9Fen=20jetzt=20K27=E2=80=93K30,=20Feld=20k24At=20hei?= =?UTF-8?q?=C3=9Ft=20einschaltMailAt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit K24–K26 sind seit dem Webshop-Livegang (main) vergeben; der Mail-Lader sucht die Vorlage über den Dateianfang, doppelte Nummern hätten die falsche Mail geschickt. Das Feld ist noch nicht in der Produktion angelegt (zeiten-setup.mjs lief noch nicht), daher jetzt ein sprechender Name. Spec und Plan behalten die alten Nummern (Hinweis oben im Dokument). Co-Authored-By: Claude Opus 5.5 --- docs/funktionen/zeiten-einbau.md | 4 +- docs/rechtliches/zeiten-k02-k03-entwurf.md | 6 +- docs/rechtliches/zeiten-kanzlei-fragen.md | 6 +- ...026-10-04-oeffnungszeiten-live-livegang.md | 10 +- .../plans/2026-10-04-oeffnungszeiten-live.md | 2 + .../2026-10-04-oeffnungszeiten-live-design.md | 2 + public/funktionen.js | 2 +- public/zeiten-bestellen.js | 2 +- scripts/zeiten-setup.mjs | 2 +- ...tet.html => K27 Zeiten eingeschaltet.html} | 2 +- ...html => K28 Zeiten Feiertage pruefen.html} | 2 +- ...endet.html => K29 Zeiten Abo beendet.html} | 2 +- ...ltet.html => K30 Zeiten abgeschaltet.html} | 2 +- server/routes/admin/funktionenAdmin.js | 2 +- server/routes/funktionen.js | 2 +- server/services/siteFeatures.js | 6 +- server/services/zeiten/aboAbgleich.js | 82 +++++----- server/services/zeiten/einschalten.js | 28 ++-- server/services/zeiten/erinnerung.js | 10 +- server/services/zeiten/mails.js | 40 ++--- server/services/zeiten/schema.js | 4 +- test/mailTemplates.test.js | 15 +- test/zeitenAboAbgleich.test.js | 152 +++++++++--------- test/zeitenActivate.test.js | 2 +- test/zeitenBehalten.test.js | 2 +- test/zeitenCheckout.test.js | 6 +- test/zeitenEinschalten.test.js | 50 +++--- test/zeitenErinnerung.test.js | 6 +- test/zeitenFreischalten.test.js | 78 ++++----- test/zeitenJobs.test.js | 6 +- test/zeitenMails.test.js | 146 ++++++++--------- test/zeitenSetup.test.js | 14 +- test/zeitenTeam.test.js | 16 +- test/zeitenTeamBehalten.test.js | 2 +- 34 files changed, 359 insertions(+), 354 deletions(-) rename server/mail-templates/{K24 Zeiten eingeschaltet.html => K27 Zeiten eingeschaltet.html} (99%) rename server/mail-templates/{K25 Zeiten Feiertage pruefen.html => K28 Zeiten Feiertage pruefen.html} (99%) rename server/mail-templates/{K26 Zeiten Abo beendet.html => K29 Zeiten Abo beendet.html} (99%) rename server/mail-templates/{K27 Zeiten abgeschaltet.html => K30 Zeiten abgeschaltet.html} (99%) diff --git a/docs/funktionen/zeiten-einbau.md b/docs/funktionen/zeiten-einbau.md index dae8825..02bfa2a 100644 --- a/docs/funktionen/zeiten-einbau.md +++ b/docs/funktionen/zeiten-einbau.md @@ -58,7 +58,7 @@ Jeder Platzhalter behält eine **statische Ersatz-Tabelle**: Sie steht ohne Java 1. WOMS → Funktionen → Ersatz-HTML kopieren (je Plan ein Knopf; bei mehreren Plänen mit Namen dahinter). Erst nach dem ersten Speichern des Kunden; vorher meldet das WOMS „Der Kunde hat noch keine Zeiten eingetragen“ (die Schnittstelle antwortet 409: `GET /api/team/funktionen/:customerId/zeiten/ersatz?projectId=…&plan=`). 2. In jeden Platzhalter einsetzen. Das Ersatz-HTML ist eine schlichte Wochentabelle als reines ASCII mit Entities (`ä`, `–`), also in jeder Dateikodierung sicher. Ein Fensterende um Mitternacht steht als `00:00` („18:00–00:00“), ein Fenster von 00:00 bis 24:00 als „rund um die Uhr“. 3. Die Tabelle zeigt den Wochenplan **zum Zeitpunkt des Einbaus**. Ändert der Kunde seinen Wochenplan später, bleibt das Ersatz-HTML zunächst stehen (mit Skript unsichtbar). -4. **Beim Abschalten** der Funktion, wenn der aktuelle Wochenplan des Hauptplans vom Stand beim Einbau abweicht, entsteht ein WOMS-Ticket **„Ersatz-Tabelle aktualisieren – “** mit dem aktuellen Ersatz-HTML. Ersetze die Tabelle in allen Platzhaltern (gehört zum enthaltenen Einbau, Leistungsbeschreibung Nr. 4 Abs. 3). Die Mail K27 sagt dem Kunden, dass wieder feste Zeiten auf der Seite stehen. Liegt die Seite woanders, schicke dem Kunden den Text. +4. **Beim Abschalten** der Funktion, wenn der aktuelle Wochenplan des Hauptplans vom Stand beim Einbau abweicht, entsteht ein WOMS-Ticket **„Ersatz-Tabelle aktualisieren – “** mit dem aktuellen Ersatz-HTML. Ersetze die Tabelle in allen Platzhaltern (gehört zum enthaltenen Einbau, Leistungsbeschreibung Nr. 4 Abs. 3). Die Mail K30 sagt dem Kunden, dass wieder feste Zeiten auf der Seite stehen. Liegt die Seite woanders, schicke dem Kunden den Text. ## 5. Header-Selektor (`navSelektor`) @@ -108,7 +108,7 @@ Zur Abnahme außerdem: Seite in der Vorschau öffnen und mit ausgeschaltetem Jav ## 10. Freischalten und Ende - **Freischalten:** Der Job setzt `active` (und sendet K16), wenn das Ticket geschlossen ist und der Kunde Zeiten eingetragen hat (Hauptplan gespeichert, mindestens ein Tag nicht „zu“). Sonst bleibt `setup`, das WOMS zeigt „wartet auf die Zeiten des Kunden“. Solange der Kunde nichts eingetragen hat, kannst Du die Tabelle nicht einbauen. -- **Ende des Abos** (Gratisweg): K26 mit Frist zum Behalten (30 Tage), danach `disabled` und K27, Eingaben noch 30 Tage, dann gelöscht. Das Ticket „Ersatz-Tabelle aktualisieren“ gehört zum Abschalten (Abschnitt 4). +- **Ende des Abos** (Gratisweg): K29 mit Frist zum Behalten (30 Tage), danach `disabled` und K30, Eingaben noch 30 Tage, dann gelöscht. Das Ticket „Ersatz-Tabelle aktualisieren“ gehört zum Abschalten (Abschnitt 4). - **Abschalten durch das Team** (Grund `team`): keine automatische Löschung. ## 11. Häufige Fehlerbilder diff --git a/docs/rechtliches/zeiten-k02-k03-entwurf.md b/docs/rechtliches/zeiten-k02-k03-entwurf.md index bae0005..148cd15 100644 --- a/docs/rechtliches/zeiten-k02-k03-entwurf.md +++ b/docs/rechtliches/zeiten-k02-k03-entwurf.md @@ -26,18 +26,18 @@ Warum so: - Der Satz ist bedingt („Haben Sie … eingeschaltet“), weil der Block bei jeder Kündigung eines Wartungs-Abos erscheint, auch bei Kunden ohne die Funktion. - Wer die Funktion für 30 € bestellt hat, behält sie ohne Abo (Leistungsbeschreibung Nr. 9 Abs. 2 letzter Satz); für ihn gilt der Satz nicht, was die Bedingung „im Wartungs-Abo eingeschaltet“ ausdrückt. Ein eigener Satz dazu wäre in einer Kündigungsbestätigung verwirrend. -- Die Einzelheiten (Frist mit Datum, Knopf „Behalten“) sagt K26 („Wartungs-Abo beendet“), sobald das Ende des Abos erkannt ist; K02 und K03 sagen nur, dass es das gibt. +- Die Einzelheiten (Frist mit Datum, Knopf „Behalten“) sagt K29 („Wartungs-Abo beendet“), sobald das Ende des Abos erkannt ist; K02 und K03 sagen nur, dass es das gibt. - „Abschalten“ bedeutet: Hinweis-Leiste, Kontakt-Leiste, Status und Google-Angaben verschwinden, die feste Ersatz-Tabelle der Website bleibt stehen (Leistungsbeschreibung Nr. 9 Abs. 4). Im HTML ändert sich nur der Inhalt der Zelle zwischen `` und ``; Aufbau und Blockkommentare bleiben. Die Kopfkommentare beider Vorlagen sagen dann „Website-Analyse, Terminplaner und Öffnungszeiten live“. ## Alternative -Ein eigener Block `zeiten` (nur für Kunden, bei denen die Funktion im Abo läuft): kein Text für Kunden ohne Funktion und die Zeile steht ohne „Haben Sie …“. Dafür braucht das Programm in `server/routes/abo.js` an beiden Stellen eine zusätzliche Abfrage der Funktion, beide Vorlagen einen neuen Block, und die Pins im Mail-Pin-Test (K01 bis K27) ändern sich. Nur sinnvoll, wenn der Inhaber den bedingten Satz nicht möchte. +Ein eigener Block `zeiten` (nur für Kunden, bei denen die Funktion im Abo läuft): kein Text für Kunden ohne Funktion und die Zeile steht ohne „Haben Sie …“. Dafür braucht das Programm in `server/routes/abo.js` an beiden Stellen eine zusätzliche Abfrage der Funktion, beide Vorlagen einen neuen Block, und die Pins im Mail-Pin-Test (K01 bis K30) ändern sich. Nur sinnvoll, wenn der Inhaber den bedingten Satz nicht möchte. ## Beim Übernehmen 1. Vorlagen K02 und K03 ändern (Zelle des Blocks, Kopfkommentar). 2. `test/mailTemplates.test.js` (K02/K03-Test): zusätzlicher Wortlaut-Pin für den neuen Satz; die bestehenden Prüfungen bleiben. -3. Den Mail-Pin-Test (K01 bis K27, ebenfalls `test/mailTemplates.test.js`) und, falls sich der Block ändert, die Prüfung in `test/publicForms.test.js` nachziehen. +3. Den Mail-Pin-Test (K01 bis K30, ebenfalls `test/mailTemplates.test.js`) und, falls sich der Block ändert, die Prüfung in `test/publicForms.test.js` nachziehen. 4. Kanzlei-Frage `ZQ5` (Ende mit dem Abo, 30 Tage zum Behalten) in `zeiten-kanzlei-fragen.md` abwarten, weil sie den Inhalt des Satzes betrifft. diff --git a/docs/rechtliches/zeiten-kanzlei-fragen.md b/docs/rechtliches/zeiten-kanzlei-fragen.md index 49841ca..2657c4d 100644 --- a/docs/rechtliches/zeiten-kanzlei-fragen.md +++ b/docs/rechtliches/zeiten-kanzlei-fragen.md @@ -60,13 +60,13 @@ Reihenfolge der Rechtsrunde (gemeinsam mit TP2): gemeinsame Bausteine (TP2 Block ### ZQ6: Mails zur Funktion: Erinnerung vor Feiertagen und Zustandsmails -**Frage.** WEBklar sendet dem Kunden E-Mails: K24 (eingeschaltet), K25 (Erinnerung 1 bis 7 Tage vor einem Feiertag oder einem Prüftag: „Stimmen Ihre Zeiten an diesen Tagen?“, mit einem Knopf zum Editor und dem Hinweis, die Zeiten auch bei Google einzutragen), K26 (Wartungs-Abo beendet, Frist, „für einmalig 30 € behalten“), K27 (abgeschaltet). Sind das Vertragsmails (Art. 6 Abs. 1 lit. b DSGVO) ohne Einwilligung, oder wirkt K25 wegen des Hinweises „bei Google auch eintragen“ oder des Verweises auf die Funktion als Werbung (§ 7 UWG, Art. 6 Abs. 1 lit. f DSGVO mit Widerspruchsmöglichkeit)? Muss K25 einen Hinweis zum Abbestellen tragen? Die Erinnerung lässt sich im Programm nicht abschalten; der Kunde kann nur die Funktion abschalten lassen. +**Frage.** WEBklar sendet dem Kunden E-Mails: K27 (eingeschaltet), K28 (Erinnerung 1 bis 7 Tage vor einem Feiertag oder einem Prüftag: „Stimmen Ihre Zeiten an diesen Tagen?“, mit einem Knopf zum Editor und dem Hinweis, die Zeiten auch bei Google einzutragen), K29 (Wartungs-Abo beendet, Frist, „für einmalig 30 € behalten“), K30 (abgeschaltet). Sind das Vertragsmails (Art. 6 Abs. 1 lit. b DSGVO) ohne Einwilligung, oder wirkt K28 wegen des Hinweises „bei Google auch eintragen“ oder des Verweises auf die Funktion als Werbung (§ 7 UWG, Art. 6 Abs. 1 lit. f DSGVO mit Widerspruchsmöglichkeit)? Muss K28 einen Hinweis zum Abbestellen tragen? Die Erinnerung lässt sich im Programm nicht abschalten; der Kunde kann nur die Funktion abschalten lassen. -**Fundstelle im Text.** Abschnitt 6d Absatz 3; LB Nr. 2 Abs. 2; Mailvorlagen K24 bis K27 (`server/mail-templates/`), Spec Abschnitt 7 (K25: eine Mail für alle neuen Tage, Merker, 08:00 bis 20:00 Uhr Berliner Zeit, kein BCC ans Team). +**Fundstelle im Text.** Abschnitt 6d Absatz 3; LB Nr. 2 Abs. 2; Mailvorlagen K27 bis K30 (`server/mail-templates/`), Spec Abschnitt 7 (K28: eine Mail für alle neuen Tage, Merker, 08:00 bis 20:00 Uhr Berliner Zeit, kein BCC ans Team). **Unsere Annahme.** Die Erinnerung ist Teil der vertraglichen Leistung (LB Nr. 2 Abs. 2) und deshalb eine Vertragsmail ohne Einwilligung; der Hinweis auf Google dient der Durchführung (die Zeiten dort aktuell zu halten), nicht der Werbung. -**Alternative.** Hinweis auf Google aus K25 streichen; einen Abbestell-Link („Erinnerungen ausschalten“) mit Einstellung im Editor vorsehen. +**Alternative.** Hinweis auf Google aus K28 streichen; einen Abbestell-Link („Erinnerungen ausschalten“) mit Einstellung im Editor vorsehen. ### ZQ7: Einstellung ohne Grund bei Unternehmern im Gratisweg (LB Nr. 10 Abs. 4) diff --git a/docs/superpowers/plans/2026-10-04-oeffnungszeiten-live-livegang.md b/docs/superpowers/plans/2026-10-04-oeffnungszeiten-live-livegang.md index 0e6aadd..04d9ec4 100644 --- a/docs/superpowers/plans/2026-10-04-oeffnungszeiten-live-livegang.md +++ b/docs/superpowers/plans/2026-10-04-oeffnungszeiten-live-livegang.md @@ -27,7 +27,7 @@ Nach der Fixrunde (Abschlussprüfung, 05.10.2026), alles grün: Portal 4564/4564 - UI, je einzeln mit `nice` und vorher `free -m`: `test/ui/zeiten-embed.ui.mjs`, `test/ui/zeiten-portal.ui.mjs`, `test/ui/funktionen.ui.mjs` 3. **WOMS neu aufsetzen.** In `ticket.webklar.com/dev-zeiten`: die WOMS-Hauptlinie (`test`, mit TP2) hineinführen (`git fetch origin && git merge origin/test`). Erwarteter Konflikt (1 Datei): `src/components/customer/CustomerFunktionen.jsx`; dort bleiben unser `ersatzTicket` **und** TP2s `speicherStatus`/`K16_WARNUNG` (TP2 `4c3f67e` ändert dieselben `save()`-Zeilen sowie das Ende von `src/lib/funktionenView.js` und seinen Test, das Portal fügt dieselbe POST-Route um `warnung` ein). `K16_WARNUNG` nennt einen „AVV“, den Öffnungszeiten live nicht hat: nach der Zusammenführung prüfen und für die Zeiten anpassen. Danach `nice npm test` und `nice npx vite build`. `node_modules` ist dort im Git verfolgt und wurde von `npm ci` verändert: **nie stagen**. 4. **Relaunch prüfen.** `git log --oneline 4139f31..main` im Relaunch-Repo; gibt es neue Commits, `feature/zeiten-station` darauf aufsetzen, dann `nice npm test`, `nice npm run build` und `gzip -9 -c dist/assets/index-*.js | wc -c` (höchstens 133 120). -5. **Schema anlegen, vor dem Portal-Deploy.** `scripts/zeiten-setup.mjs` legt `oeffnungszeiten` und `zeitenErinnerungen` an und ergänzt `portalFeatures` um `unlockedBy`, `aboEndeAt`, `einbau`, `behaltenSessionId`, `k24At`. Seit der Fixrunde schreibt `activate()` `aboEndeAt` und `behaltenSessionId` nur noch für Öffnungszeiten live (Parameter `extra`); News und Terminplaner brauchen die Felder nicht mehr und laufen auch vor dem Skript. Trotzdem erst das Schema, dann der Deploy: die Zeiten-Pfade schreiben die Felder. Das Skript braucht den neuen Code, also aus dem Worktree in einem Wegwerf-Container (kein `docker compose run`: der Container bekäme die Traefik-Labels des Portals). Die Env-Datei enthält Zugangsdaten: mit `umask 077` anlegen, nicht erst danach `chmod`. Erst `--check` (beim ersten Lauf Exit 1, erwartet: es fehlt ja noch alles), dann ohne, dann **noch einmal `--check`** (muss grün sein; die Index-Reihenfolge der Schema-Skripte hat am 30.09. schon einmal überrascht): +5. **Schema anlegen, vor dem Portal-Deploy.** `scripts/zeiten-setup.mjs` legt `oeffnungszeiten` und `zeitenErinnerungen` an und ergänzt `portalFeatures` um `unlockedBy`, `aboEndeAt`, `einbau`, `behaltenSessionId`, `einschaltMailAt`. Seit der Fixrunde schreibt `activate()` `aboEndeAt` und `behaltenSessionId` nur noch für Öffnungszeiten live (Parameter `extra`); News und Terminplaner brauchen die Felder nicht mehr und laufen auch vor dem Skript. Trotzdem erst das Schema, dann der Deploy: die Zeiten-Pfade schreiben die Felder. Das Skript braucht den neuen Code, also aus dem Worktree in einem Wegwerf-Container (kein `docker compose run`: der Container bekäme die Traefik-Labels des Portals). Die Env-Datei enthält Zugangsdaten: mit `umask 077` anlegen, nicht erst danach `chmod`. Erst `--check` (beim ersten Lauf Exit 1, erwartet: es fehlt ja noch alles), dann ohne, dann **noch einmal `--check`** (muss grün sein; die Index-Reihenfolge der Schema-Skripte hat am 30.09. schon einmal überrascht): ``` (umask 077; docker inspect webklar-kundenbereich-server -f '{{range .Config.Env}}{{println .}}{{end}}' > /root/zeiten-env.tmp) docker run --rm --env-file /root/zeiten-env.tmp --network webklar-network -v /home/webklar/apps/kundenbereich.webklar.com/dev-zeiten:/app:ro -w /app node:20-alpine node scripts/zeiten-setup.mjs --check @@ -58,11 +58,11 @@ Nach der Fixrunde (Abschlussprüfung, 05.10.2026), alles grün: Portal 4564/4564 Nur dein Konto sieht die Kachel. Beachte: Das Portal prüft nur „Leistungsbeschreibung vorhanden“, nicht „freigegeben“ (`unterlagenBereit` ist für Zeiten immer wahr). Der Pilot ist deshalb der einzige Schutz vor dem Entwurfstext, bis `on` kommt. 1. Kachel im Funktionen-Tab sichtbar. Je nach Konto: „Einschalten“ (Wartungs-Abo aktiv) oder „30 € einmalig“. Den Bezahlweg nur mit echter 30-€-Zahlung testen (danach erstatten) oder weglassen; die Tests decken ihn ab. -2. Einschalten: Ticket „Öffnungszeiten live einbauen“ in WOMS, Mail K24, `einbau` = `angestossen` (Runner-Log) oder `manuell`. +2. Einschalten: Ticket „Öffnungszeiten live einbauen“ in WOMS, Mail K27, `einbau` = `angestossen` (Runner-Log) oder `manuell`. 3. Editor: Wochenplan mit Fenstern und Mitternacht, zweiter Plan, Bundesland und Feiertage, Urlaub (Hinweis-Vorschlag), Hinweis-Leiste, Kontakt-Leiste mit Telefon und Adresse, „Für Google kopieren“, Uhrzeit-Regler. 4. Preview der `test-website` nach dem Neubau: im Quelltext `