package workers import ( "log" "lost-and-found/internal/models" "lost-and-found/internal/repositories" "time" "gorm.io/gorm" ) // ExpireWorker handles item expiration background tasks type ExpireWorker struct { db *gorm.DB itemRepo *repositories.ItemRepository archiveRepo *repositories.ArchiveRepository stopChan chan bool } // NewExpireWorker creates a new expire worker func NewExpireWorker(db *gorm.DB) *ExpireWorker { return &ExpireWorker{ db: db, itemRepo: repositories.NewItemRepository(db), archiveRepo: repositories.NewArchiveRepository(db), stopChan: make(chan bool), } } // Start starts the expire worker func (w *ExpireWorker) Start() { log.Println("⏰ Expire Worker started") // Run immediately on start w.expireItems() // Then run every hour ticker := time.NewTicker(1 * time.Hour) defer ticker.Stop() for { select { case <-ticker.C: w.expireItems() case <-w.stopChan: log.Println("⏰ Expire Worker stopped") return } } } // Stop stops the expire worker func (w *ExpireWorker) Stop() { w.stopChan <- true } // expireItems finds and expires items that have passed their expiration date func (w *ExpireWorker) expireItems() { log.Println("🔍 Checking for expired items...") // Find expired items expiredItems, err := w.itemRepo.FindExpired() if err != nil { log.Printf("❌ Error finding expired items: %v", err) return } if len(expiredItems) == 0 { log.Println("✅ No expired items found") return } log.Printf("📦 Found %d expired items", len(expiredItems)) // Process each expired item expiredCount := 0 for _, item := range expiredItems { if err := w.archiveExpiredItem(&item); err != nil { log.Printf("❌ Failed to archive item ID %d: %v", item.ID, err) continue } expiredCount++ } log.Printf("✅ Successfully archived %d expired items", expiredCount) } // archiveExpiredItem archives an expired item func (w *ExpireWorker) archiveExpiredItem(item *models.Item) error { // Archive the item if err := w.itemRepo.ArchiveItem(item, models.ArchiveReasonExpired, nil); err != nil { return err } log.Printf("📦 Archived expired item: %s (ID: %d)", item.Name, item.ID) return nil } // RunNow runs expiration check immediately (for testing) func (w *ExpireWorker) RunNow() { log.Println("▶️ Running expiration check manually...") w.expireItems() }