- Decision-Update Preisstruktur & Veroeffentlichungs-Flow aufgenommen (Launch-Tarife, Slot-Verbrauch bei Veroeffentlichung, Submit-Gate, Launch-Credits) inkl. Klarstellung 12.06.: Gelb geht direkt live, keine manuelle Pruef-Queue, nur Rot wird abgelehnt - Alle Status-Dokumente auf den Code-Stand gezogen: README-Index, STATUS-ABGLEICH (KI-Pipeline, Bilder/Lizenzen, Pricing), Checkliste (KI- und Titelbild-Bloecke, Launch-To-dos), Admin-User, user-zusammenhaenge (Datenmodell-Delta), Entwicklungsplan KI-Pruefung (Phase 0 abgehakt, Decision-Abgleich) - Ueberschriebene Tarif-Abschnitte in Konzept-Update 1/2 und Relaunch-Konzept mit Superseded-/IST-Hinweisen markiert - Neues Plan-Dokument PHASE-9-FLOW-UND-TARIFE-PLAN.md (9A-9J) - Phase-8-Roadmap-Doku (20-PHASE-8-USER-PANEL.md) + PROGRESS-Eintraege Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
10 KiB
Phase 9 · Veröffentlichungs-Flow (Launch) & Tarif-Modul
Stand: 2026-06-12 — in Umsetzung (Block 1: 9A–9C zuerst, dann Review-Stopp,
dann Block 2: 9D–9J).
Vorgänger: Phase 8 (User-Panel-Konsolidierung) + KI-Prüf-Pipeline (beide abgeschlossen).
Verbindliche Entscheidungen: docs/Decision-Update Preisstruktur & Veröffentlichungs-Flow.md
Abgleich-Doku: docs/STATUS-ABGLEICH-USER-PANEL.md
0. Worum es geht
Phase 9 setzt das Decision-Update vom 11./12.06.2026 um — in zwei Blöcken:
- Block 1 — Veröffentlichungs-Flow (9A–9C): Die Flow-Regeln, die unabhängig vom Tarif-Modul gelten und auf denen das Tarif-Modul aufsetzt. Funktioniert vollständig mit dem vorhandenen Quota-Stub.
- Block 2 — Tarif-Modul (9D–9I): Zahlung, Tarife, Einzel-PM, Tageslimit und die drei Launch-Credit-Posten. Löst den Quota-Stub ab.
Leitplanken aus dem Decision-Update:
- Gelb geht zum Launch direkt live wie Grün — keine manuelle Prüf-Queue. Nur Rot wird abgelehnt (Meldung mit Begründung an den Autor).
- Der PM-Slot zählt bei Veröffentlichung runter, nicht bei der Prüfung. Rot verbraucht keinen Slot.
- „Speichern" bleibt immer frei; „Speichern & zur Prüfung einreichen" ist hinter eine aktive Buchung gegated (der Button konvertiert, er verschwindet nicht).
- Kein Re-Check zum Launch: eine Einreichung = eine Prüfung = (bei Gelb/Grün) eine Veröffentlichung. Vorab-Prüfung/Redigieren sind Phase 2.
1. Sub-Päckchen-Übersicht
| ID | Thema | Größe | Risiko |
|---|---|---|---|
| 9A | Gelb-Routing auf Direkt-Live umstellen (Routing, Scheduler, Tests) | S | gering |
| 9B | Slot-Verbrauch von Einreichung auf Veröffentlichung umstellen (Rot = kein Slot) | M | mittel (Idempotenz) |
| 9C | Submit-Gate-Schnittstelle (hasActiveBooking()-Stub, Modal-Hinweis, Server-Guard) |
M | gering |
| — | Review-Stopp mit User | ||
| 9D | Tarif-Datenmodell: Pläne, Subscriptions, Einzel-PM-Käufe; Quota-Stub ablösen | L | hoch (Datenmodell) |
| 9E | Stripe-Anbindung (Laravel Cashier — Dependency-Freigabe nötig) | L | mittel |
| 9F | Tarif-Seite + Checkout-UI (Raster, Einzel-PM-Block, „2 Monate gratis", Enterprise-Hinweis) | M | gering |
| 9G | Tageslimit je Tier (Business 2 / Pro 3 / Agency 5; gilt auch für Extra-PMs) | S | gering |
| 9H | Einzel-PM-Kauf (19 €) + Einzel→Abo-Brücke (Anrechnung 30 Tage) | M | mittel |
| 9I | Launch-Credits: Extra-PM, Boost (nur Grün), Veröffentlichungsnachweis-PDF | L | mittel |
| 9J | Abschluss: Tests, Pint, Build, Doku-Sync, PROGRESS-Eintrag | S | keine |
Nach jedem Päckchen Review-Stopp mit dem User; vor 9D ein größerer (Datenmodell-Entscheidungen + Cashier-Freigabe).
2. Block 1 — Veröffentlichungs-Flow
9A · Gelb-Routing auf Direkt-Live
Entscheidung (12.06.2026): Rot = nicht veröffentlichbar (rechtlich/ inhaltlich) → Ablehnung mit Meldung. Gelb/Grün = veröffentlichbar → geht in der ersten Phase direkt online. Gelb bleibt als interne Markierung erhalten (nicht boostbar, Admin-Signal), löst aber keine manuelle Prüfung aus.
Anpassungen:
PressReleaseService::routeByClassification(): Gelb durchläuft denselben Auto-Publish-Pfad wie Grün (autoPublishGreen()→ generalisiert zuautoPublishApproved()); Verzögerungsfenster (scoring.classification.green_delay_minutes) gilt für beide.PublishScheduledPressReleases: Kandidaten-Query vonclassification = greenaufclassification IN (green, yellow).- Admin-Review-Queue bleibt als Fallback bestehen: unklassifizierte PMs
(Job noch nicht gelaufen / KI-Ausfall ohne Fallback-Ergebnis) bleiben in
reviewund sind manuell behandelbar. KI-Badge und Klassifikations-Filter im Admin bleiben unverändert.
Tests: PressReleaseClassificationJobTest (Gelb-sofort → published,
Gelb-geplant → bleibt review bis Termin), PressReleaseSchedulingTest
(gelbe fällige PM wird publiziert).
9B · Slot-Verbrauch bei Veröffentlichung
Regel: Der Slot zählt genau einmal pro PM, beim ersten Übergang zu
published. Rot abgelehnte PMs verbrauchen nichts.
Anpassungen:
submitForReview(): Increment vonpress_release_quota_used_this_monthentfernen. Stattdessen Guard: Einreichen erfordertpressReleaseQuotaRemaining() > 0(sonst würde eine grüne PM ohne verfügbaren Slot veröffentlicht).publish(): Increment beim Statuswechsel aufpublished, idempotent — nur wenn die PM zuvor noch nie veröffentlicht war (Prüfung überpress_release_status_logs, kein neues Schema-Feld). Zählt auf den PM-Eigentümer (user_id).- Veröffentlichungs-Modal: Text von „wird bei Einreichung verbraucht" auf „wird bei Veröffentlichung verbraucht; abgelehnte PMs kosten keinen Slot".
Tests: Submit verbraucht keinen Slot; Publish (Admin, Auto-Publish, Scheduler) verbraucht genau einen; Rot → kein Verbrauch; Archivieren + erneutes Publizieren zählt nicht doppelt; Submit bei 0 Rest-Slots blockiert.
9C · Submit-Gate-Schnittstelle
Ziel: Das Gate aus dem Decision-Update §5.1, gebaut gegen eine schmale Schnittstelle, die zunächst ein Stub bedient und in 9D/9E vom Tarif-Modul implementiert wird — Modal und Service müssen dann nicht mehr angefasst werden.
Anpassungen:
User::hasActiveBooking(): bool— Launch-Schnittstelle. Stub-Verhalten überconfig/billing.php(billing.enforce_booking, Defaultfalse): solange das Tarif-Modul fehlt, gibt die Methodetruezurück; mit aktiviertem Flag (und später echter Subscription-Prüfung) greift das Gate.- Einreichungs-Modal (
press-release-submit-modal): ohne aktive Buchung zeigt das Modal statt des Prüf-Flows einen Buchungs-Hinweis mit CTA („Buchung erforderlich" → Tarif-Seite). Der Button bleibt sichtbar. - Server-Guard:
submitForReview()wirft ohne aktive Buchung eine Exception (UI allein reicht nicht); API-Submit-Route antwortet mit 402.
Tests: Gate aus (Default) → Verhalten unverändert; Gate an →
Modal-Hinweis statt Checkboxen, submitForReview wirft, API gibt 402.
3. Block 2 — Tarif-Modul (nach Review-Stopp)
9D · Tarif-Datenmodell
- Tabellen (Arbeitsstand, final beim Review-Stopp vor 9D):
plans(Starter/Business/Pro/Agency: Preis mtl./jährl., PMs/Monat, Tageslimit),subscriptions(User, Plan, Zyklus, Status, Periodenstart/-ende),single_purchases(Einzel-PM, Extra-PM, Boost, PDF — Typ, Preis, Status,applied_to_press_release_id). User::hasActiveBooking()prüft echte Subscription oder offenen Einzel-PM-Kauf.- Slot-Logik wechselt von
users.press_release_quotaauf Plan-Kontingent + Periodenzähler; Stub-Spalten werden nach Migration entfernt. - Kontingent-Anzeige (Modal, Editor) liest aus der neuen Quelle —
Schnittstelle
pressReleaseQuotaRemaining()bleibt stabil.
9E · Stripe (Laravel Cashier)
- Vor Start freizugeben:
laravel/cashierals neue Dependency. - Checkout für Abo (monatlich/jährlich) und Einmalzahlung (Einzel-PM, Credits).
- Webhooks (Subscription-Status, Zahlungsausfall) + lokale Spiegelung.
- Rechnungen an bestehende
invoices-Struktur anbinden (Klärung beim Review).
9F · Tarif-Seite + Checkout-UI
- Raster mit 4 Tiers; Einzel-PM als separater No-Abo-Block (nicht als billigste Spalte); Enterprise als dezenter Sales-Hinweis unter der Tabelle.
- Jahrespreis kommuniziert als „2 Monate gratis".
- Einstieg aus dem Submit-Gate-Hinweis (9C) und aus „Buchungen & Add-ons".
9G · Tageslimit
plans.daily_limit(Starter ohne Limit); Prüfung beim Veröffentlichen (nicht beim Einreichen), zählt veröffentlichte PMs des Users pro Kalendertag (Europe/Berlin); gilt auch für Extra-PMs. Überschreitung → PM bleibt inreviewmit Hinweis, Veröffentlichung am Folgetag durch den Scheduler.
9H · Einzel-PM + Abo-Brücke
- Einzel-PM-Kauf 19 € → genau eine Einreichung/Veröffentlichung.
- Brücke: Abo-Abschluss innerhalb 30 Tagen rechnet 19 € auf den ersten Monat an (Stripe-Coupon oder Rabatt-Position).
9I · Launch-Credits
- Credit-Wallet (1 Credit = 1 € Listenpreis, Pakete mit Volumenrabatt).
- Posten: Extra-PM (Kontingent voll → einzelne PM nachkaufen), Boost (nur für grün klassifizierte PMs, nachträglich), Veröffentlichungsnachweis-PDF.
- Kein Dofollow-Backlink-Verkauf (bewusst ausgeschlossen).
9J · Abschluss
- Volle Suite grün, Pint clean,
npm run buildclean. - Doku-Sync:
STATUS-ABGLEICH,checkliste-user-backend.md, dieses Dokument,PROGRESS.md-Eintrag.
4. Was außerhalb von Phase 9 bleibt
- Vorab-KI-Prüfung, Redigieren/Re-Check-Loop, Prüfzähler, Credit-Overflow (Decision-Update §7 — Phase 2)
- Score-Feinstufung für Boost („nur Geprüft/Hochwertig boostbar")
- Magic-Link-Flow, Statistik-/Abrechnungs-Tabs, Anhänge-Reaktivierung, Trust-Score, Notice-and-Action
5. Risiken & Annahmen
- Idempotenz Slot-Verbrauch (9B): Prüfung über Status-Logs statt neuem Feld — bei Alt-Daten mit unvollständigen Logs schlimmstenfalls ein doppelter Zähler; akzeptabel für den Stub, wird mit 9D-Periodenzähler sauber.
- Gate-Stub (9C):
enforce_booking=falseals Default hält das System bis zum Tarif-Modul voll funktionsfähig; das Flag erlaubt Tests und frühe Aktivierung. - 9D/9E Datenmodell + Cashier: größter Block, eigener Review-Stopp davor;
Stub-Ablösung (
press_release_quota-Spalten entfernen) erst nach verifizierter Migration. - Rechtstexte (Einreichungs-Modal) sind weiterhin Platzhalter — anwaltliche Prüfung läuft parallel, unabhängig von Phase 9.
- Betrieb: Queue-Worker für
classificationin Produktion bleibt Go-Live-Voraussetzung (unabhängig von Phase 9).
6. Akzeptanzkriterien Phase 9 gesamt
- Gelb klassifizierte PMs gehen ohne manuelle Prüfung live (sofort/Termin)
- Rot verbraucht keinen Slot; Slot zählt genau einmal, bei Veröffentlichung
- Einreichen ohne aktive Buchung zeigt Buchungs-Hinweis (UI) und wird serverseitig abgelehnt (Gate aktiviert)
- Tarife buchbar (4 Tiers, monatlich/jährlich), Einzel-PM kaufbar
- Tageslimit greift je Tier, auch für Extra-PMs
- Extra-PM, Boost (nur Grün) und PDF-Nachweis als Credits kaufbar
- Quota-Stub vollständig abgelöst,
pressReleaseQuotaRemaining()stabil - Tests grün, Pint clean, Build clean, Doku synchron