Doku: Credit-Oekonomie in WS-7-Checkliste + Umsetzungsstand im Decision-Update

- WS-7: Credit-Migrationen (wallets/transactions/review_checks/boosts/topups)
  in die Pflichtliste; Hinweis dass Credit-Pakete keine Stripe-Preis-IDs
  brauchen (checkoutCharge, config/credits.php); Webhook erfuellt credit_topup_id
  idempotent; Post-Deploy-Checks fuer Wallet-Topup + Gate-Datenschutz
- Decision-Update: Abschnitt 'Umsetzungsstand 17.06.2026' (Fundament,
  Launch-Funktionen, Phase-2-vorbereitet, offene Punkte)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-06-17 16:01:24 +00:00
parent 764d56ebd0
commit dd5a937b1b

View file

@ -100,12 +100,16 @@ Diese Phase-Migrationen MÜSSEN durchlaufen (Details im Sicherheits-Doc §7):
2. `downgrade_legacy_editor_users_to_customer` — schließt die Admin-Überberechtigung.
3. `add_oauth_provider_columns_to_users` — Google-Verknüpfung.
4. `create_legal_requests_table` — Compliance-Queue (WS-3).
5. **Credit-Ökonomie** (Decision-Update Rev. 4): `create_credit_wallets_table`, `create_credit_transactions_table` (Wallet + Ledger), `create_review_checks_table` (Prüfzähler), `create_boosts_table` (Platzierung), `create_credit_topups_table` (Stripe-Aufladung). Ohne sie schlagen Wallet-, Boost-, Nachweis- und Topup-Flows fehl.
Einmalige Setups (idempotent, in dieser Reihenfolge):
```bash
# Stripe: Tarife als Netto-Produkte/Preise anlegen → liefert STRIPE_PRICE_SINGLE_PM
php artisan billing:sync-stripe-plans
# Hinweis: Credit-Pakete (Wallet-Topup) brauchen KEINE Stripe-Preis-IDs — sie
# laufen als Ad-hoc-Charge (checkoutCharge). Preise/Staffeln stehen in
# config/credits.php (Pakete, Extra-PM-Tiers, Boost, Nachweis, Prüf-Overflow).
# Bestandsschutz aus dem Rechnungsarchiv neu nach user_payment_options migrieren.
# WICHTIG: auf Prod erneut laufen lassen, damit net_cents befüllt ist (vorher nur Dry-Run prüfen).
@ -126,6 +130,8 @@ php artisan cashier:webhook # registriert den Webhook-Endpoint bei Stripe
Danach das im Stripe-Dashboard angezeigte **Signing-Secret** als `STRIPE_WEBHOOK_SECRET` in die `.env` eintragen und `config:cache` erneuern.
> Der Webhook (`ProcessStripeWebhook`) erfüllt bei `checkout.session.completed` zwei Fälle über die Session-Metadaten: `single_purchase_id` (Einzel-/Extra-PM bezahlt) und `credit_topup_id` (Wallet-Gutschrift). Beide sind idempotent (Pending-Gate bzw. `credited_at`). Ohne funktionierenden Webhook bleibt aufgeladenes Guthaben aus.
---
## 5. Caches scharf stellen
@ -164,7 +170,8 @@ Verarbeitet die `ShouldQueue`-Jobs `ClassifyPressRelease` & `ScorePressRelease`
- [ ] **`editor`-Rolle bereinigt:** `Role::findByName('editor')->users()->whereNotNull('legacy_portal')->count()` == 0.
- [ ] **Admins legitim:** Die 4 verbliebenen Legacy-Admins (Alt-Gruppe 1) sind echtes Personal.
- [ ] **Bestandsschutz korrekt:** `user_payment_options` (grandfathered) hat befülltes `net_cents`; Bestandskunden sehen den Buchungs-Hinweis NICHT (WS-5).
- [ ] **Gate scharf:** Einreichen ohne Buchung → 402; Bestandskunde/Abo → durchgelassen.
- [ ] **Gate scharf:** Einreichen ohne Buchung → Hinweis „Noch keine Buchung" mit Link zur Buchungsseite (Entwurf bleibt erhalten, kein Datenverlust); Bestandskunde/Abo → durchgelassen.
- [ ] **Credit-Wallet:** Paket-Topup-Checkout → Webhook → Guthaben gutgeschrieben (genau einmal). Extra-PM/Boost/Nachweis aus Guthaben buchbar; bei zu wenig Guthaben Mini-Checkout-Hinweis (kein Absturz).
- [ ] **Auth-Kanäle:** Registrierung→Verifizierungsmail→Aktivierung; Magic-Link-Login; Google-Round-Trip (live mit echter https-Domain).
- [ ] **Stripe:** Test-Checkout + Webhook-Event kommt an (Cashier verarbeitet).
- [ ] **KI-Queue:** eine PM einreichen → Worker klassifiziert (kein Stau in `jobs`/`failed_jobs`).