// internal/repositories/match_result_repo.go package repositories import ( "errors" "lost-and-found/internal/models" "gorm.io/gorm" ) type MatchResultRepository struct { db *gorm.DB } func NewMatchResultRepository(db *gorm.DB) *MatchResultRepository { return &MatchResultRepository{db: db} } // Create creates a new match result func (r *MatchResultRepository) Create(match *models.MatchResult) error { return r.db.Create(match).Error } // FindByID finds match result by ID func (r *MatchResultRepository) FindByID(id uint) (*models.MatchResult, error) { var match models.MatchResult err := r.db.Preload("LostItem").Preload("LostItem.User"). Preload("Item").Preload("Item.Category"). First(&match, id).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, errors.New("match result not found") } return nil, err } return &match, nil } // FindAll returns all match results with filters func (r *MatchResultRepository) FindAll(page, limit int, lostItemID, itemID *uint) ([]models.MatchResult, int64, error) { var matches []models.MatchResult var total int64 query := r.db.Model(&models.MatchResult{}) // Apply filters if lostItemID != nil { query = query.Where("lost_item_id = ?", *lostItemID) } if itemID != nil { query = query.Where("item_id = ?", *itemID) } // Count total if err := query.Count(&total).Error; err != nil { return nil, 0, err } // Get paginated results offset := (page - 1) * limit err := query.Preload("LostItem").Preload("LostItem.User"). Preload("Item").Preload("Item.Category"). Order("similarity_score DESC"). Offset(offset).Limit(limit).Find(&matches).Error if err != nil { return nil, 0, err } return matches, total, nil } // FindByLostItem finds match results for a lost item func (r *MatchResultRepository) FindByLostItem(lostItemID uint) ([]models.MatchResult, error) { var matches []models.MatchResult err := r.db.Where("lost_item_id = ?", lostItemID). Preload("Item").Preload("Item.Category"). Order("similarity_score DESC").Find(&matches).Error return matches, err } // FindByItem finds match results for an item func (r *MatchResultRepository) FindByItem(itemID uint) ([]models.MatchResult, error) { var matches []models.MatchResult err := r.db.Where("item_id = ?", itemID). Preload("LostItem").Preload("LostItem.User"). Order("similarity_score DESC").Find(&matches).Error return matches, err } // Update updates match result func (r *MatchResultRepository) Update(match *models.MatchResult) error { return r.db.Save(match).Error } // MarkAsNotified marks match result as notified func (r *MatchResultRepository) MarkAsNotified(id uint) error { return r.db.Model(&models.MatchResult{}).Where("id = ?", id).Update("is_notified", true).Error } // FindUnnotifiedMatches finds match results that haven't been notified func (r *MatchResultRepository) FindUnnotifiedMatches() ([]models.MatchResult, error) { var matches []models.MatchResult err := r.db.Where("is_notified = ?", false). Preload("LostItem").Preload("LostItem.User"). Preload("Item").Preload("Item.Category"). Order("matched_at ASC").Find(&matches).Error return matches, err } // Delete deletes a match result func (r *MatchResultRepository) Delete(id uint) error { return r.db.Delete(&models.MatchResult{}, id).Error } // CheckExistingMatch checks if a match already exists func (r *MatchResultRepository) CheckExistingMatch(lostItemID, itemID uint) (bool, error) { var count int64 err := r.db.Model(&models.MatchResult{}). Where("lost_item_id = ? AND item_id = ?", lostItemID, itemID). Count(&count).Error if err != nil { return false, err } return count > 0, nil }