2025-11-23 22:49:46 +07:00

128 lines
3.9 KiB
Go

// internal/models/notification.go
package models
import (
"time"
"gorm.io/gorm"
)
// Notification represents a notification for a user
type Notification struct {
ID uint `gorm:"primaryKey" json:"id"`
UserID uint `gorm:"not null" json:"user_id"`
User User `gorm:"foreignKey:UserID" json:"user,omitempty"`
Type string `gorm:"type:varchar(50);not null" json:"type"` // match_found, claim_approved, claim_rejected, item_expired, etc.
Title string `gorm:"type:varchar(200);not null" json:"title"`
Message string `gorm:"type:text;not null" json:"message"`
EntityType string `gorm:"type:varchar(50)" json:"entity_type"` // item, claim, match, etc.
EntityID *uint `json:"entity_id"`
IsRead bool `gorm:"default:false" json:"is_read"`
ReadAt *time.Time `json:"read_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 Notification model
func (Notification) TableName() string {
return "notifications"
}
// Notification type constants
const (
NotificationMatchFound = "match_found"
NotificationClaimApproved = "claim_approved"
NotificationClaimRejected = "claim_rejected"
NotificationItemExpired = "item_expired"
NotificationNewClaim = "new_claim"
NotificationItemReturned = "item_returned"
)
// MarkAsRead marks the notification as read
func (n *Notification) MarkAsRead() {
n.IsRead = true
now := time.Now()
n.ReadAt = &now
}
// NotificationResponse represents notification data for API responses
type NotificationResponse struct {
ID uint `json:"id"`
Type string `json:"type"`
Title string `json:"title"`
Message string `json:"message"`
EntityType string `json:"entity_type"`
EntityID *uint `json:"entity_id"`
IsRead bool `json:"is_read"`
ReadAt *time.Time `json:"read_at"`
CreatedAt time.Time `json:"created_at"`
}
// ToResponse converts Notification to NotificationResponse
func (n *Notification) ToResponse() NotificationResponse {
return NotificationResponse{
ID: n.ID,
Type: n.Type,
Title: n.Title,
Message: n.Message,
EntityType: n.EntityType,
EntityID: n.EntityID,
IsRead: n.IsRead,
ReadAt: n.ReadAt,
CreatedAt: n.CreatedAt,
}
}
// CreateNotification creates a new notification
func CreateNotification(db *gorm.DB, userID uint, notifType, title, message, entityType string, entityID *uint) error {
notification := &Notification{
UserID: userID,
Type: notifType,
Title: title,
Message: message,
EntityType: entityType,
EntityID: entityID,
}
return db.Create(notification).Error
}
// CreateMatchNotification creates a notification for match found
func CreateMatchNotification(db *gorm.DB, userID uint, itemName string, matchID uint) error {
return CreateNotification(
db,
userID,
NotificationMatchFound,
"Barang yang Mirip Ditemukan!",
"Kami menemukan barang yang mirip dengan laporan kehilangan Anda: "+itemName,
"match",
&matchID,
)
}
// CreateClaimApprovedNotification creates a notification for approved claim
func CreateClaimApprovedNotification(db *gorm.DB, userID uint, itemName string, claimID uint) error {
return CreateNotification(
db,
userID,
NotificationClaimApproved,
"Klaim Disetujui!",
"Klaim Anda untuk barang '"+itemName+"' telah disetujui. Silakan ambil barang di tempat yang ditentukan.",
"claim",
&claimID,
)
}
// CreateClaimRejectedNotification creates a notification for rejected claim
func CreateClaimRejectedNotification(db *gorm.DB, userID uint, itemName, reason string, claimID uint) error {
return CreateNotification(
db,
userID,
NotificationClaimRejected,
"Klaim Ditolak",
"Klaim Anda untuk barang '"+itemName+"' ditolak. Alasan: "+reason,
"claim",
&claimID,
)
}