From ddaf2879c4d5ef4ceca73b813e06e1289e0cc150 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 16 Oct 2026 21:41:28 +0000 Subject: [PATCH] Kundenansicht neu E-Fix M2: aboModellFuerKunde liest bei Modus off kein Kundendokument MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit aboModellFuerKunde las das Kundendokument auch bei KUNDENANSICHT_NEU=off, obwohl neueAnsichtFuerKunde dort sofort false liefert. Alt-Kunden bekamen so eine zusätzliche Lesung und einen neuen Fehlerpfad (ein 503 beim Widerruf des Wechsels ließ die Beenden-Mail der Analyse entfallen, die Team-Aktivierung und GET /api/admin/analyse/:id antworteten mit 500). Jetzt sofort false im Modus off; Pilot und on lesen wie bisher (kein Dokument: false). Test in analyseAboModell.test.js (eingeplanter 503 wird im Modus off nicht verbraucht). Co-Authored-By: Claude Sonnet 5.5 --- server/services/aboFunktionen.js | 5 ++++- test/analyseAboModell.test.js | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/server/services/aboFunktionen.js b/server/services/aboFunktionen.js index 519e106..2c645e0 100644 --- a/server/services/aboFunktionen.js +++ b/server/services/aboFunktionen.js @@ -2,7 +2,7 @@ import { config } from '../config.js' import { getDocument } from './appwriteAdmin.js' import { ACTIVE_STATUSES, getCurrentSubscription } from './stripeBilling.js' import { listContractEvents, openWithdrawals } from './contractEvents.js' -import { neueAnsichtFuerKunde } from './kundenansicht/schalter.js' +import { neueAnsichtFuerKunde, neueAnsichtModus } from './kundenansicht/schalter.js' /** * Abo-Zuordnung der Funktionen (V5, Spec E3/E8): Welches Abo deckt welche Funktion? Ein Lesepfad (lies) fuer alle @@ -98,6 +98,9 @@ export async function aboLaeuftFuer(customerId, key) { */ export async function aboModellFuerKunde(customerId) { if (typeof customerId !== 'string' || customerId === '') return false + // Modus off: sofort false, ohne das Kundendokument zu lesen (E-Fix M2). Alt-Kunden bekommen so keine zusätzliche Lesung und keinen neuen Fehlerpfad + // (ein transienter Lesefehler liess die Beenden-Mail beim Widerruf des Wechsels und die Team-Aktivierung scheitern). + if (neueAnsichtModus() === 'off') return false let kunde try { kunde = await getDocument(config.collections.customers, customerId) diff --git a/test/analyseAboModell.test.js b/test/analyseAboModell.test.js index b31098b..b325029 100644 --- a/test/analyseAboModell.test.js +++ b/test/analyseAboModell.test.js @@ -198,3 +198,24 @@ test('Tagesprüfung: Hosting-Analyse bleibt für Kunden der neuen Ansicht, sonst assert.equal(await aboModellFuerKunde('gibtEsNicht'), false) // kein Kundendokument: kein Abo-Modell assert.equal(await aboModellFuerKunde(''), false) }) + +test('M2: aboModellFuerKunde liest bei Modus off kein Kundendokument (keine zusätzliche Lesung, kein neuer Fehlerpfad für Alt-Kunden)', async () => { + const vorher = { mode: config.kundenansichtNeu.mode, pilotEmails: [...config.kundenansichtNeu.pilotEmails] } + try { + Object.assign(config.kundenansichtNeu, { mode: 'off', pilotEmails: ['*'] }) + // ein transienter Lesefehler (503) trifft im Modus off nie: es wird gar nicht gelesen, die Antwort ist sofort false + aw.failNext({ collection: 'customers', method: 'GET', status: 503 }) + assert.equal(await aboModellFuerKunde('c1'), false) + // der eingeplante Fehler ist nicht verbraucht: die erste Lesung im Pilot trifft ihn (Lesefehler werden weitergereicht) + Object.assign(config.kundenansichtNeu, { mode: 'pilot', pilotEmails: ['k@example.invalid'] }) + await assert.rejects(() => aboModellFuerKunde('c1'), (err) => err.status === 500 && err.code === 503) // adminFetch macht aus jedem 5xx den Status 500, code bleibt 503 + // danach wie bisher: Pilot und on lesen das Kundendokument (kein Dokument: false) + assert.equal(await aboModellFuerKunde('c1'), true) + assert.equal(await aboModellFuerKunde('gibtEsNicht'), false) + Object.assign(config.kundenansichtNeu, { mode: 'on', pilotEmails: [] }) + assert.equal(await aboModellFuerKunde('c1'), true) + assert.equal(await aboModellFuerKunde('gibtEsNicht'), false) + } finally { + Object.assign(config.kundenansichtNeu, vorher) + } +})