veza/veza-backend-api/internal/services/gear_warranty_notifier.go

94 lines
2.5 KiB
Go
Raw Normal View History

package services
import (
"context"
"fmt"
"time"
"github.com/google/uuid"
"go.uber.org/zap"
"gorm.io/gorm"
)
// GearWarrantyNotifier sends notifications for gear items with expiring warranty
type GearWarrantyNotifier struct {
db *gorm.DB
notificationService *NotificationService
logger *zap.Logger
interval time.Duration
}
// NewGearWarrantyNotifier creates a new warranty notifier
func NewGearWarrantyNotifier(db *gorm.DB, notificationService *NotificationService, logger *zap.Logger) *GearWarrantyNotifier {
return &GearWarrantyNotifier{
db: db,
notificationService: notificationService,
logger: logger,
interval: 24 * time.Hour,
}
}
// Start runs the notifier loop
func (n *GearWarrantyNotifier) Start(ctx context.Context) {
if n.notificationService == nil {
n.logger.Info("Gear warranty notifier: notification service not configured, skipping")
return
}
ticker := time.NewTicker(n.interval)
defer ticker.Stop()
n.logger.Info("Gear warranty notifier started", zap.Duration("interval", n.interval))
for {
select {
case <-ctx.Done():
return
case <-ticker.C:
if err := n.runCheck(ctx); err != nil {
n.logger.Error("Gear warranty check failed", zap.Error(err))
}
}
}
}
func (n *GearWarrantyNotifier) runCheck(ctx context.Context) error {
var items []struct {
ID uuid.UUID
UserID uuid.UUID
Name string
WarrantyExpire *time.Time
}
err := n.db.WithContext(ctx).Raw(`
SELECT id, user_id, name, warranty_expire
FROM gear_items
WHERE warranty_expire IS NOT NULL
AND warranty_expire > NOW()
AND warranty_expire <= NOW() + INTERVAL '30 days'
AND deleted_at IS NULL
`).Scan(&items).Error
if err != nil {
return fmt.Errorf("query expiring gear: %w", err)
}
for _, item := range items {
if item.WarrantyExpire == nil {
continue
}
daysLeft := int(time.Until(*item.WarrantyExpire).Hours() / 24)
if daysLeft < 0 {
daysLeft = 0
}
msg := fmt.Sprintf("Warranty for %s expires in %d days", item.Name, daysLeft)
link := fmt.Sprintf("/inventory/gear/%s", item.ID)
if err := n.notificationService.CreateNotification(item.UserID, "gear_warranty", "Warranty expiring soon", msg, link); err != nil {
n.logger.Warn("failed to send warranty notification", zap.String("gear_id", item.ID.String()), zap.Error(err))
}
}
if len(items) > 0 {
n.logger.Info("Gear warranty notifications sent", zap.Int("count", len(items)))
}
return nil
}