Shop Review A I1/I2: Statuswechsel und Bestandsabzug unter einer Sperre, fehlende Schritte (Bestand, G09, K25) per Marker nachholen

Der Bestandsabzug laeuft jetzt im selben Block unter shop-bestand und shop-produkte wie der Statuswechsel auf bezahlt, zieheBestandAb haelt keine eigene Sperre mehr. Im Bestell-JSON stehen bestandAbgezogenAt, mailsKaeuferAt und mailsHaendlerAt als Marker; schliesseAb (Webhook-Wiederholung, Statusabruf, Minutenjob) holt fehlende Schritte genau einmal nach, Mails hoechstens fuenfmal versucht. Bezahlte Bestellungen ohne Bestandsabzug zaehlen weiter als reserviert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
ClaudeandClaude Opus 5.5 committed 2026-10-05 09:30:36 +00:00
1 parent 42a6bb5a4a
commit 9c2897a0b0
4 files changed
+305 -83

No files matched your search

+25
View File
@@ -450,6 +450,31 @@ test('Status: offen ⇒ bezahlt, sobald Stripe die Sitzung als bezahlt meldet; E
assert.equal(sink.sent.length, mailsVorher)
})
test('Status I2: bezahlte Bestellung mit fehlendem Bestandsabzug wird beim nächsten Abruf nachgeholt', async () => {
await aufbau({ produkte: [artikel('a1', { bestand: 10 })] })
const { orderId, t, sessionId } = await offeneBestellung()
st.completeSession(ACCOUNT, sessionId, {
payment_status: 'paid',
amount_total: 2990,
customer_details: { name: 'Max Mustermann', email: 'max@example.com' },
shipping: { name: 'Max Mustermann', address: { line1: 'Musterweg 1', postal_code: '67655', city: 'Kaiserslautern', country: 'DE' } },
payment_intent: 'pi_test1',
})
aw.failNext({ collection: config.collections.shopProducts, method: 'PATCH', status: 500 })
const erster = await status(orderId, t)
assert.equal(erster.status, 200)
assert.equal(orders()[0].status, 'bezahlt')
assert.equal(JSON.parse(orders()[0].bestellung).bestandAbgezogenAt, null)
const zweiter = await status(orderId, t)
assert.equal(zweiter.body.status, 'bezahlt')
assert.ok(JSON.parse(orders()[0].bestellung).bestandAbgezogenAt)
await warteAufVersand()
const mails = sink.sent.length
await status(orderId, t)
await warteAufVersand()
assert.equal(sink.sent.length, mails, 'Mails nur einmal')
})
test('Status: nicht bezahlte Sitzung (z. B. SEPA unterwegs) bleibt offen; Stripe-Fehler beim Abgleich ⇒ trotzdem Antwort', async () => {
const { orderId, t, sessionId } = await offeneBestellung()
st.completeSession(ACCOUNT, sessionId, { payment_status: 'unpaid', amount_total: 2990 })