package models import ( "time" "gorm.io/gorm" ) // Archive represents an archived item type Archive struct { ID uint `gorm:"primaryKey" json:"id"` ItemID uint `gorm:"not null;uniqueIndex" json:"item_id"` // Original item ID Name string `gorm:"type:varchar(100);not null" json:"name"` CategoryID uint `gorm:"not null" json:"category_id"` Category Category `gorm:"foreignKey:CategoryID" json:"category,omitempty"` PhotoURL string `gorm:"type:varchar(255)" json:"photo_url"` Location string `gorm:"type:varchar(200)" json:"location"` Description string `gorm:"type:text" json:"description"` DateFound time.Time `json:"date_found"` Status string `gorm:"type:varchar(50)" json:"status"` // case_closed, expired ReporterName string `gorm:"type:varchar(100)" json:"reporter_name"` ReporterContact string `gorm:"type:varchar(50)" json:"reporter_contact"` ArchivedReason string `gorm:"type:varchar(100)" json:"archived_reason"` // expired, case_closed ClaimedBy *uint `json:"claimed_by"` // User who claimed (if applicable) Claimer *User `gorm:"foreignKey:ClaimedBy" json:"claimer,omitempty"` ArchivedAt time.Time `json:"archived_at"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` } // TableName specifies the table name for Archive model func (Archive) TableName() string { return "archives" } // Archive reason constants const ( ArchiveReasonExpired = "expired" ArchiveReasonCaseClosed = "case_closed" ) // BeforeCreate hook func (a *Archive) BeforeCreate(tx *gorm.DB) error { if a.ArchivedAt.IsZero() { a.ArchivedAt = time.Now() } return nil } // ArchiveResponse represents archive data for API responses type ArchiveResponse struct { ID uint `json:"id"` ItemID uint `json:"item_id"` Name string `json:"name"` Category string `json:"category"` PhotoURL string `json:"photo_url"` Location string `json:"location"` DateFound time.Time `json:"date_found"` Status string `json:"status"` ArchivedReason string `json:"archived_reason"` ClaimedBy string `json:"claimed_by,omitempty"` ArchivedAt time.Time `json:"archived_at"` } // ToResponse converts Archive to ArchiveResponse func (a *Archive) ToResponse() ArchiveResponse { categoryName := "" if a.Category.ID != 0 { categoryName = a.Category.Name } claimedByName := "" if a.Claimer != nil && a.Claimer.ID != 0 { claimedByName = a.Claimer.Name } return ArchiveResponse{ ID: a.ID, ItemID: a.ItemID, Name: a.Name, Category: categoryName, PhotoURL: a.PhotoURL, Location: a.Location, DateFound: a.DateFound, Status: a.Status, ArchivedReason: a.ArchivedReason, ClaimedBy: claimedByName, ArchivedAt: a.ArchivedAt, } } // CreateFromItem creates an Archive from an Item func CreateFromItem(item *Item, reason string, claimedBy *uint) *Archive { return &Archive{ ItemID: item.ID, Name: item.Name, CategoryID: item.CategoryID, PhotoURL: item.PhotoURL, Location: item.Location, Description: item.Description, DateFound: item.DateFound, Status: item.Status, ReporterName: item.ReporterName, ReporterContact: item.ReporterContact, ArchivedReason: reason, ClaimedBy: claimedBy, ArchivedAt: time.Now(), } }