117 lines
2.8 KiB
Go
117 lines
2.8 KiB
Go
// 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()
|
|
} |