*/ public static function all(): array { $mode = OperatingMode::current(); return [ new Check( key: 'billing.stripe_secret', group: self::GROUP, severity: Check::SEVERITY_BLOCKING, label: __('readiness.billing.stripe_secret', ['mode' => __('readiness.mode.'.$mode->value)]), breaks: __('readiness.billing.stripe_secret_breaks'), tab: 'services', // get() löst den aktiven Modus selbst auf UND ist für Stripe // strikt — ein Live-Schlüssel zählt im Testbetrieb nicht als // Nachweis, sonst widerspräche diese Seite der Kassensperre. satisfied: filled(app(SecretVault::class)->get('stripe.secret')), ), new Check( key: 'billing.webhook_secret', group: self::GROUP, severity: Check::SEVERITY_BLOCKING, label: __('readiness.billing.webhook_secret'), breaks: __('readiness.billing.webhook_secret_breaks'), tab: 'env', // Die Auswahl nach Modus liegt schon in StripeWebhookSecret — // hier noch einmal per config() nach Modus zu unterscheiden // wäre eine zweite Stelle, die dieselbe Entscheidung trifft. satisfied: filled(StripeWebhookSecret::current()), ), new Check( key: 'billing.company_details', group: self::GROUP, severity: Check::SEVERITY_BLOCKING, label: __('readiness.billing.company_details'), breaks: __('readiness.billing.company_details_breaks'), tab: 'company', // Die vorhandene Liste wird gerufen, nicht verdoppelt: zwei // Quellen für eine Frage ist der Weg, auf dem sie auseinanderlaufen. satisfied: CompanyProfile::missingForInvoicing() === [], ), new Check( key: 'billing.invoice_series', group: self::GROUP, severity: Check::SEVERITY_BLOCKING, label: __('readiness.billing.invoice_series'), breaks: __('readiness.billing.invoice_series_breaks'), tab: 'company', satisfied: InvoiceSeries::query() ->whereIn('kind', ['invoice', 'credit_note', 'cancellation']) ->distinct() ->count('kind') === 3, ), new Check( key: 'billing.catalogue_synced', group: self::GROUP, severity: Check::SEVERITY_BLOCKING, label: __('readiness.billing.catalogue_synced'), breaks: __('readiness.billing.catalogue_synced_breaks'), tab: 'services', satisfied: PlanPrice::query()->whereNull('stripe_price_id')->doesntExist(), ), ]; } }