feat: add app and database modules

This commit is contained in:
2026-05-21 16:05:11 +07:00
parent 37b7e783f5
commit fad70d096b
212 changed files with 23901 additions and 0 deletions
+327
View File
@@ -0,0 +1,327 @@
<?php
/**
* ============================================================
*
* @project biiproject
*
* @author Andika Debi Putra
*
* @email andikadebiputra@gmail.com
*
* @website https://biiproject.com
*
* @copyright Copyright (c) 2026 Andika Debi Putra
* @license Proprietary - All Rights Reserved
*
* @version 1.0.0
*
* @created 2026-05-01
* ============================================================
*
* Unauthorized copying, modification, distribution, or use
* of this file is strictly prohibited without prior written
* permission from the author.
* ============================================================
*/
namespace App\Providers;
use App\Events\ActivityLogCreated;
use App\Listeners\AnalyzeSystemError;
use App\Models\Permission;
use App\Models\Role;
use App\Models\User;
use App\Observers\PermissionObserver;
use App\Observers\RoleObserver;
use App\Observers\UserObserver;
use App\Services\Monitoring\SystemMonitoringService;
use App\Services\SystemConfig\SystemConfigService;
use Google\Client;
use Google\Service\Drive;
use Illuminate\Auth\Events\Login;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Filesystem\FilesystemAdapter;
use Illuminate\Http\Request;
use Illuminate\Log\Events\MessageLogged;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Gate;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Facades\URL;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
use League\Flysystem\Filesystem;
use Masbug\Flysystem\GoogleDriveAdapter;
use Spatie\Activitylog\Models\Activity;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*/
public function register(): void
{
//
}
/**
* Bootstrap any application services.
*/
public function boot(): void
{
// 🔒 Configure Rate Limiters
$this->configureRateLimiting();
// Super Admin Gate (Developer has full power)
Gate::before(function ($user, $capability) {
// Monitoring dynamic gates
$monitoringKeys = [
'view pulse' => 'engine_pulse_enabled',
'view telescope' => 'engine_telescope_enabled',
'view api docs' => 'engine_swagger_enabled',
'viewHorizon' => 'engine_horizon_enabled',
];
if (isset($monitoringKeys[$capability])) {
if (!get_setting($monitoringKeys[$capability], true)) {
return false; // Force deny if disabled at engine level
}
}
return $user->hasRole('Developer') ? true : null;
});
// Force HTTPS in production
if ($this->app->environment('production')) {
URL::forceScheme('https');
}
// Global Password Reset Expiry Override
if ($this->app->bound(SystemConfigService::class)) {
$expiry = get_setting('password_reset_link_expiry', 60);
config(['auth.passwords.users.expire' => $expiry]);
}
// User Observer
User::observe(UserObserver::class);
// Role Observer
Role::observe(RoleObserver::class);
// Permission Observer
Permission::observe(PermissionObserver::class);
// Windows Backup Compatibility Layer
$this->ensureWindowsBackupCompatibility();
// Google Drive Filesystem Adapter
$this->registerGoogleDriveAdapter();
// S3 Dynamic Config
$this->injectS3DynamicConfig();
// Backup Dynamic Config
$this->injectBackupDynamicConfig();
// Monitoring Dynamic Config
$this->injectMonitoringDynamicConfig();
// Dashboard View Composer
$this->registerDashboardComposer();
// Tab-permission Blade directives
$this->registerTabPermissionDirectives();
// 📡 Real-time Activity Log Broadcasting
Activity::created(function ($activity) {
try {
broadcast(new ActivityLogCreated($activity))->toOthers();
} catch (\Throwable $e) {
// Silently fail if Reverb is not running
}
});
// 🔍 Register AI error analysis listener (not auto-discovered for MessageLogged)
Event::listen(
MessageLogged::class,
AnalyzeSystemError::class
);
}
/**
* Configure the rate limiters for the application.
*/
protected function configureRateLimiting(): void
{
// Rate limiting for API
RateLimiter::for('api', function (Request $request) {
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
});
// Rate limiting for Login attempts
RateLimiter::for('login', function (Request $request) {
return Limit::perMinute(5)->by($request->ip())->response(function (Request $request, array $headers) {
return response()->json([
'message' => 'Too many login attempts. Please try again in 1 minute.',
'status' => 'error',
], 429, $headers);
});
});
}
/**
* Inject Monitoring configuration from database.
*/
protected function injectMonitoringDynamicConfig(): void
{
if (!$this->app->bound(SystemConfigService::class)) {
return;
}
config(['pulse.enabled' => get_setting('engine_pulse_enabled', true)]);
config(['telescope.enabled' => get_setting('engine_telescope_enabled', true)]);
if (!get_setting('engine_swagger_enabled', true)) {
config(['l5-swagger.documentations.default.routes.api' => null]);
config(['l5-swagger.defaults.routes.docs' => null]);
}
}
/**
* Register a view composer for the dashboard.
*/
protected function registerDashboardComposer(): void
{
view()->composer('pages.dashboard', function ($view) {
$stats = Cache::remember('dashboard_stats', now()->addMinutes(5), function () {
return [
'total_users' => User::count(),
'active_sessions' => app(SystemMonitoringService::class)->getActiveUsers(),
'today_actions' => Activity::whereDate('created_at', now()->today())->count(),
'failed_jobs' => DB::table('failed_jobs')->count(),
'recent_activities' => Activity::with('causer')->latest()->take(5)->get(),
];
});
$view->with('dashboardStats', $stats);
});
}
/**
* Register Google Drive filesystem adapter.
*/
protected function registerGoogleDriveAdapter(): void
{
Storage::extend('google', function ($app, $config) {
$clientId = get_setting('gdrive_client_id', $config['clientId'] ?? '');
$clientSecret = get_setting('gdrive_client_secret', $config['clientSecret'] ?? '');
$refreshToken = get_setting('gdrive_refresh_token', $config['refreshToken'] ?? '');
$folder = get_setting('gdrive_folder', $config['folder'] ?? 'LaravelBackups');
$client = new Client;
$client->setClientId($clientId);
$client->setClientSecret($clientSecret);
if ($refreshToken) {
$token = $client->refreshToken($refreshToken);
if (!isset($token['error'])) {
$client->setAccessToken($token);
}
}
$service = new Drive($client);
$adapter = new GoogleDriveAdapter($service, $folder, []);
$driver = new Filesystem($adapter);
return new FilesystemAdapter($driver, $adapter, $config);
});
}
/**
* Inject S3 credentials from database if set.
*/
protected function injectS3DynamicConfig(): void
{
if (get_setting('backup_db_driver') === 's3') {
config([
'filesystems.disks.s3.key' => get_setting('s3_key', config('filesystems.disks.s3.key')),
'filesystems.disks.s3.secret' => get_setting('s3_secret', config('filesystems.disks.s3.secret')),
'filesystems.disks.s3.region' => get_setting('s3_region', config('filesystems.disks.s3.region')),
'filesystems.disks.s3.bucket' => get_setting('s3_bucket', config('filesystems.disks.s3.bucket')),
'filesystems.disks.s3.endpoint' => get_setting('s3_endpoint', config('filesystems.disks.s3.endpoint')),
]);
}
}
/**
* Ensures Windows backup compatibility.
*/
protected function ensureWindowsBackupCompatibility(): void
{
if (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') {
return;
}
$dbDriver = config('database.default');
if (config("database.connections.{$dbDriver}.dump.dump_binary_path")) {
return;
}
$isPg = $dbDriver === 'pgsql';
$binary = $isPg ? 'pg_dump.exe' : 'mysqldump.exe';
$paths = $isPg ? ['C:\laragon\bin\postgresql\*\bin', 'C:\Program Files\PostgreSQL\*\bin'] : ['C:\laragon\bin\mysql\*\bin', 'C:\xampp\mysql\bin'];
foreach ($paths as $path) {
$matchedPaths = glob($path, GLOB_ONLYDIR);
if (!$matchedPaths) {
continue;
}
$foundPath = $matchedPaths[count($matchedPaths) - 1];
if (file_exists($foundPath . DIRECTORY_SEPARATOR . $binary)) {
config(["database.connections.{$dbDriver}.dump.dump_binary_path" => $foundPath]);
break;
}
}
}
/*
* Register Blade if/unless directives for tab-level permission checks.
*
* Usage in Blade:
* @cantab('global settings', 'login-security') ... @endcantab
* @managetab('mobile settings', 'branding') ... @endmanagetab
*/
protected function registerTabPermissionDirectives(): void
{
Blade::if('cantab', fn (string $menu, string $tab) => can_view_tab($menu, $tab));
Blade::if('managetab', fn (string $menu, string $tab) => can_manage_tab($menu, $tab));
Blade::if('canviewanytab', fn (string $menu) => can_view_any_tab($menu));
Blade::if('canmanageanytab', fn (string $menu) => can_manage_any_tab($menu));
}
/**
* Inject Backup configuration from database.
*/
protected function injectBackupDynamicConfig(): void
{
if (!$this->app->bound(SystemConfigService::class)) {
return;
}
$driver = get_setting('backup_db_driver', 'local');
config(['backup.backup.destination.disks' => [$driver]]);
config(['backup.monitor_backups.0.disks' => [$driver]]);
if ($driver === 'gdrive') {
config([
'filesystems.disks.gdrive.clientId' => get_setting('gdrive_client_id'),
'filesystems.disks.gdrive.clientSecret' => get_setting('gdrive_client_secret'),
'filesystems.disks.gdrive.refreshToken' => get_setting('gdrive_refresh_token'),
'filesystems.disks.gdrive.folder' => get_setting('gdrive_folder', 'LaravelBackups'),
]);
}
}
}