new SafeEmailValidator($translator, $data, $rules, $messages, $attributes)); // Mindestanforderung für alle neu gesetzten Passwörter (Registrierung, Wizard, Ändern, Zurücksetzen) Password::defaults(fn () => Password::min(8)); Paginator::defaultView('pagination::bootstrap-4'); Paginator::defaultSimpleView('pagination::simple-bootstrap-4'); if ($this->app->environment('production')) { URL::forceScheme('https'); } Queue::failing(function (JobFailed $event): void { OperationalAlert::send('Queue-Job fehlgeschlagen: '.$event->job->resolveName(), [ 'connection' => $event->connectionName, 'queue' => $event->job->getQueue(), 'exception' => $event->exception->getMessage(), ]); }); AboutCommand::add('mivita', fn (): array => [ 'Version' => config('app.version') ?? 'unbekannt', ]); // Domain-bewusster View Composer für user_shop // HOTFIX: DomainContext temporär deaktiviert // TODO: Nach Claude v2 Implementation wieder aktivieren \View::composer('*', function ($view) { try { // $context = app(\App\Domain\DomainContext::class); // if ($context->type === 'main') { // $view->with('user_shop', null); // } else { // $userShop = $context->userShop ?? \App\Services\Util::getUserShop(); // $view->with('user_shop', $userShop); // } // Temporär: Verwende immer das normale Verhalten $view->with('user_shop', Util::getUserShop()); } catch (\Exception $e) { // Fallback bei Fehlern $view->with('user_shop', Util::getUserShop()); } }); } /** * Register any application services. * * @return void */ public function register() { // PAYONE payment service: built from merchant defaults, real Guzzle client at runtime. // The per-request `mode` is always passed explicitly to the service methods, so the // shared singleton needs only the base defaults from config. $this->app->singleton(PayonePaymentService::class, function () { return new PayonePaymentService(config('payone.defaults')); }); // Stripe: lazy Client-Hülle; Hard-Fail erst bei Nutzung ohne STRIPE_SECRET // (Dark-Launch-fähig, siehe config/stripe.php + dev/2026-07-08-stripe/). $this->app->singleton(StripeClientWrapper::class, function () { return new StripeClientWrapper(config('stripe.secret')); }); // Dashboard-Services teilen die Baum-Traversierung (lineBuckets-Memo): // als Singleton läuft die Downline-BFS pro Request/Prozess nur einmal je Root. $this->app->singleton(BackofficeDashboardService::class); if ($this->app->environment() !== 'production' && class_exists(IdeHelperServiceProvider::class)) { $this->app->register(IdeHelperServiceProvider::class); } } }