app->bind(LoginResponseContract::class, AdminLoginResponse::class); $this->app->singleton(SerpProviderRegistry::class, function ($app): SerpProviderRegistry { $r = new SerpProviderRegistry; $r->register($app->make(FakeSerpProvider::class)); $r->register($app->make(DataForSeoProvider::class)); return $r; }); } public function boot(): void { Sanctum::usePersonalAccessTokenModel(EarnApiToken::class); Gate::policy(User::class, UserPolicy::class); Gate::policy(Project::class, ProjectPolicy::class); Gate::policy(Keyword::class, KeywordPolicy::class); Gate::policy(SerpCheck::class, SerpCheckPolicy::class); Paginator::useBootstrapFive(); RateLimiter::for('serp-manual', fn ($request) => Limit::perMinute((int) config('serp.manual_rate_limit'))->by((string) ($request->user()?->id ?? $request->ip()))); Route::bind('customerProject', fn (string $value) => request()->user()->projects()->where('ulid', $value)->firstOrFail()); Route::bind('keyword', fn (string $value) => Keyword::query()->whereHas('project', fn ($query) => $query->where('user_id', request()->user()->id))->where('ulid', $value)->firstOrFail()); Route::bind('customerKeyword', fn (string $value) => request()->route('customerProject')->keywords()->where('ulid', $value)->firstOrFail()); Route::bind('customerSerpCheck', fn (string $value) => request()->route('customerKeyword')->serpChecks()->where('ulid', $value)->firstOrFail()); Event::listen(Login::class, function (Login $event): void { if ($event->user instanceof User) { $event->user->forceFill(['last_login_at' => now(), 'last_login_ip' => request()->ip()])->saveQuietly(); } }); } }