package repository import ( "context" "gorm.io/gorm" "github.com/gochat/gochat/internal/model" ) // AssignmentPolicyRepo implements GORM repository for AssignmentPolicy. // Reference: Chatwoot app/models/assignment_policy.rb type AssignmentPolicyRepo struct { db *gorm.DB } // NewAssignmentPolicyRepo creates a new AssignmentPolicy repository. func NewAssignmentPolicyRepo(db *gorm.DB) *AssignmentPolicyRepo { return &AssignmentPolicyRepo{db: db} } // Create creates a new assignment policy. func (r *AssignmentPolicyRepo) Create(ctx context.Context, policy *model.AssignmentPolicy) error { return r.db.WithContext(ctx).Create(policy).Error } // FindByID retrieves an assignment policy by primary key. func (r *AssignmentPolicyRepo) FindByID(ctx context.Context, id uint) (*model.AssignmentPolicy, error) { var policy model.AssignmentPolicy if err := r.db.WithContext(ctx).First(&policy, id).Error; err != nil { return nil, err } return &policy, nil } // GetByID retrieves an assignment policy by primary key (alias for FindByID matching service expectations). func (r *AssignmentPolicyRepo) GetByID(ctx context.Context, id uint) (*model.AssignmentPolicy, error) { return r.FindByID(ctx, id) } // FindByAccount retrieves all assignment policies for an account. func (r *AssignmentPolicyRepo) FindByAccount(ctx context.Context, accountID uint) ([]model.AssignmentPolicy, error) { var policies []model.AssignmentPolicy if err := r.db.WithContext(ctx). Where("account_id = ?", accountID). Order("id ASC"). Find(&policies).Error; err != nil { return nil, err } return policies, nil } // FindByAccountAndID retrieves an account-scoped assignment policy. func (r *AssignmentPolicyRepo) FindByAccountAndID(ctx context.Context, accountID, id uint) (*model.AssignmentPolicy, error) { var policy model.AssignmentPolicy if err := r.db.WithContext(ctx). Where("account_id = ? AND id = ?", accountID, id). First(&policy).Error; err != nil { return nil, err } return &policy, nil } // Update updates an assignment policy. func (r *AssignmentPolicyRepo) Update(ctx context.Context, policy *model.AssignmentPolicy) error { return r.db.WithContext(ctx).Save(policy).Error } // Delete soft-deletes an assignment policy. func (r *AssignmentPolicyRepo) Delete(ctx context.Context, id uint) error { return r.db.WithContext(ctx).Delete(&model.AssignmentPolicy{}, id).Error } // CountAssignedInboxes returns how many inboxes use an assignment policy. func (r *AssignmentPolicyRepo) CountAssignedInboxes(ctx context.Context, policyID uint) (int64, error) { var count int64 err := r.db.WithContext(ctx). Model(&model.InboxAssignmentPolicy{}). Where("assignment_policy_id = ?", policyID). Count(&count).Error return count, err } // InboxAssignmentPolicyRepo implements GORM repository for InboxAssignmentPolicy. // Reference: Chatwoot app/models/inbox_assignment_policy.rb type InboxAssignmentPolicyRepo struct { db *gorm.DB } // NewInboxAssignmentPolicyRepo creates a new InboxAssignmentPolicy repository. func NewInboxAssignmentPolicyRepo(db *gorm.DB) *InboxAssignmentPolicyRepo { return &InboxAssignmentPolicyRepo{db: db} } // Create creates a new inbox assignment policy. func (r *InboxAssignmentPolicyRepo) Create(ctx context.Context, policy *model.InboxAssignmentPolicy) error { return r.db.WithContext(ctx).Create(policy).Error } // FindByID retrieves an inbox assignment policy by primary key. func (r *InboxAssignmentPolicyRepo) FindByID(ctx context.Context, id uint) (*model.InboxAssignmentPolicy, error) { var policy model.InboxAssignmentPolicy if err := r.db.WithContext(ctx).First(&policy, id).Error; err != nil { return nil, err } return &policy, nil } // FindByInbox retrieves the active assignment policy override for an inbox. func (r *InboxAssignmentPolicyRepo) FindByInbox(ctx context.Context, accountID, inboxID uint) (*model.InboxAssignmentPolicy, error) { var policy model.InboxAssignmentPolicy if err := r.db.WithContext(ctx). Joins("JOIN assignment_policies ON assignment_policies.id = inbox_assignment_policies.assignment_policy_id"). Where("assignment_policies.account_id = ? AND inbox_assignment_policies.inbox_id = ?", accountID, inboxID). First(&policy).Error; err != nil { return nil, err } return &policy, nil } // FindPolicyByInbox retrieves the assignment policy associated with an inbox. func (r *InboxAssignmentPolicyRepo) FindPolicyByInbox(ctx context.Context, accountID, inboxID uint) (*model.AssignmentPolicy, error) { var policy model.AssignmentPolicy if err := r.db.WithContext(ctx). Joins("JOIN inbox_assignment_policies ON inbox_assignment_policies.assignment_policy_id = assignment_policies.id"). Where("assignment_policies.account_id = ? AND inbox_assignment_policies.inbox_id = ?", accountID, inboxID). First(&policy).Error; err != nil { return nil, err } return &policy, nil } // FindInboxesByPolicy retrieves inboxes linked to an account-scoped policy. func (r *InboxAssignmentPolicyRepo) FindInboxesByPolicy(ctx context.Context, accountID, policyID uint) ([]model.Inbox, error) { var inboxes []model.Inbox err := r.db.WithContext(ctx). Joins("JOIN inbox_assignment_policies ON inbox_assignment_policies.inbox_id = inboxes.id"). Joins("JOIN assignment_policies ON assignment_policies.id = inbox_assignment_policies.assignment_policy_id"). Where("assignment_policies.account_id = ? AND assignment_policies.id = ?", accountID, policyID). Order("inboxes.id ASC"). Find(&inboxes).Error return inboxes, err } // ReplaceForInbox attaches one policy to an inbox, replacing an old association. func (r *InboxAssignmentPolicyRepo) ReplaceForInbox(ctx context.Context, inboxID, policyID uint) (*model.InboxAssignmentPolicy, error) { var policy model.InboxAssignmentPolicy err := r.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error { if err := tx.Where("inbox_id = ?", inboxID).Delete(&model.InboxAssignmentPolicy{}).Error; err != nil { return err } policy = model.InboxAssignmentPolicy{InboxID: inboxID, AssignmentPolicyID: policyID} return tx.Create(&policy).Error }) if err != nil { return nil, err } return &policy, nil } // DeleteByInbox removes an inbox assignment policy association. func (r *InboxAssignmentPolicyRepo) DeleteByInbox(ctx context.Context, inboxID uint) error { return r.db.WithContext(ctx). Where("inbox_id = ?", inboxID). Delete(&model.InboxAssignmentPolicy{}).Error } // Update updates an inbox assignment policy. func (r *InboxAssignmentPolicyRepo) Update(ctx context.Context, policy *model.InboxAssignmentPolicy) error { return r.db.WithContext(ctx).Save(policy).Error } // Delete soft-deletes an inbox assignment policy. func (r *InboxAssignmentPolicyRepo) Delete(ctx context.Context, id uint) error { return r.db.WithContext(ctx).Delete(&model.InboxAssignmentPolicy{}, id).Error }