Initialer Laravel Commit für BetiX
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled

This commit is contained in:
2026-04-04 18:01:50 +02:00
commit 0280278978
374 changed files with 65210 additions and 0 deletions

120
bootstrap/app.php Normal file
View 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();

2
bootstrap/cache/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
*
!.gitignore

6
bootstrap/providers.php Normal file
View File

@@ -0,0 +1,6 @@
<?php
return [
App\Providers\AppServiceProvider::class,
App\Providers\FortifyServiceProvider::class,
];