withRouting( web: __DIR__ . '/../routes/web.php', api: __DIR__ . '/../routes/api.php', commands: __DIR__ . '/../routes/console.php', health: '/up', then: function () { // Load public API routes (not loaded in api.php) Route::middleware('apipub') ->prefix('public/api') ->group(base_path('routes/apipub.php')); }, ) ->withMiddleware(function (Middleware $middleware) { // '*' trusts all proxies, required for correct IP/HTTPS detection behind AWS ALB/Vapor $middleware->trustProxies(at: '*'); $middleware->web(append: [ \App\Http\Middleware\LogRequestPathMiddleware::class, ]); $middleware->api(append: [ \App\Http\Middleware\LogRequestPathMiddleware::class, ]); $middleware->api(prepend: [ 'throttle:300,1', ]); $middleware->validateCsrfTokens(except: [ ]); $middleware->alias([ 'valid.token' => ValidateToken::class, 'token.check' => \App\Http\Middleware\TokenCheckerMiddleware::class, 'admin' => \App\Http\Middleware\EnsureUserIsAdmin::class, ]); $middleware->appendToGroup('apipub', [ \Illuminate\Routing\Middleware\SubstituteBindings::class, \App\Http\Middleware\LogRequestPathMiddleware::class, ]); }) ->withExceptions(function (Exceptions $exceptions) { // Custom exception rendering // $exceptions->render(function (MaintenanceModeException $e, $request) { // return response()->view('pages.errors.maintenance'); // }); $exceptions->render(function (AuthenticationException $e, $request) { return (new ApiResponseObject( 'Authentication', 'To keep your account secure, we need to re-validate it.', HttpStatus::ACCESS_UNAUTHORISED ))->handler(); }); // Don't flash these inputs $exceptions->dontFlash([ 'password', 'password_confirmation', ]); }) ->withCommands([ __DIR__ . '/../app/Console/Commands', __DIR__ . '/../app/Console/Commands/V2', ]) ->withSchedule(function ($schedule) { // Commands Version 2: Laravel Vapor/AWS $isEnabled = env('COMMANDS_V2_ENABLED', false); if ($isEnabled) { $schedule->command('housekeeping-s3-files-command') ->dailyAt('01:00') ->withoutOverlapping(); $schedule->command('password-reset-token-expriration-check-command') ->everySixHours() ->withoutOverlapping(); $schedule->command('new-user-registration-expire-check-command') ->everySixHours() ->withoutOverlapping(); if (env('APP_ENV') === 'production') { $schedule->command('email-do-to-vt-command') ->dailyAt('10:00') ->withoutOverlapping(); $schedule->command('seasonal-segmant-company-remove-command') ->dailyAt('01:00') ->withoutOverlapping(); $schedule->command('delete-bulk-download-files-command') ->hourly() ->withoutOverlapping(); $schedule->command('booking-expired-command') ->dailyAt('02:00') ->withoutOverlapping(); // Push company module to Lark // $schedule->command('lark:push-company-module') // ->hourly() // ->withoutOverlapping(); // Push booking module to Lark // $schedule->command('lark:push-booking-module') // ->hourly() // ->withoutOverlapping(); // // Push booking module to Lark // $schedule->command('lark:push-booking-transactions-module') // ->everyTenMinutes(); // $schedule->command('lark:push-booking-2025-transactions-module') // ->everyTenMinutes(); $schedule->command('lark:push-booking-september-2025-transactions-module') ->everyTenMinutes(); } } // Commands Version 1: Before Laravel Vapor/AWS else { $schedule->command('mail:EmailDoToVTCommand') ->dailyAt('10:00') ->withoutOverlapping(); $schedule->command('seasonalSegmantCompany:remove') ->dailyAt('01:00') ->appendOutputTo(storage_path() . '/logs/soft-delete-seasonal-segmant-company.log') ->withoutOverlapping(); $schedule->command('delete:bulk-download-files') ->hourly() ->appendOutputTo(storage_path() . '/logs/delete-bulk-download-files.log') ->withoutOverlapping(); $schedule->command('booking:expired') ->dailyAt('02:00') ->appendOutputTo(storage_path() . '/logs/expire-booking.log') ->withoutOverlapping(); } }) ->create();