bootstrapWorker(); /** @var NotificationRepository $repository */ $repository = $container->get(NotificationRepository::class); // Sample notification types final readonly class NotificationType implements App\Framework\Notification\ValueObjects\NotificationTypeInterface { public function __construct(private string $value) {} public function toString(): string { return $this->value; } public function getDisplayName(): string { return match ($this->value) { 'ml_performance_degradation' => 'ML Performance Degradation', 'ml_model_deployed' => 'ML Model Deployed', 'ml_training_complete' => 'ML Training Complete', 'system_alert' => 'System Alert', 'security_alert' => 'Security Alert', 'info' => 'Information', default => ucwords(str_replace('_', ' ', $this->value)), }; } public function isCritical(): bool { return in_array($this->value, [ 'ml_performance_degradation', 'security_alert', 'system_alert' ], true); } public function equals($other): bool { return $other instanceof self && $this->value === $other->value; } } // Sample notifications to create $notifications = [ // ML Performance Alerts [ 'type' => 'ml_performance_degradation', 'title' => 'ML Model Performance Degradation Detected', 'body' => 'The spam-classifier model (v2.0.0) is experiencing performance degradation. Current accuracy: 78% (below threshold of 85%). Immediate attention recommended.', 'priority' => NotificationPriority::URGENT, 'action_url' => '/admin/ml/models/spam-classifier', 'action_label' => 'View Model Details', 'created_offset' => -7200, // 2 hours ago ], [ 'type' => 'ml_model_deployed', 'title' => 'New ML Model Deployed Successfully', 'body' => 'Fraud detector model v1.0.0 has been successfully deployed to production. Initial accuracy: 94%. Monitoring active.', 'priority' => NotificationPriority::NORMAL, 'action_url' => '/admin/ml/models/fraud-detector', 'action_label' => 'View Deployment', 'created_offset' => -3600, // 1 hour ago ], [ 'type' => 'ml_training_complete', 'title' => 'Model Training Completed', 'body' => 'Sentiment analyzer training completed successfully. New version 2.1.0 ready for deployment. Validation accuracy: 91%.', 'priority' => NotificationPriority::HIGH, 'action_url' => '/admin/ml/models/sentiment-analyzer', 'action_label' => 'Review & Deploy', 'created_offset' => -1800, // 30 minutes ago ], // System Alerts [ 'type' => 'system_alert', 'title' => 'High Memory Usage Detected', 'body' => 'System memory usage exceeded 85% threshold. Current usage: 87%. Consider scaling resources or optimizing memory-intensive processes.', 'priority' => NotificationPriority::HIGH, 'action_url' => '/admin/performance', 'action_label' => 'View Metrics', 'created_offset' => -900, // 15 minutes ago ], [ 'type' => 'system_alert', 'title' => 'Queue Backlog Warning', 'body' => 'Job queue backlog detected. 1,234 pending jobs in queue. Processing rate: 45 jobs/minute. Estimated clearance time: 27 minutes.', 'priority' => NotificationPriority::NORMAL, 'action_url' => '/admin/queue', 'action_label' => 'View Queue', 'created_offset' => -600, // 10 minutes ago ], // Security Alerts [ 'type' => 'security_alert', 'title' => 'Suspicious Login Attempts Detected', 'body' => 'Multiple failed login attempts detected from IP 203.0.113.42. Rate limiting applied. Review access logs for potential security threat.', 'priority' => NotificationPriority::URGENT, 'action_url' => '/admin/security/logs', 'action_label' => 'View Security Logs', 'created_offset' => -300, // 5 minutes ago ], [ 'type' => 'security_alert', 'title' => 'WAF Blocked Malicious Request', 'body' => 'Web Application Firewall blocked SQL injection attempt. Attack pattern detected: UNION SELECT. Source IP: 198.51.100.10.', 'priority' => NotificationPriority::HIGH, 'action_url' => '/admin/security/waf', 'action_label' => 'View WAF Logs', 'created_offset' => -120, // 2 minutes ago ], // Info Notifications [ 'type' => 'info', 'title' => 'System Backup Completed', 'body' => 'Daily system backup completed successfully. Backup size: 2.3 GB. Next scheduled backup: Tomorrow at 2:00 AM.', 'priority' => NotificationPriority::LOW, 'action_url' => '/admin/backups', 'action_label' => 'View Backups', 'created_offset' => -86400, // 1 day ago ], [ 'type' => 'info', 'title' => 'Database Optimization Recommended', 'body' => 'Database performance analysis suggests optimizing 3 tables. Estimated performance improvement: 15%. Schedule maintenance window for optimization.', 'priority' => NotificationPriority::NORMAL, 'action_url' => '/admin/database/optimization', 'action_label' => 'View Recommendations', 'created_offset' => -172800, // 2 days ago ], [ 'type' => 'info', 'title' => 'Weekly Performance Report Available', 'body' => 'Weekly system performance report is now available. Key metrics: 99.8% uptime, 145ms avg response time, 1.2M requests processed.', 'priority' => NotificationPriority::LOW, 'action_url' => '/admin/reports/weekly', 'action_label' => 'View Report', 'created_offset' => -259200, // 3 days ago ], ]; echo "Creating " . count($notifications) . " sample notifications...\n\n"; $createdCount = 0; $now = time(); foreach ($notifications as $index => $notificationData) { $notificationNum = $index + 1; echo "[$notificationNum/" . count($notifications) . "] Creating: {$notificationData['title']}\n"; try { // Create notification timestamp (offset from now) $createdAt = Timestamp::fromTimestamp($now + $notificationData['created_offset']); // For recent notifications (< 1 hour ago), leave unread // For older notifications, mark some as read $isRecent = abs($notificationData['created_offset']) < 3600; $shouldBeRead = !$isRecent && (($index % 3) === 0); // Mark every 3rd older notification as read $notification = new Notification( id: NotificationId::generate(), recipientId: 'admin', type: new NotificationType($notificationData['type']), title: $notificationData['title'], body: $notificationData['body'], createdAt: $createdAt, data: [], channels: [NotificationChannel::DATABASE], priority: $notificationData['priority'], status: $shouldBeRead ? NotificationStatus::READ : NotificationStatus::SENT, sentAt: $createdAt, readAt: $shouldBeRead ? Timestamp::fromTimestamp($now + $notificationData['created_offset'] + 300) : null, actionUrl: $notificationData['action_url'], actionLabel: $notificationData['action_label'] ); $repository->save($notification); $createdCount++; $statusIcon = $shouldBeRead ? '✓' : '📬'; $priorityLabel = $notificationData['priority']->value; echo " $statusIcon Successfully created ($priorityLabel priority, " . ($shouldBeRead ? 'read' : 'unread') . ")\n"; echo " - Created: " . $createdAt->format('Y-m-d H:i:s') . "\n"; if ($notificationData['action_url']) { echo " - Action: {$notificationData['action_label']} → {$notificationData['action_url']}\n"; } echo "\n"; } catch (\Exception $e) { echo " ❌ Error: {$e->getMessage()}\n\n"; } } echo "=====================\n"; echo "✅ Seeding complete!\n\n"; echo "Summary:\n"; echo "- Total notifications created: $createdCount\n"; // Get current stats $unreadCount = $repository->countUnreadByUser('admin'); echo "- Unread notifications: $unreadCount\n"; $allNotifications = $repository->findByUser('admin', limit: 100); echo "- Total notifications for admin: " . count($allNotifications) . "\n\n"; echo "Next steps:\n"; echo "1. Visit https://localhost/admin/notifications to view the notifications\n"; echo "2. Test mark as read functionality\n"; echo "3. Test mark all as read functionality\n"; echo "4. Verify unread badge updates in real-time\n";