From 70f22d9541eff3bee5c103f7947cad7467d8fb6a Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 29 Oct 2026 12:26:21 +0000 Subject: [PATCH] Kundenansicht neu P10: bei on gilt Fassung 5 aus einem alten Tab nicht mehr (409 Seite neu laden) Ein Tab der alten Ansicht, der vor dem Umschalten geladen wurde, schickt weiter Fassung 5. Bei on zeigt /abo-bedingungen.html aber schon Fassung 6; ohne Sperre entstuende ein Vertrag nach Fassung 5. fassungDerAnfrage liefert dann null, Bestellung, Wechsel und Speicher antworten 409. Querpruefung Teil A. Co-Authored-By: Claude Opus 5.5 --- server/services/vertragsNachweis.js | 11 +++++++---- test/knCheckoutFassung6.test.js | 23 +++++++++++++++++++++++ test/knVertragsNachweis.test.js | 6 ++++++ 3 files changed, 36 insertions(+), 4 deletions(-) diff --git a/server/services/vertragsNachweis.js b/server/services/vertragsNachweis.js index 482d643..1a1fd3f 100644 --- a/server/services/vertragsNachweis.js +++ b/server/services/vertragsNachweis.js @@ -1,7 +1,7 @@ import { config } from '../config.js' import { createDocument } from './appwriteAdmin.js' import { actingPerson, texteHash } from './featureConsents.js' -import { neueAnsicht } from './kundenansicht/schalter.js' +import { neueAnsicht, neueAnsichtModus } from './kundenansicht/schalter.js' import { KUNDENARTEN } from './kundenart.js' import { FEHLER_NACHWEIS, WORTLAUT_STATUS } from './bestelltexte.js' @@ -27,13 +27,16 @@ const nichtLeer = (wert) => typeof wert === 'string' && wert.trim() !== '' /** * 'alt' | 'neu' | null. 'neu': termsVersion ist nichtleer, gleich config.abo.termsVersionNeu UND die Anfrage sieht die neue Ansicht. - * 'alt': termsVersion ist gleich config.abo.termsVersion. Alles andere (auch eine fehlende Neu-Fassung) ist null. Die Neu-Fassung - * wird zuerst geprueft: bei gleichen Werten gilt neueAnsicht(req) ? 'neu' : null (P10 aendert hier nichts). + * 'alt': termsVersion ist gleich config.abo.termsVersion und der Schalter steht nicht auf on. Alles andere (auch eine fehlende + * Neu-Fassung) ist null. Die Neu-Fassung wird zuerst geprueft: bei gleichen Werten gilt neueAnsicht(req) ? 'neu' : null. + * Bei on schickt die alte Fassung nur noch ein Tab der alten Ansicht, der vor dem Umschalten geladen wurde: null (die Routen antworten + * 409 "Seite neu laden"), sonst entstuende ein Vertrag nach Fassung 5, waehrend /abo-bedingungen.html schon Fassung 6 zeigt (P10). */ export function fassungDerAnfrage(req, termsVersion) { if (!nichtLeer(termsVersion)) return null if (istNeueFassung(termsVersion)) return neueAnsicht(req) ? 'neu' : null - return termsVersion === config.abo.termsVersion ? 'alt' : null + if (termsVersion !== config.abo.termsVersion) return null + return neueAnsichtModus() === 'on' ? null : 'alt' } /** Nichtleer und gleich config.abo.termsVersionNeu (ohne Sitzungsbezug; fuer Mails und Ereignisse). */ diff --git a/test/knCheckoutFassung6.test.js b/test/knCheckoutFassung6.test.js index e21f74d..89d57eb 100644 --- a/test/knCheckoutFassung6.test.js +++ b/test/knCheckoutFassung6.test.js @@ -222,3 +222,26 @@ test('Webhook: Ereignis abschluss nennt den Grund kundenart nur bei Fassung 6 oh assert.equal('kundenart' in (await lauf({ termsVersion: NEU(), startChoice: 'nach_frist', earlyStartConsentAt: '' })), false) assert.equal('kundenart' in (await lauf({ termsVersion: config.abo.termsVersion, startChoice: 'sofort', earlyStartConsentAt: '' })), false) }) + +test('on (P10): Fassung 5 aus einem alten Tab bekommt bei Bestellung, Wechsel und Speicher 409 „Seite neu laden“, nichts geht an Stripe', async () => { + const modus = config.kundenansichtNeu.mode + config.kundenansichtNeu.mode = 'on' + try { + const vorher = st.calls.length + const fuenf = config.abo.termsVersion + for (const [pfad, b] of [ + ['/api/abo/checkout', { productKey: 'wartung', acceptTerms: true, startChoice: 'sofort', termsVersion: fuenf, offerId: '' }], + ['/api/abo/switch', { acceptTerms: true, earlyStart: true, termsVersion: fuenf, prorationDate: 1, amountDueCents: 100 }], + ['/api/abo/storage', { units: 1, acceptTerms: true, termsVersion: fuenf }], + ]) { + for (const cookie of [customerCookie('c3'), customerCookie('c2')]) { + const r = await post(pfad, b, { cookie }) + assert.equal(r.status, 409, pfad) + assert.equal(r.body.error, 'Die Bedingungen wurden aktualisiert. Bitte lade die Seite neu.', pfad) + } + } + assert.equal(st.calls.length, vorher) + } finally { + config.kundenansichtNeu.mode = modus + } +}) diff --git a/test/knVertragsNachweis.test.js b/test/knVertragsNachweis.test.js index 13e99f8..81cddcf 100644 --- a/test/knVertragsNachweis.test.js +++ b/test/knVertragsNachweis.test.js @@ -46,6 +46,12 @@ test('fassungDerAnfrage: alt, neu, null; fehlende Neu-Fassung ist nie neu', () = config.abo.termsVersionNeu = NEU const ohneKonto = req(); delete ohneKonto.session.appwriteUserId assert.equal(fassungDerAnfrage(ohneKonto, NEU), null) + // on (P10): die alte Fassung kommt nur noch aus einem Tab der alten Ansicht von vor dem Umschalten, sie gilt nicht mehr + config.kundenansichtNeu.mode = 'on' + assert.equal(fassungDerAnfrage(req('fremd@example.invalid'), config.abo.termsVersion), null) + assert.equal(fassungDerAnfrage(req('fremd@example.invalid'), NEU), 'neu') + config.kundenansichtNeu.mode = 'pilot' + assert.equal(fassungDerAnfrage(req('fremd@example.invalid'), config.abo.termsVersion), 'alt') } finally { config.abo.termsVersionNeu = NEU config.kundenansichtNeu.mode = modus