configureRateLimiting(); $this->routes(function () { Route::middleware('api') ->prefix('api') ->group(base_path('routes/api.php')); Route::prefix('webhooks') ->group(base_path('routes/webhooks.php')); Route::middleware('v5.web') ->prefix('v5') ->as('v5.') ->group(base_path('routes/v5.php')); Route::middleware('web') ->group(base_path('routes/web.php')); }); } /** * Configure the rate limiters for the application. */ protected function configureRateLimiting(): void { RateLimiter::for('api', function (Request $request) { if ($request->path() === 'api/health') { return Limit::perMinute(1000)->by($request->user()?->id ?: $request->ip()); } return Limit::perMinute((int) config('api.rate_limit'))->by($request->user()?->id ?: $request->ip()); }); RateLimiter::for('5', function (Request $request) { return Limit::perMinute(5)->by($request->user()?->id ?: $request->ip()); }); // v5 authenticated web endpoints run synchronous SSH/Flux work per // request (connectivity checks, bootstrap, diagnostics). Throttle per // user so a single member cannot pin FPM workers by hammering them, // while leaving ample headroom for the canvas's 3s cluster polling. RateLimiter::for('v5', function (Request $request) { return Limit::perMinute(120)->by($request->user()?->id ?: $request->ip()); }); RateLimiter::for('feedback', function (Request $request) { return Limit::perMinute(3)->by($request->user()?->id ?: $request->ip()); }); } }