Admin Menü neu geordnet.
Introduced a two-tier media pipeline with dynamic disks, asset tracking, admin controls, and alerting around
upload/archival workflows.
- Added storage metadata + asset tables and models so every photo/variant knows where it lives
(database/migrations/2025_10_20_090000_create_media_storage_targets_table.php, database/ migrations/2025_10_20_090200_create_event_media_assets_table.php, app/Models/MediaStorageTarget.php:1, app/
Models/EventMediaAsset.php:1, app/Models/EventStorageAssignment.php:1, app/Models/Event.php:27).
- Rewired guest and tenant uploads to pick the event’s hot disk, persist EventMediaAsset records, compute
checksums, and clean up on delete (app/Http/Controllers/Api/EventPublicController.php:243, app/Http/
Controllers/Api/Tenant/PhotoController.php:25, app/Models/Photo.php:25).
- Implemented storage services, archival job scaffolding, monitoring config, and queue-failure notifications for upload issues (app/Services/Storage/EventStorageManager.php:16, app/Services/Storage/
StorageHealthService.php:9, app/Jobs/ArchiveEventMediaAssets.php:16, app/Providers/AppServiceProvider.php:39, app/Notifications/UploadPipelineFailed.php:8, config/storage-monitor.php:1).
- Seeded default hot/cold targets and exposed super-admin tooling via a Filament resource and capacity widget (database/seeders/MediaStorageTargetSeeder.php:13, database/seeders/DatabaseSeeder.php:17, app/Filament/Resources/MediaStorageTargetResource.php:1, app/Filament/Widgets/StorageCapacityWidget.php:12, app/Providers/Filament/SuperAdminPanelProvider.php:47).
- Dropped cron skeletons and artisan placeholders to schedule storage monitoring, archival dispatch, and upload queue health checks (cron/storage_monitor.sh, cron/archive_dispatcher.sh, cron/upload_queue_health.sh, routes/console.php:9).
This commit is contained in:
@@ -5,8 +5,14 @@ namespace App\Providers;
|
||||
use App\Services\Checkout\CheckoutAssignmentService;
|
||||
use App\Services\Checkout\CheckoutPaymentService;
|
||||
use App\Services\Checkout\CheckoutSessionService;
|
||||
use App\Notifications\UploadPipelineFailed;
|
||||
use App\Services\Storage\EventStorageManager;
|
||||
use App\Services\Storage\StorageHealthService;
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Queue\Events\JobFailed;
|
||||
use Illuminate\Support\Facades\Notification;
|
||||
use Illuminate\Support\Facades\Queue;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
use Inertia\Inertia;
|
||||
@@ -21,6 +27,8 @@ class AppServiceProvider extends ServiceProvider
|
||||
$this->app->singleton(CheckoutSessionService::class);
|
||||
$this->app->singleton(CheckoutAssignmentService::class);
|
||||
$this->app->singleton(CheckoutPaymentService::class);
|
||||
$this->app->singleton(EventStorageManager::class);
|
||||
$this->app->singleton(StorageHealthService::class);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -28,6 +36,8 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
$this->app->make(EventStorageManager::class)->registerDynamicDisks();
|
||||
|
||||
RateLimiter::for('tenant-api', function (Request $request) {
|
||||
$tenantId = $request->attributes->get('tenant_id')
|
||||
?? $request->user()?->tenant_id
|
||||
@@ -42,12 +52,41 @@ class AppServiceProvider extends ServiceProvider
|
||||
return Limit::perMinute(10)->by('oauth:' . ($request->ip() ?? 'unknown'));
|
||||
});
|
||||
|
||||
\Inertia\Inertia::share('locale', function () {
|
||||
return app()->getLocale();
|
||||
});
|
||||
Inertia::share('locale', fn () => app()->getLocale());
|
||||
|
||||
if (config('storage-monitor.queue_failure_alerts')) {
|
||||
Queue::failing(function (JobFailed $event) {
|
||||
$context = [
|
||||
'queue' => $event->job->getQueue(),
|
||||
'job' => $event->job->resolveName(),
|
||||
'exception' => $event->exception->getMessage(),
|
||||
];
|
||||
|
||||
$command = data_get($event->job->payload(), 'data.command');
|
||||
|
||||
if (is_string($command)) {
|
||||
try {
|
||||
$instance = @unserialize($command, ['allowed_classes' => true]);
|
||||
if (is_object($instance)) {
|
||||
foreach (['eventId' => 'event_id', 'photoId' => 'photo_id'] as $property => $label) {
|
||||
if (isset($instance->{$property})) {
|
||||
$context[$label] = $instance->{$property};
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\Throwable $e) {
|
||||
$context['unserialize_error'] = $e->getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
if ($mail = config('storage-monitor.alert_recipients.mail')) {
|
||||
Notification::route('mail', $mail)->notify(new UploadPipelineFailed($context));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if ($this->app->runningInConsole()) {
|
||||
$this->app->register(\App\Providers\Filament\AdminPanelProvider::class);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user