Initialer Laravel Commit für BetiX
This commit is contained in:
120
bootstrap/app.php
Normal file
120
bootstrap/app.php
Normal file
@@ -0,0 +1,120 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Middleware\HandleAppearance;
|
||||
use App\Http\Middleware\HandleInertiaRequests;
|
||||
use App\Http\Middleware\SetLocale;
|
||||
use App\Http\Middleware\CheckBanned;
|
||||
use App\Http\Middleware\DetectCiphertextInJson;
|
||||
use App\Http\Middleware\GeoBlockMiddleware;
|
||||
use App\Http\Middleware\MaintenanceModeMiddleware;
|
||||
use Illuminate\Foundation\Application;
|
||||
use Illuminate\Foundation\Configuration\Exceptions;
|
||||
use Illuminate\Foundation\Configuration\Middleware;
|
||||
use Illuminate\Http\Middleware\AddLinkHeadersForPreloadedAssets;
|
||||
|
||||
return Application::configure(basePath: dirname(__DIR__))
|
||||
->withRouting(
|
||||
web: __DIR__.'/../routes/web.php',
|
||||
commands: __DIR__.'/../routes/console.php',
|
||||
health: '/up',
|
||||
then: function () {
|
||||
// B2B operator routes — served at /operator/* (no /api prefix)
|
||||
\Illuminate\Support\Facades\Route::middleware(['throttle:60,1'])
|
||||
->prefix('operator')
|
||||
->group(base_path('routes/operator.php'));
|
||||
},
|
||||
)
|
||||
->withSchedule(function (\Illuminate\Console\Scheduling\Schedule $schedule): void {
|
||||
// Expire old user bonuses every hour
|
||||
$schedule->call(function () {
|
||||
app(\App\Services\BonusService::class)->expireBonuses();
|
||||
})->hourly()->name('bonus:expire')->withoutOverlapping();
|
||||
|
||||
// Recalculate VIP levels based on total wager – runs daily at 03:00
|
||||
$schedule->call(function () {
|
||||
$thresholds = [5 => 10000, 4 => 2000, 3 => 500, 2 => 100, 1 => 0];
|
||||
\App\Models\User::chunk(200, function ($users) use ($thresholds) {
|
||||
foreach ($users as $user) {
|
||||
$totalWager = \App\Models\GameBet::where('user_id', $user->id)->sum('wager_amount');
|
||||
$newLevel = 1;
|
||||
foreach ($thresholds as $level => $min) {
|
||||
if ($totalWager >= $min) { $newLevel = $level; break; }
|
||||
}
|
||||
if ($user->vip_level !== $newLevel) {
|
||||
$user->forceFill(['vip_level' => $newLevel])->save();
|
||||
}
|
||||
}
|
||||
});
|
||||
})->dailyAt('03:00')->name('vip:recalculate')->withoutOverlapping();
|
||||
|
||||
// Flag / notify inactive users (no login for 90 days) – runs weekly
|
||||
$schedule->call(function () {
|
||||
$cutoff = now()->subDays(90);
|
||||
\App\Models\User::where('last_login_at', '<', $cutoff)
|
||||
->where('is_banned', false)
|
||||
->chunk(100, function ($users) {
|
||||
foreach ($users as $user) {
|
||||
\Illuminate\Support\Facades\Log::info('Inactive user flagged', [
|
||||
'user_id' => $user->id,
|
||||
'last_login_at' => $user->last_login_at,
|
||||
]);
|
||||
}
|
||||
});
|
||||
})->weekly()->name('users:cleanup-inactive')->withoutOverlapping();
|
||||
})
|
||||
->withMiddleware(function (Middleware $middleware): void {
|
||||
$middleware->encryptCookies(except: ['appearance', 'sidebar_state', 'XSRF-TOKEN']);
|
||||
|
||||
$middleware->validateCsrfTokens(except: [
|
||||
'api/webhooks/nowpayments',
|
||||
'api/betix/*',
|
||||
'wallet/deposits',
|
||||
'locale',
|
||||
'api/wallet/vault/*',
|
||||
'api/wallet/vault',
|
||||
// Operator B2B API — authenticated via license key, not CSRF
|
||||
'operator/*',
|
||||
]);
|
||||
|
||||
$middleware->web(append: [
|
||||
HandleAppearance::class,
|
||||
SetLocale::class,
|
||||
HandleInertiaRequests::class,
|
||||
AddLinkHeadersForPreloadedAssets::class,
|
||||
CheckBanned::class,
|
||||
DetectCiphertextInJson::class,
|
||||
GeoBlockMiddleware::class,
|
||||
MaintenanceModeMiddleware::class,
|
||||
]);
|
||||
|
||||
// Route middleware aliases
|
||||
$middleware->alias([
|
||||
'restrict' => \App\Http\Middleware\EnforceRestriction::class,
|
||||
'license.key' => \App\Http\Middleware\ValidateLicenseKey::class,
|
||||
]);
|
||||
})
|
||||
->withExceptions(function (Exceptions $exceptions): void {
|
||||
$exceptions->render(function (\Illuminate\Validation\ValidationException $e, $request) {
|
||||
if ($request->is('api/*')) {
|
||||
return response()->json([
|
||||
'message' => 'The given data was invalid.',
|
||||
'errors' => $e->errors(),
|
||||
], 422);
|
||||
}
|
||||
});
|
||||
|
||||
$exceptions->render(function (\Illuminate\Auth\AuthenticationException $e, $request) {
|
||||
if ($request->is('api/*')) {
|
||||
return response()->json(['message' => 'Unauthenticated.'], 401);
|
||||
}
|
||||
});
|
||||
|
||||
$exceptions->render(function (\Symfony\Component\HttpKernel\Exception\HttpException $e, $request) {
|
||||
if ($request->is('api/*')) {
|
||||
return response()->json([
|
||||
'message' => $e->getMessage() ?: 'An error occurred.',
|
||||
'status' => $e->getStatusCode(),
|
||||
], $e->getStatusCode());
|
||||
}
|
||||
});
|
||||
})->create();
|
||||
Reference in New Issue
Block a user