Abo-Baustein aboStatus.js: Wechsel-Regel in laeuft/bestellbar, aboLage; Analyse nutzt ihn

aboStatus.js (Kernversion aus B5 ausgebaut): ein privater Lader lage(customerId, { altbestand })
ueber getCurrentSubscription und listContractEvents, alle Praedikate bauen darauf. laeuft kennt
altbestand (Vorgabe true: productKey || 'wartung' plus Wechsel-Regel; false: die heutige Regel der
Analyse, keine Ereignisabfrage). Wechsel-Regel: sagt der Spiegel "Wartung laeuft" und ist das
juengste wechsel-Ereignis des Abos widerrufen, laeuft das Wartungs-Abo nicht (kein_abo beim
Bestell-Gate, Freischaltung bleibt in setup). Neu aboLage ({ laeuft, art, endedAt }) und
aboMemo().lage; der Memo merkt eine Ablehnung fuer den Lauf. analyse.js nutzt
laeuft(id, { altbestand: false }); Verhalten der Analyse unveraendert (+1 Pin-Test).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Sonnet 5.5 committed 2026-10-04 13:50:51 +00:00
1 parent cf9f9b30a0
commit 144b053851
6 files changed
+449 -58

No files matched your search

+29 -1
View File
@@ -13,6 +13,7 @@ const aw = await startAppwriteMock({
portalFeatures: schemaKeys('portalFeatures'),
subscriptions: schemaKeys('subscriptions'),
termineConfig: schemaKeys('termineConfig'),
contractEvents: schemaKeys('contractEvents'),
},
})
after(() => aw.close())
@@ -84,7 +85,7 @@ const STUMM = (t) => {
}
beforeEach(async () => {
for (const col of ['portalFeatures', 'workorders', 'termineConfig', 'subscriptions', 'websiteProjects']) {
for (const col of ['portalFeatures', 'workorders', 'termineConfig', 'subscriptions', 'websiteProjects', 'contractEvents']) {
for (const id of aw.docs(col).keys()) await deleteDocument(col, id)
}
seedFixtures(aw)
@@ -213,6 +214,33 @@ test('Termine: Abo beendet (canceled) => bleibt setup', async (t) => {
assert.equal(mails.sent.length, 0)
})
test('Termine: Wechsel-Widerruf (Spiegel Wartung active, juengstes wechsel-Ereignis widerrufen) => bleibt setup, keine Mail; ein neueres erledigtes Ereignis gibt frei', async (t) => {
STUMM(t)
const wechsel = (nr, status) =>
aw.seed('contractEvents', {
$id: `ev_w${nr}`,
$createdAt: new Date(Date.UTC(2026, 8, 1, 0, 0, nr)).toISOString(),
customerId: 'c1',
subscriptionId: 'sub_h',
type: 'wechsel',
productKey: 'wartung',
details: '{}',
status,
})
const id = einrichtung('termine', { einstellung: true })
wechsel(1, 'widerrufen')
assert.deepEqual(await sf.runActivation({ now: JETZT }), [])
assert.equal(zustand(id), 'setup')
assert.equal(feld(id, 'enabled'), false)
assert.equal(wartetEintraege(id).length, 1)
assert.equal(mails.sent.length, 0)
wechsel(2, 'erledigt')
assert.deepEqual((await sf.runActivation({ now: JETZT })).map((d) => d.$id), [id])
assert.equal(zustand(id), 'active')
assert.equal(k16('Dein Terminplaner ist bereit').length, 1)
})
test('Termine: keine Einstellung => bleibt setup (mit Notiz), mit gespeicherter Einstellung aktiviert der naechste Lauf', async (t) => {
STUMM(t)
const id = einrichtung('termine')