2025-11-23 22:49:46 +07:00

104 lines
2.4 KiB
Go

// internal/workers/expire_worker.go
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()
}