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>
36 lines
945 B
PHP
36 lines
945 B
PHP
<?php
|
|
|
|
namespace App\Enums;
|
|
|
|
/**
|
|
* Abrechnungs-Tier laut Decision-Update (Rev. 4). `Einzel` ist der Fall ohne
|
|
* aktives Abo (Pay-per-Release); die übrigen entsprechen den `plans.slug`.
|
|
* Treuelogik: höheres Tier = günstigere Extra-PM und mehr Freiprüfungen.
|
|
*/
|
|
enum Tier: string
|
|
{
|
|
case Einzel = 'einzel';
|
|
case Starter = 'starter';
|
|
case Business = 'business';
|
|
case Pro = 'pro';
|
|
case Agency = 'agency';
|
|
|
|
public function label(): string
|
|
{
|
|
return match ($this) {
|
|
self::Einzel => 'Einzel',
|
|
self::Starter => 'Starter',
|
|
self::Business => 'Business',
|
|
self::Pro => 'Pro',
|
|
self::Agency => 'Agency',
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Leitet das Tier aus einem `plans.slug` ab; unbekannt/kein Abo → Einzel.
|
|
*/
|
|
public static function fromPlanSlug(?string $slug): self
|
|
{
|
|
return self::tryFrom((string) $slug) ?? self::Einzel;
|
|
}
|
|
}
|