129 lines
4.1 KiB
Go
129 lines
4.1 KiB
Go
// internal/models/match_result.go
|
|
package models
|
|
|
|
import (
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// MatchResult represents auto-matching result between lost item and found item
|
|
type MatchResult struct {
|
|
ID uint `gorm:"primaryKey" json:"id"`
|
|
LostItemID uint `gorm:"not null" json:"lost_item_id"`
|
|
LostItem LostItem `gorm:"foreignKey:LostItemID" json:"lost_item,omitempty"`
|
|
ItemID uint `gorm:"not null" json:"item_id"`
|
|
Item Item `gorm:"foreignKey:ItemID" json:"item,omitempty"`
|
|
SimilarityScore float64 `gorm:"type:decimal(5,2)" json:"similarity_score"` // Percentage match (0-100)
|
|
MatchedFields string `gorm:"type:text" json:"matched_fields"` // JSON of matched fields
|
|
MatchedAt time.Time `gorm:"not null" json:"matched_at"`
|
|
IsNotified bool `gorm:"default:false" json:"is_notified"` // Was user notified?
|
|
CreatedAt time.Time `json:"created_at"`
|
|
UpdatedAt time.Time `json:"updated_at"`
|
|
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
|
}
|
|
|
|
// TableName specifies the table name for MatchResult model
|
|
func (MatchResult) TableName() string {
|
|
return "match_results"
|
|
}
|
|
|
|
// BeforeCreate hook
|
|
func (mr *MatchResult) BeforeCreate(tx *gorm.DB) error {
|
|
if mr.MatchedAt.IsZero() {
|
|
mr.MatchedAt = time.Now()
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// IsHighMatch checks if similarity score is high (>= 70%)
|
|
func (mr *MatchResult) IsHighMatch() bool {
|
|
return mr.SimilarityScore >= 70.0
|
|
}
|
|
|
|
// IsMediumMatch checks if similarity score is medium (50-69%)
|
|
func (mr *MatchResult) IsMediumMatch() bool {
|
|
return mr.SimilarityScore >= 50.0 && mr.SimilarityScore < 70.0
|
|
}
|
|
|
|
// IsLowMatch checks if similarity score is low (< 50%)
|
|
func (mr *MatchResult) IsLowMatch() bool {
|
|
return mr.SimilarityScore < 50.0
|
|
}
|
|
|
|
// GetMatchLevel returns the match level as string
|
|
func (mr *MatchResult) GetMatchLevel() string {
|
|
if mr.IsHighMatch() {
|
|
return "high"
|
|
} else if mr.IsMediumMatch() {
|
|
return "medium"
|
|
}
|
|
return "low"
|
|
}
|
|
|
|
// MatchResultResponse represents match result data for API responses
|
|
type MatchResultResponse struct {
|
|
ID uint `json:"id"`
|
|
LostItemID uint `json:"lost_item_id"`
|
|
LostItemName string `json:"lost_item_name"`
|
|
ItemID uint `json:"item_id"`
|
|
ItemName string `json:"item_name"`
|
|
ItemPhotoURL string `json:"item_photo_url"`
|
|
ItemLocation string `json:"item_location"`
|
|
ItemDateFound time.Time `json:"item_date_found"`
|
|
ItemStatus string `json:"item_status"`
|
|
SimilarityScore float64 `json:"similarity_score"`
|
|
MatchLevel string `json:"match_level"`
|
|
MatchedFields string `json:"matched_fields"`
|
|
MatchedAt time.Time `json:"matched_at"`
|
|
IsNotified bool `json:"is_notified"`
|
|
}
|
|
|
|
// ToResponse converts MatchResult to MatchResultResponse
|
|
func (mr *MatchResult) ToResponse() MatchResultResponse {
|
|
lostItemName := ""
|
|
if mr.LostItem.ID != 0 {
|
|
lostItemName = mr.LostItem.Name
|
|
}
|
|
|
|
itemName := ""
|
|
itemPhotoURL := ""
|
|
itemLocation := ""
|
|
itemDateFound := time.Time{}
|
|
itemStatus := ""
|
|
if mr.Item.ID != 0 {
|
|
itemName = mr.Item.Name
|
|
itemPhotoURL = mr.Item.PhotoURL
|
|
itemLocation = mr.Item.Location
|
|
itemDateFound = mr.Item.DateFound
|
|
itemStatus = mr.Item.Status
|
|
}
|
|
|
|
return MatchResultResponse{
|
|
ID: mr.ID,
|
|
LostItemID: mr.LostItemID,
|
|
LostItemName: lostItemName,
|
|
ItemID: mr.ItemID,
|
|
ItemName: itemName,
|
|
ItemPhotoURL: itemPhotoURL,
|
|
ItemLocation: itemLocation,
|
|
ItemDateFound: itemDateFound,
|
|
ItemStatus: itemStatus,
|
|
SimilarityScore: mr.SimilarityScore,
|
|
MatchLevel: mr.GetMatchLevel(),
|
|
MatchedFields: mr.MatchedFields,
|
|
MatchedAt: mr.MatchedAt,
|
|
IsNotified: mr.IsNotified,
|
|
}
|
|
}
|
|
|
|
// ItemMatchResponse represents simplified item data for matching display
|
|
type ItemMatchResponse struct {
|
|
ID uint `json:"id"`
|
|
Name string `json:"name"`
|
|
PhotoURL string `json:"photo_url"`
|
|
Location string `json:"location"`
|
|
DateFound time.Time `json:"date_found"`
|
|
Status string `json:"status"`
|
|
Similarity float64 `json:"similarity"`
|
|
} |