notification
This commit is contained in:
@@ -0,0 +1,150 @@
|
||||
package entities
|
||||
|
||||
import (
|
||||
"database/sql/driver"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type NotificationPriority string
|
||||
type NotificationDeliveryStatus string
|
||||
type NotificationChannel string
|
||||
type NotificationProvider string
|
||||
|
||||
const (
|
||||
NotificationPriorityLow NotificationPriority = "low"
|
||||
NotificationPriorityNormal NotificationPriority = "normal"
|
||||
NotificationPriorityHigh NotificationPriority = "high"
|
||||
|
||||
NotificationDeliveryStatusPending NotificationDeliveryStatus = "pending"
|
||||
NotificationDeliveryStatusSent NotificationDeliveryStatus = "sent"
|
||||
NotificationDeliveryStatusDelivered NotificationDeliveryStatus = "delivered"
|
||||
NotificationDeliveryStatusFailed NotificationDeliveryStatus = "failed"
|
||||
|
||||
NotificationChannelPush NotificationChannel = "push"
|
||||
NotificationChannelWebsocket NotificationChannel = "websocket"
|
||||
NotificationChannelEmail NotificationChannel = "email"
|
||||
|
||||
NotificationProviderFirebase NotificationProvider = "firebase"
|
||||
)
|
||||
|
||||
// NotificationData is a JSON-serializable map for extra notification payload.
|
||||
type NotificationData map[string]interface{}
|
||||
|
||||
func (d NotificationData) Value() (driver.Value, error) {
|
||||
if d == nil {
|
||||
return nil, nil
|
||||
}
|
||||
return json.Marshal(d)
|
||||
}
|
||||
|
||||
func (d *NotificationData) Scan(value interface{}) error {
|
||||
if value == nil {
|
||||
*d = nil
|
||||
return nil
|
||||
}
|
||||
bytes, ok := value.([]byte)
|
||||
if !ok {
|
||||
return errors.New("type assertion to []byte failed")
|
||||
}
|
||||
return json.Unmarshal(bytes, d)
|
||||
}
|
||||
|
||||
// Notification is the master notification record.
|
||||
type Notification struct {
|
||||
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
|
||||
Title string `gorm:"not null;size:255" json:"title"`
|
||||
Body string `gorm:"type:text" json:"body"`
|
||||
Type string `gorm:"size:100" json:"type"`
|
||||
Category string `gorm:"size:100" json:"category"`
|
||||
Priority NotificationPriority `gorm:"size:50;default:'normal'" json:"priority"`
|
||||
ImageURL string `gorm:"size:512" json:"image_url"`
|
||||
ActionURL string `gorm:"size:512" json:"action_url"`
|
||||
NotifiableType string `gorm:"size:100" json:"notifiable_type"`
|
||||
NotifiableID *uuid.UUID `gorm:"type:uuid" json:"notifiable_id"`
|
||||
Data NotificationData `gorm:"type:jsonb" json:"data"`
|
||||
ScheduledAt *time.Time `gorm:"type:timestamptz" json:"scheduled_at"`
|
||||
SentAt *time.Time `gorm:"type:timestamptz" json:"sent_at"`
|
||||
ExpiredAt *time.Time `gorm:"type:timestamptz" json:"expired_at"`
|
||||
CreatedBy *uuid.UUID `gorm:"type:uuid" json:"created_by"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||
|
||||
Creator *User `gorm:"foreignKey:CreatedBy" json:"creator,omitempty"`
|
||||
Receivers []*NotificationReceiver `gorm:"foreignKey:NotificationID" json:"receivers,omitempty"`
|
||||
}
|
||||
|
||||
func (n *Notification) BeforeCreate(tx *gorm.DB) error {
|
||||
if n.ID == uuid.Nil {
|
||||
n.ID = uuid.New()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (Notification) TableName() string {
|
||||
return "notifications"
|
||||
}
|
||||
|
||||
// NotificationReceiver links a notification to a specific user.
|
||||
type NotificationReceiver struct {
|
||||
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
|
||||
NotificationID uuid.UUID `gorm:"type:uuid;not null;index" json:"notification_id"`
|
||||
UserID uuid.UUID `gorm:"type:uuid;not null;index" json:"user_id"`
|
||||
IsRead bool `gorm:"default:false" json:"is_read"`
|
||||
ReadAt *time.Time `gorm:"type:timestamptz" json:"read_at"`
|
||||
IsDeleted bool `gorm:"default:false" json:"is_deleted"`
|
||||
DeletedAt *time.Time `gorm:"type:timestamptz" json:"deleted_at"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||
|
||||
Notification *Notification `gorm:"foreignKey:NotificationID" json:"notification,omitempty"`
|
||||
User *User `gorm:"foreignKey:UserID" json:"user,omitempty"`
|
||||
Deliveries []*NotificationDelivery `gorm:"foreignKey:NotificationReceiverID" json:"deliveries,omitempty"`
|
||||
}
|
||||
|
||||
func (n *NotificationReceiver) BeforeCreate(tx *gorm.DB) error {
|
||||
if n.ID == uuid.Nil {
|
||||
n.ID = uuid.New()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NotificationReceiver) TableName() string {
|
||||
return "notification_receivers"
|
||||
}
|
||||
|
||||
// NotificationDelivery tracks per-device delivery attempts.
|
||||
type NotificationDelivery struct {
|
||||
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
|
||||
NotificationReceiverID uuid.UUID `gorm:"type:uuid;not null;index" json:"notification_receiver_id"`
|
||||
UserDeviceID uuid.UUID `gorm:"type:uuid;not null;index" json:"user_device_id"`
|
||||
Channel NotificationChannel `gorm:"size:50;default:'push'" json:"channel"`
|
||||
DeliveryStatus NotificationDeliveryStatus `gorm:"size:50;default:'pending'" json:"delivery_status"`
|
||||
Provider NotificationProvider `gorm:"size:50" json:"provider"`
|
||||
ProviderMessageID string `gorm:"size:255" json:"provider_message_id"`
|
||||
SentAt *time.Time `gorm:"type:timestamptz" json:"sent_at"`
|
||||
DeliveredAt *time.Time `gorm:"type:timestamptz" json:"delivered_at"`
|
||||
FailedAt *time.Time `gorm:"type:timestamptz" json:"failed_at"`
|
||||
FailureReason string `gorm:"type:text" json:"failure_reason"`
|
||||
RetryCount int `gorm:"default:0" json:"retry_count"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||
|
||||
NotificationReceiver *NotificationReceiver `gorm:"foreignKey:NotificationReceiverID" json:"notification_receiver,omitempty"`
|
||||
UserDevice *UserDevice `gorm:"foreignKey:UserDeviceID" json:"user_device,omitempty"`
|
||||
}
|
||||
|
||||
func (n *NotificationDelivery) BeforeCreate(tx *gorm.DB) error {
|
||||
if n.ID == uuid.Nil {
|
||||
n.ID = uuid.New()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (NotificationDelivery) TableName() string {
|
||||
return "notification_deliveries"
|
||||
}
|
||||
Reference in New Issue
Block a user