// internal/workers/notification_worker.go package workers import ( "log" "lost-and-found/internal/models" "lost-and-found/internal/repositories" "time" "gorm.io/gorm" ) // NotificationWorker handles sending notifications asynchronously type NotificationWorker struct { db *gorm.DB notificationRepo *repositories.NotificationRepository matchRepo *repositories.MatchResultRepository stopChan chan bool } // NewNotificationWorker creates a new notification worker func NewNotificationWorker(db *gorm.DB) *NotificationWorker { return &NotificationWorker{ db: db, notificationRepo: repositories.NewNotificationRepository(db), matchRepo: repositories.NewMatchResultRepository(db), stopChan: make(chan bool), } } // Start starts the notification worker func (w *NotificationWorker) Start() { log.Println("📬 Notification Worker started") // Run every 5 minutes ticker := time.NewTicker(5 * time.Minute) defer ticker.Stop() for { select { case <-ticker.C: w.sendPendingNotifications() case <-w.stopChan: log.Println("📬 Notification Worker stopped") return } } } // Stop stops the notification worker func (w *NotificationWorker) Stop() { w.stopChan <- true } // sendPendingNotifications sends notifications for unnotified matches func (w *NotificationWorker) sendPendingNotifications() { log.Println("🔍 Checking for pending notifications...") // Get unnotified matches matches, err := w.matchRepo.FindUnnotifiedMatches() if err != nil { log.Printf("❌ Error fetching unnotified matches: %v", err) return } if len(matches) == 0 { log.Println("✅ No pending notifications") return } log.Printf("📧 Found %d pending notifications", len(matches)) sentCount := 0 for _, match := range matches { // Send notification to lost item owner if err := w.sendMatchNotification(&match); err != nil { log.Printf("❌ Failed to send notification for match ID %d: %v", match.ID, err) continue } // Mark as notified if err := w.matchRepo.MarkAsNotified(match.ID); err != nil { log.Printf("❌ Failed to mark match ID %d as notified: %v", match.ID, err) continue } sentCount++ } log.Printf("✅ Sent %d notifications", sentCount) } // sendMatchNotification sends a match notification func (w *NotificationWorker) sendMatchNotification(match *models.MatchResult) error { // Create notification err := models.CreateMatchNotification( w.db, match.LostItem.UserID, match.Item.Name, match.ID, ) if err != nil { return err } log.Printf("📧 Sent match notification to user ID %d for item: %s", match.LostItem.UserID, match.Item.Name) return nil } // RunNow runs notification sending immediately (for testing) func (w *NotificationWorker) RunNow() { log.Println("▶️ Running notification sending manually...") w.sendPendingNotifications() }