second commit
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
package autoassignment
|
||||
|
||||
// GORM models for the auto-assignment system.
|
||||
//
|
||||
// Reference: Chatwoot AutoAssignment pattern
|
||||
// - AssignmentPolicy: global policy for how conversations are assigned
|
||||
// (round_robin, longest_waiting). Has fair_distribution_limit and
|
||||
// fair_distribution_window for rate limiting per agent.
|
||||
// - InboxAssignmentPolicy: per-inbox override of the global policy.
|
||||
// Each inbox can have its own assignment policy and rate limits.
|
||||
//
|
||||
// Pattern: gochat models embed model.Base (ID, CreatedAt, UpdatedAt, DeletedAt),
|
||||
// use TableName() method, and use gorm struct tags.
|
||||
|
||||
import (
|
||||
"github.com/gochat/gochat/internal/model"
|
||||
)
|
||||
|
||||
// AssignmentPolicyType defines the type of auto-assignment policy.
|
||||
type AssignmentPolicyType string
|
||||
|
||||
const (
|
||||
// PolicyRoundRobin assigns conversations to agents in round-robin order.
|
||||
// Reference: Chatwoot InboxRoundRobinService
|
||||
PolicyRoundRobin AssignmentPolicyType = "round_robin"
|
||||
|
||||
// PolicyLongestWaiting assigns conversations to the agent with the
|
||||
// longest idle time since their last assignment.
|
||||
// Reference: Chatwoot "longest_waiting" policy (planned feature)
|
||||
PolicyLongestWaiting AssignmentPolicyType = "longest_waiting"
|
||||
|
||||
// PolicyLowestLoad assigns conversations to the agent with the
|
||||
// fewest currently open conversations.
|
||||
// Reference: Chatwoot "least_busy" concept — agent with lowest workload.
|
||||
PolicyLowestLoad AssignmentPolicyType = "lowest_load"
|
||||
)
|
||||
|
||||
// AssignmentPolicy represents the global auto-assignment policy for an account.
|
||||
// Reference: Chatwoot AssignmentPolicy model
|
||||
// - Defines how unassigned conversations are distributed among agents
|
||||
// - fair_distribution_limit: max assignments per agent per window (default 5)
|
||||
// - fair_distribution_window: time window in seconds for rate limiting (default 300 = 5 min)
|
||||
type AssignmentPolicy struct {
|
||||
model.Base
|
||||
AccountID uint `gorm:"index;not null" json:"account_id"`
|
||||
Policy AssignmentPolicyType `gorm:"size:50;default:round_robin" json:"policy"`
|
||||
FairDistributionLimit int `gorm:"default:5" json:"fair_distribution_limit"`
|
||||
FairDistributionWindow int `gorm:"default:300" json:"fair_distribution_window"` // seconds
|
||||
Active bool `gorm:"default:true" json:"active"`
|
||||
}
|
||||
|
||||
func (AssignmentPolicy) TableName() string { return "assignment_policies" }
|
||||
|
||||
// InboxAssignmentPolicy represents a per-inbox override of the global assignment policy.
|
||||
// Reference: Chatwoot InboxAssignmentPolicy model
|
||||
// - Each inbox can override the account-level policy
|
||||
// - If no inbox-specific policy exists, the account policy is used
|
||||
type InboxAssignmentPolicy struct {
|
||||
model.Base
|
||||
AccountID uint `gorm:"index;not null" json:"account_id"`
|
||||
InboxID uint `gorm:"uniqueIndex;not null" json:"inbox_id"`
|
||||
Policy AssignmentPolicyType `gorm:"size:50;default:round_robin" json:"policy"`
|
||||
FairDistributionLimit int `gorm:"default:5" json:"fair_distribution_limit"`
|
||||
FairDistributionWindow int `gorm:"default:300" json:"fair_distribution_window"` // seconds
|
||||
Active bool `gorm:"default:true" json:"active"`
|
||||
}
|
||||
|
||||
func (InboxAssignmentPolicy) TableName() string { return "inbox_assignment_policies" }
|
||||
|
||||
// EffectivePolicy returns the effective assignment policy for a given inbox.
|
||||
// If the inbox has a specific policy, it is used; otherwise the account policy is used.
|
||||
func EffectivePolicy(accountPolicy *AssignmentPolicy, inboxPolicy *InboxAssignmentPolicy) AssignmentPolicyType {
|
||||
if inboxPolicy != nil && inboxPolicy.Active {
|
||||
return inboxPolicy.Policy
|
||||
}
|
||||
if accountPolicy != nil && accountPolicy.Active {
|
||||
return accountPolicy.Policy
|
||||
}
|
||||
return PolicyRoundRobin // default
|
||||
}
|
||||
|
||||
// EffectiveLimit returns the effective fair distribution limit for a given inbox.
|
||||
func EffectiveLimit(accountPolicy *AssignmentPolicy, inboxPolicy *InboxAssignmentPolicy) int {
|
||||
if inboxPolicy != nil && inboxPolicy.Active && inboxPolicy.FairDistributionLimit > 0 {
|
||||
return inboxPolicy.FairDistributionLimit
|
||||
}
|
||||
if accountPolicy != nil && accountPolicy.FairDistributionLimit > 0 {
|
||||
return accountPolicy.FairDistributionLimit
|
||||
}
|
||||
return 5 // default
|
||||
}
|
||||
|
||||
// EffectiveWindow returns the effective fair distribution window (in seconds).
|
||||
func EffectiveWindow(accountPolicy *AssignmentPolicy, inboxPolicy *InboxAssignmentPolicy) int {
|
||||
if inboxPolicy != nil && inboxPolicy.Active && inboxPolicy.FairDistributionWindow > 0 {
|
||||
return inboxPolicy.FairDistributionWindow
|
||||
}
|
||||
if accountPolicy != nil && accountPolicy.FairDistributionWindow > 0 {
|
||||
return accountPolicy.FairDistributionWindow
|
||||
}
|
||||
return 300 // default (5 minutes)
|
||||
}
|
||||
Reference in New Issue
Block a user