104 lines
2.4 KiB
Go
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()
|
|
} |