package model import ( "time" "github.com/google/uuid" "gorm.io/datatypes" "gorm.io/gorm" ) // Conversation represents a conversation between a contact and agents. type Conversation struct { Base UUID string `gorm:"type:uuid;uniqueIndex;not null" json:"uuid"` // auto-generated global unique identifier DisplayID *uint `gorm:"index" json:"display_id,omitempty"` // account-level auto-increment number AccountID uint `gorm:"index;not null" json:"account_id"` InboxID uint `gorm:"index;not null" json:"inbox_id"` ContactID uint `gorm:"index;not null" json:"contact_id"` ContactInboxID *uint `gorm:"index" json:"contact_inbox_id,omitempty"` AssigneeID *uint `gorm:"index" json:"assignee_id"` TeamID *uint `gorm:"index" json:"team_id,omitempty"` CampaignID *uint `gorm:"index" json:"campaign_id,omitempty"` SlaPolicyID *uint `gorm:"index" json:"sla_policy_id,omitempty"` Status string `gorm:"size:50;index;default:open" json:"status"` // open, resolved, pending, snoozed Priority string `gorm:"size:50;default:none" json:"priority"` // none, low, medium, high, urgent ChannelType string `gorm:"size:50;not null" json:"channel_type"` Channel string `gorm:"size:50;not null" json:"channel"` // channel identifier for routing Labels string `gorm:"type:text" json:"labels,omitempty"` // comma-separated or JSON label list SnoozedUntil *int64 `gorm:"index" json:"snoozed_until,omitempty"` // timestamp for snoozed conversations AdditionalAttributes datatypes.JSON `gorm:"type:jsonb" json:"additional_attributes,omitempty"` CustomAttributes datatypes.JSON `gorm:"type:jsonb" json:"custom_attributes,omitempty"` AgentLastSeenAt *int64 `json:"agent_last_seen_at,omitempty"` AssigneeLastSeenAt *int64 `json:"assignee_last_seen_at,omitempty"` ContactLastSeenAt *int64 `json:"contact_last_seen_at,omitempty"` WaitingSince *int64 `json:"waiting_since,omitempty"` LastActivityAt *int64 `json:"last_activity_at,omitempty"` FirstReplyCreatedAt *int64 `json:"first_reply_created_at,omitempty"` Muted bool `gorm:"default:false" json:"muted"` ResolvedAt *time.Time `json:"resolved_at,omitempty"` // Chatwoot: timestamp when conversation was resolved ResumedAt *time.Time `json:"resumed_at,omitempty"` // Chatwoot: timestamp when conversation was reopened LastMessageAt *int64 `gorm:"index" json:"last_message_at,omitempty"` LastNonSysMsgAt *int64 `json:"last_non_system_message_at,omitempty"` Contact *Contact `gorm:"foreignKey:ContactID" json:"contact,omitempty"` Inbox *Inbox `gorm:"foreignKey:InboxID" json:"inbox,omitempty"` Assignee *User `gorm:"foreignKey:AssigneeID" json:"assignee,omitempty"` Messages []Message `gorm:"foreignKey:ConversationID" json:"messages,omitempty"` } // BeforeCreate auto-generates UUID before inserting a new Conversation record. func (c *Conversation) BeforeCreate(tx *gorm.DB) error { if c.UUID == "" { c.UUID = uuid.New().String() } return nil } func (Conversation) TableName() string { return "conversations" }