From 67c913892991bd3fb299025875b25198a9c450f5 Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 29 Oct 2026 12:27:05 +0000 Subject: [PATCH] Kundenansicht neu P10: Checkliste nach der Querpruefung (Kaeufe vor dem Stopp, Push mit Zugang, echte Schalterwerte, PDF-Inhalt, Wartezeit nach dem Neustart, alte Tabs) Co-Authored-By: Claude Opus 5.5 --- docs/umschalten-kundenansicht.md | 17 +++++++++-------- test/knUmschaltCheckliste.test.js | 3 +++ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/docs/umschalten-kundenansicht.md b/docs/umschalten-kundenansicht.md index 36e9392..9a32519 100644 --- a/docs/umschalten-kundenansicht.md +++ b/docs/umschalten-kundenansicht.md @@ -10,7 +10,7 @@ Anleitung für Inhaber und Controller, Reihenfolge laut Spec 5.10: Kundenart set 1. Du hast Vorschau, Pilot und Fassung 6 freigegeben und ausdrücklich „umschalten“ gesagt. Der Hauptzweig des Portals ist nach Phase E fertig (P0 bis P8 und die freigegebene Rechtsrunde), `WORTLAUT_STATUS` steht auf `'freigegeben'`; das WOMS-Paket P9 prüft Abschnitt 4. 2. Teil A prüfen und taggen (erwartet: `fail 0`, Status leer): `cd /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 && timeout 900 nice -n 10 node --max-old-space-size=1024 --test --test-concurrency=1 test/kundenartBestand.test.js test/knUmschaltSeiten.test.js test/knUmschaltNachpruefung.test.js test/kaufBestandPruefen.test.js test/knUmschaltCheckliste.test.js test/kundenansichtDashboard.test.js test/adminPanelGone.test.js test/legalDocs.test.js && git status --short && git tag kn-p10-a` -3. **Stop: Inhaber-OK nötig** (Push, Teil A ändert für Kunden nichts, solange der Schalter nicht `on` ist): `cd /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 && git fetch origin && git log --oneline origin/main..kn-p10-a`, dann `git push origin 'kn-p10-a^{commit}:refs/heads/main'`. Fragt git nach dem Passwort (HTTP 401), pushst du wie bisher mit `/root/reports/workers-2026-10-16/push-mit-zugang.sh`. +3. **Stop: Inhaber-OK nötig** (Push, Teil A ändert für Kunden nichts, solange der Schalter nicht `on` ist): `cd /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 && git fetch origin && git log --oneline origin/main..kn-p10-a`, dann `git push origin 'kn-p10-a^{commit}:refs/heads/main'`. Fragt git nach dem Passwort (HTTP 401, der Zugang steckt in der Remote-Adresse), pushst du den Zweig mit Zugang: `cd /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 && git fetch origin && bash /root/reports/workers-2026-10-16/push-mit-zugang.sh /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 feature/kn-p10-a main "$(git rev-parse origin/main)" "$(git rev-parse --short=7 kn-p10-a)"` (letzte Zeile `✓ origin/main = …`). Für spätere Pushes gilt dasselbe mit dem jeweiligen Zweig. 4. Deploy prüfen (beide Kurzformen gleich, sonst zwei Minuten warten; im Log kein `Unbehandelter Fehler`): `git -C /home/webklar/apps/kundenbereich.webklar.com/build rev-parse --short HEAD && git -C /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 rev-parse --short kn-p10-a && docker logs --since 5m webklar-kundenbereich-server 2>&1 | tail -5` 5. Ruhezustand (Exit 0, alle Zeilen `ok`): `cd /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 && node scripts/umschalten-nachpruefung.mjs https://project.webklar.com --erwartet=alt` @@ -40,27 +40,28 @@ Anleitung für Inhaber und Controller, Reihenfolge laut Spec 5.10: Kundenart set 1. Kundenart (Vorflug): `docker exec -w /app webklar-kundenbereich-server node scripts/kundenart-bestand.mjs --pruefen | command grep -a "Ohne Kundenart"`. Erwartet `Ohne Kundenart: 0`, sonst Abschnitt 2 wiederholen (ein Lead, der seitdem entstand, ist normal). 2. Setup und Wortlaut: `docker exec -w /app webklar-kundenbereich-server node scripts/kundenansicht-setup.mjs --pruefen; docker exec -w /app webklar-kundenbereich-server grep -n "WORTLAUT_STATUS" server/services/bestelltexte.js`. Erwartet: keine fehlenden Attribute (insbesondere `featureConsents.kundenart`, sonst scheitert jede Bestellung der neuen Ansicht mit 500) und `'freigegeben'`. Das Setup selbst läuft nur auf Anweisung nach deinem OK. 3. Schalter in Compose und `.env`: `command grep -a -n 'KUNDENANSICHT_NEU' /home/webklar/apps/docker-compose.yml; command grep -a -n '^KUNDENANSICHT_NEU' /home/webklar/apps/.env`. Erwartet in `docker-compose.yml` zwei Zeilen `- KUNDENANSICHT_NEU=${KUNDENANSICHT_NEU:-off}` und `- KUNDENANSICHT_NEU_PILOT_EMAILS=${KUNDENANSICHT_NEU_PILOT_EMAILS:-}`, in `.env` `KUNDENANSICHT_NEU=pilot` und die Pilot-Liste. Fehlt eine Compose-Zeile, meldet der Controller es und wartet auf die Korrektur. -4. Katalog-Schalter, du bestätigst jeden Wert: `command grep -a -n '^\(ABO_PILOT_EMAILS\|TERMINE_ENABLED\|SHOP_ENABLED\|UNTERKUNFT_ENABLED\|ZEITEN_ENABLED\|ANALYSE_ENABLED\|AUFTRAEGE_ENABLED\)=' /home/webklar/apps/.env`. `ABO_PILOT_EMAILS` muss `*` sein (sonst antwortet jede Abo-Bestellung eines Nicht-Pilot-Kunden mit 403); `ANALYSE_ENABLED` und `AUFTRAEGE_ENABLED` bleiben `off`, bis ihre eigenen Livegänge erledigt sind. +4. Katalog-Schalter, du bestätigst jeden Wert: `command grep -a -n '^\(ABO_PILOT_EMAILS\|TERMINE_ENABLED\|SHOP_ENABLED\|UNTERKUNFT_ENABLED\|ZEITEN_ENABLED\|ANALYSE_ENABLED\|AUFTRAEGE_ENABLED\)=' /home/webklar/apps/.env`. `ABO_PILOT_EMAILS` muss `*` sein (sonst antwortet jede Abo-Bestellung eines Nicht-Pilot-Kunden mit 403). Stand 29.10.: `TERMINE`, `ZEITEN` und `UNTERKUNFT` stehen auf `pilot`, `SHOP` auf `on` (die Zeile steht doppelt), `ANALYSE_ENABLED` auf `on`: du bestätigst, dass die Analyse danach für alle unter „Entdecken“ erscheint. `AUFTRAEGE_ENABLED` hat weder `.env`- noch Compose-Zeile und bleibt damit `off`. 5. Ruhe und Sicherung (Erwartet: 0, sonst die Zeilen ansehen): `docker logs --since 72h webklar-kundenbereich-server 2>&1 | command grep -a -c 'Unbehandelter Fehler'`, dann `cp -n /home/webklar/apps/.env /home/webklar/apps/.env.bak-$(date -u +%Y-%m-%d)-kundenansicht-on` -6. **Stop: Inhaber-OK nötig:** Der Controller nennt dir das Ergebnis der Schritte 1 bis 5 und schlägt eine ruhige Uhrzeit vor; du sagst „umschalten, jetzt“. -7. `.env` ändern (erwartet genau die Zeile `KUNDENANSICHT_NEU=on`, sonst stoppt der Controller): `sed -i 's/^KUNDENANSICHT_NEU=.*/KUNDENANSICHT_NEU=on/' /home/webklar/apps/.env && command grep -a -n '^KUNDENANSICHT_NEU=' /home/webklar/apps/.env` -8. Neu starten (erwartet `Up …`; bei 502 in den ersten Sekunden Abschnitt 6 nach 10 s wiederholen): `cd /home/webklar/apps && docker compose up -d --no-deps kundenbereich-server && docker ps --filter name=webklar-kundenbereich-server --format '{{.Status}}'` +6. Käufe (nur lesend, Exit 0 und `Offene Bestellungen: 0`, sonst wartest du die Zahlung ab; `Fristen laufen` ist nur Information, eine Zeile `Behalten-Sitzung eingetragen` klärt der Controller vorher): `set -o pipefail; docker exec -w /app webklar-kundenbereich-server node scripts/kauf-bestand-pruefen.mjs | tee /root/reports/kundenansicht-neu-2026-10-15/umschalten/kauf-bestand-$(date -u +%Y%m%d-%H%M%S).log` +7. **Stop: Inhaber-OK nötig:** Der Controller nennt dir das Ergebnis der Schritte 1 bis 6 und schlägt eine ruhige Uhrzeit vor; du sagst „umschalten, jetzt“. +8. `.env` ändern (erwartet genau die Zeile `KUNDENANSICHT_NEU=on`, sonst stoppt der Controller): `sed -i 's/^KUNDENANSICHT_NEU=.*/KUNDENANSICHT_NEU=on/' /home/webklar/apps/.env && command grep -a -n '^KUNDENANSICHT_NEU=' /home/webklar/apps/.env` +9. Neu starten (erwartet `Up …`; der Server lauscht erst nach `npm install`, weiter erst, wenn `docker logs --since 2m webklar-kundenbereich-server 2>&1 | command grep -a -c 'Kundenbereich läuft auf Port'` mindestens 1 ergibt): `cd /home/webklar/apps && docker compose up -d --no-deps kundenbereich-server && docker ps --filter name=webklar-kundenbereich-server --format '{{.Status}}'` ## 6. Nachprüfung -1. Seiten (Exit 0, alle Zeilen `ok`, einschließlich `/abo-bedingungen.html` mit `Version 6` und des PDFs): `cd /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 && node scripts/umschalten-nachpruefung.mjs https://project.webklar.com --erwartet=neu` +1. Seiten (Exit 0, alle Zeilen `ok`, einschließlich `/abo-bedingungen.html` mit `Version 6` und des PDFs): `cd /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 && node scripts/umschalten-nachpruefung.mjs https://project.webklar.com --erwartet=neu`. Das Skript prüft beim PDF nur Typ und Anfang, deshalb dazu der Inhalt (beide Werte gleich): `curl -s https://project.webklar.com/WEBklar-Abo-Vertragsunterlagen.pdf | sha256sum; cat public/neu/rechtliches/WEBklar-Abo-Vertragsunterlagen.pdf.sha256` 2. Routen (erwartet JSON mit `"authenticated":false`): `curl -s https://project.webklar.com/api/auth/me` 3. Login und Oberfläche, du mit zwei Konten (Betrieb und Pilot-Konto) auf Handy und Desktop: (a) `/login.html` ist weiß, die Anmeldung führt auf Website; (b) `#chat`, `#rechnungen`, `#wartung` und `#termine?bestellt=1&projekt=` landen am richtigen Ort mit erhaltener Query; (c) „Verträge kündigen“ und „Vertrag widerrufen“ liegen höchstens zwei Taps entfernt, beide Seiten öffnen weiß; (d) Funktionen zeigt „Meine/Entdecken“ ohne Preise, „Einschalten“ eines Betriebs hat kein Häkchen; (e) die Kundenansicht der Mitarbeiter (WOMS) zeigt die neue Oberfläche und sperrt Schreibaktionen. 4. Mails, optional: Probekauf mit dem Testkonto aus `ABO_TEST_EMAILS` (0,50 €). Erwartet: K01 an den Kunden und T02 ans Team kommen an, der Anhang `WEBklar-Abo-Vertragsunterlagen.pdf` ist Fassung 6, in `featureConsents` steht eine Zeile mit `featureKey` `abo` und der Kundenart. **Stop: Inhaber-OK nötig** für Kauf und Stornieren. 5. Logs (erwartet 0): `docker logs --since 30m webklar-kundenbereich-server 2>&1 | command grep -a -c -i 'Unbehandelter Fehler'` -6. Installierte App: Android öffnet weiß. iOS liest die Statusleiste beim Installieren; bleibt sie schwarz, entfernst du die App vom Home-Bildschirm und fügst sie neu hinzu. +6. Installierte App und offene Tabs: Ein Tab der alten Ansicht von vor dem Umschalten bekommt bei Bestellung, Wechsel oder Speicher 409 „Seite neu laden“ (gewollt, keine Bestellung nach Fassung 5 mehr). Android öffnet weiß. iOS liest die Statusleiste beim Installieren; bleibt sie schwarz, entfernst du die App vom Home-Bildschirm und fügst sie neu hinzu. 7. Beobachtungszeit: Beginn und Ende (Vorschlag: sieben Tage) stehen in `/root/reports/kundenansicht-neu-2026-10-15/umschalten/beobachtung.txt`. Die Offline-Seite aus Abschnitt 8 darf sofort laufen, das Festschreiben erst nach Ablauf und mit deinem neuen OK. ## 7. Rückweg 1. Nur bei Fehler, und vorher informiert der Controller dich kurz. 2. `.env` zurück auf `off` und neu starten: `sed -i 's/^KUNDENANSICHT_NEU=.*/KUNDENANSICHT_NEU=off/' /home/webklar/apps/.env && cd /home/webklar/apps && docker compose up -d --no-deps kundenbereich-server` -3. Dann aus dem Worktree (erwartet Exit 0): `cd /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 && node scripts/umschalten-nachpruefung.mjs https://project.webklar.com --erwartet=alt` +3. Dann aus dem Worktree, sobald der Server wieder lauscht (wie Abschnitt 5, Schritt 9; erwartet Exit 0): `cd /home/webklar/apps/kundenbereich.webklar.com/dev-kn-p10 && node scripts/umschalten-nachpruefung.mjs https://project.webklar.com --erwartet=alt` 4. Verträge, die unter Fassung 6 abgeschlossen wurden, bleiben gültig: Fassungstabelle und Archiv bleiben stehen. 5. Der Schalter ist der Rückweg nur bis zum Festschreiben (Abschnitt 8). diff --git a/test/knUmschaltCheckliste.test.js b/test/knUmschaltCheckliste.test.js index 9694a71..608f9c4 100644 --- a/test/knUmschaltCheckliste.test.js +++ b/test/knUmschaltCheckliste.test.js @@ -27,6 +27,8 @@ function regelverstoesse(d) { for (const [n, min] of [[1, 1], [2, 1], [3, 1], [5, 1], [6, 1], [8, 2]]) soll(anzahl(a(n), STOPP) >= min, `Abschnitt ${n}: Stopp fehlt`) soll(vor(a(5), STOPP, 'sed -i') && vor(a(5), 'cp -n', 'sed -i') && vor(a(5), STOPP, 'docker compose up'), 'Abschnitt 5: Sicherung und Stopp stehen nicht vor dem Schreiben der .env') soll(vor(a(2), STOPP, '--ausfuehren'), 'Abschnitt 2: Stopp steht nicht vor --ausfuehren') + // Querpruefung Teil A: offene Bestellungen werden vor dem Stopp des Umschaltens gelesen + soll(vor(a(5), 'kauf-bestand-pruefen.mjs', STOPP), 'Abschnitt 5: Käufe nicht vor dem Stopp geprüft') // Push nur mit Stopp, auf main, nie erzwungen for (const l of d.split('\n').filter((z) => z.includes('git push'))) soll(l.includes(STOPP) && l.includes('refs/heads/main') && !/--force|\s-f\s/.test(l), 'Push ohne Stopp oder erzwungen') // Kundenart-Skript: Protokoll mit tee, Ausführen mit Bestätigung und pipefail (sonst verschluckt tee den Exit-Code) @@ -76,6 +78,7 @@ const BRUCH = { '--ausfuehren ohne pipefail': ALLE('set -o pipefail; ', ''), 'Protokolle entfernt': ALLE(' | tee ', ' > '), 'Abschnitt 5 zu lang': imAbschnitt(5, (s) => `${s}9. a\n10. b\n11. c\n`), + 'Käufe nicht geprüft': ALLE('kauf-bestand-pruefen.mjs', 'kauf-liste.mjs'), } test('die echte Checkliste hält alle Regeln', () => { assert.deepEqual(regelverstoesse(doc), []) }) for (const [name, aendern] of Object.entries(BRUCH)) {