feat: add guest notification insights

This commit is contained in:
Codex Agent
2025-11-12 19:31:13 +01:00
parent 642541c8fb
commit 2c412e3764
7 changed files with 440 additions and 7 deletions

View File

@@ -2,6 +2,7 @@
namespace App\Http\Controllers\Api\Tenant;
use App\Enums\GuestNotificationType;
use App\Http\Controllers\Controller;
use App\Http\Requests\Tenant\EventStoreRequest;
use App\Http\Resources\Tenant\EventJoinTokenResource;
@@ -9,6 +10,7 @@ use App\Http\Resources\Tenant\EventResource;
use App\Http\Resources\Tenant\PhotoResource;
use App\Models\Event;
use App\Models\EventPackage;
use App\Models\GuestNotification;
use App\Models\Package;
use App\Models\Photo;
use App\Models\Tenant;
@@ -426,6 +428,47 @@ class EventController extends Controller
->take(3)
->get();
$notificationQuery = GuestNotification::query()->where('event_id', $event->id);
$notificationTotal = (clone $notificationQuery)->count();
$notificationTypeCounts = (clone $notificationQuery)
->select('type', DB::raw('COUNT(*) as total'))
->groupBy('type')
->pluck('total', 'type')
->map(fn ($value) => (int) $value)
->toArray();
$lastNotificationAt = $notificationTotal > 0
? (clone $notificationQuery)->latest('created_at')->value('created_at')
: null;
$lastBroadcast = (clone $notificationQuery)
->where('type', GuestNotificationType::BROADCAST->value)
->latest('created_at')
->first(['id', 'title', 'created_at']);
$recentNotifications = (clone $notificationQuery)
->latest('created_at')
->limit(5)
->get(['id', 'title', 'type', 'status', 'audience_scope', 'created_at']);
$notificationsPayload = [
'summary' => [
'total' => $notificationTotal,
'last_sent_at' => $lastNotificationAt ? $lastNotificationAt->toAtomString() : null,
'by_type' => $notificationTypeCounts,
'broadcasts' => [
'total' => $notificationTypeCounts[GuestNotificationType::BROADCAST->value] ?? 0,
'last_title' => $lastBroadcast?->title,
'last_sent_at' => $lastBroadcast?->created_at?->toAtomString(),
],
],
'recent' => $recentNotifications->map(fn (GuestNotification $notification) => [
'id' => $notification->id,
'title' => $notification->title,
'type' => $notification->type->value,
'status' => $notification->status->value,
'audience_scope' => $notification->audience_scope->value,
'created_at' => $notification->created_at?->toAtomString(),
])->all(),
];
$alerts = [];
if (($event->settings['engagement_mode'] ?? 'tasks') !== 'photo_only' && $taskSummary['total'] === 0) {
$alerts[] = 'no_tasks';
@@ -461,6 +504,7 @@ class EventController extends Controller
],
'items' => EventJoinTokenResource::collection($recentInvites)->resolve($request),
],
'notifications' => $notificationsPayload,
'alerts' => $alerts,
]);
}