Credit-Wallet + Ledger + Tier-Preisableitung (Fundament)

Echte Credit-Wallet (1 Credit = 1 EUR) mit append-only Ledger als Basis fuer
die Credit-Oekonomie aus dem Decision-Update (Rev. 4):

- credit_wallets (denormalisierter Saldo) + credit_transactions (Ledger,
  vorzeichenbehaftet, balance_after, polymorphe reference)
- CreditWalletService: einziger Schreibpfad, atomar mit Row-Lock,
  InsufficientCreditsException mit shortfall fuer den Mini-Checkout
- Tier-Enum (Einzel/Starter/Business/Pro/Agency) + User::currentTier()
- CreditPricingService: tier-gestaffelte Ableitung aus config/credits.php
  (Extra-PM 19/15/12/10/8, Boost 12/20/35, PDF 3, Depublish 25, Pruef-Quota)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Kevin Adametz 2026-06-17 14:16:43 +00:00
parent 97d69a1a3a
commit 1306849b21
15 changed files with 756 additions and 0 deletions

79
config/credits.php Normal file
View file

@ -0,0 +1,79 @@
<?php
use App\Enums\Tier;
return [
/*
|--------------------------------------------------------------------------
| Credit-Ökonomie (Decision-Update Phase-2-Funktionen, Rev. 4)
|--------------------------------------------------------------------------
|
| 1 Credit = 1 €. Alle Preise sind die zur Kaufzeit aus dem aktiven Tier
| abgeleiteten Credit-Beträge (nicht statisch je Kauf gespeichert). Die
| zentrale Ableitung erfolgt in App\Services\Billing\CreditPricingService.
|
*/
/*
| Extra-PM (Kontingent-Nachkauf) — tier-gestaffelt. Treuevorteil:
| höheres Abo = günstigere Extra-PM (Einzel 19 … Agency 8).
*/
'extra_pm' => [
Tier::Einzel->value => 19,
Tier::Starter->value => 15,
Tier::Business->value => 12,
Tier::Pro->value => 10,
Tier::Agency->value => 8,
],
/*
| Boost (Platzierung Startseite + Branchenseite) — nach Dauer in Tagen.
| Pro-Tag-Preis sinkt mit der Dauer; Einstieg bleibt unter dem PM-Preis.
*/
'boost' => [
7 => 12,
14 => 20,
30 => 35,
],
/*
| Veröffentlichungsnachweis-PDF — pauschal pro PM (Impulskauf).
*/
'proof_pdf' => 3,
/*
| Depublizieren (Magic-Link-Pfad G) — bewusst am teuersten, mit Bedenkzeit.
*/
'depublish' => 25,
/*
| Kostenpflichtige Magic-Link-Pfade C/D (Phase 2, Anker „zu bestätigen").
*/
'paths' => [
'correction' => 8, // C – inhaltliche Korrektur
'update' => 4, // D – Update/Ergänzung
],
/*
|--------------------------------------------------------------------------
| Prüfzähler / Prüfkontingent (Decision-Update §4.2/§4.3)
|--------------------------------------------------------------------------
|
| Eigener Zähler, getrennt von der Wallet. Tier-gestaffelte Freiprüfungen
| pro Account/Monat (aggregiert, nicht pro PM). Burst-Schutz per Tageslimit.
| Overflow: leerer Zähler → je weitere Prüfung 1 Credit aus der Wallet.
*/
'review' => [
'free_per_month' => [
Tier::Einzel->value => 4,
Tier::Starter->value => 12,
Tier::Business->value => 30,
Tier::Pro->value => 60,
Tier::Agency->value => 120,
],
'daily_limit' => 10,
'overflow_cost' => 1,
],
];