package repository import ( "context" "encoding/json" "gorm.io/gorm" "github.com/gochat/gochat/internal/model" ) // WebhookSubscriptionRepo implements GORM repository for WebhookSubscription. // Reference: Chatwoot webhook integration + P2B M8 spec type WebhookSubscriptionRepo struct { db *gorm.DB } // NewWebhookSubscriptionRepo creates a new WebhookSubscription repository. func NewWebhookSubscriptionRepo(db *gorm.DB) *WebhookSubscriptionRepo { return &WebhookSubscriptionRepo{db: db} } // FindByID retrieves a webhook subscription by primary key. func (r *WebhookSubscriptionRepo) FindByID(ctx context.Context, id uint) (*model.WebhookSubscription, error) { var s model.WebhookSubscription err := r.db.WithContext(ctx).Preload("Inbox").First(&s, id).Error if err != nil { return nil, err } return &s, nil } // FindByAccountAndID retrieves a webhook subscription scoped to an account. func (r *WebhookSubscriptionRepo) FindByAccountAndID(ctx context.Context, accountID, id uint) (*model.WebhookSubscription, error) { var s model.WebhookSubscription err := r.db.WithContext(ctx). Preload("Inbox"). Where("account_id = ?", accountID). First(&s, id).Error if err != nil { return nil, err } return &s, nil } // FindByAccountAndURL retrieves an active webhook by account and URL. func (r *WebhookSubscriptionRepo) FindByAccountAndURL(ctx context.Context, accountID uint, url string) (*model.WebhookSubscription, error) { var s model.WebhookSubscription err := r.db.WithContext(ctx). Where("account_id = ? AND url = ? AND active = ?", accountID, url, true). First(&s).Error if err != nil { return nil, err } return &s, nil } // GetByID is an alias for FindByID for compatibility with service callers. func (r *WebhookSubscriptionRepo) GetByID(ctx context.Context, id uint) (*model.WebhookSubscription, error) { return r.FindByID(ctx, id) } // ListByAccount retrieves all webhook subscriptions for an account. func (r *WebhookSubscriptionRepo) ListByAccount(ctx context.Context, accountID uint) ([]model.WebhookSubscription, error) { var subs []model.WebhookSubscription err := r.db.WithContext(ctx). Preload("Inbox"). Where("account_id = ? AND active = ?", accountID, true). Order("id ASC"). Find(&subs).Error return subs, err } // ListActiveByAccount retrieves all active webhook subscriptions for an account. func (r *WebhookSubscriptionRepo) ListActiveByAccount(ctx context.Context, accountID uint) ([]model.WebhookSubscription, error) { var subs []model.WebhookSubscription err := r.db.WithContext(ctx). Preload("Inbox"). Where("account_id = ? AND active = ?", accountID, true). Order("id ASC"). Find(&subs).Error return subs, err } // ListByAccountAndEvent retrieves webhook subscriptions that include a specific event type. func (r *WebhookSubscriptionRepo) ListByAccountAndEvent(ctx context.Context, accountID uint, eventType string) ([]model.WebhookSubscription, error) { subs, err := r.ListActiveByAccount(ctx, accountID) if err != nil { return nil, err } filtered := make([]model.WebhookSubscription, 0, len(subs)) for _, sub := range subs { var events []string if err := json.Unmarshal(sub.Events, &events); err != nil { continue } for _, event := range events { if event == eventType { filtered = append(filtered, sub) break } } } return filtered, nil } // Create inserts a new webhook subscription. func (r *WebhookSubscriptionRepo) Create(ctx context.Context, sub *model.WebhookSubscription) error { return r.db.WithContext(ctx).Create(sub).Error } // Update updates a webhook subscription. func (r *WebhookSubscriptionRepo) Update(ctx context.Context, sub *model.WebhookSubscription) error { return r.db.WithContext(ctx).Save(sub).Error } // Delete soft-deletes a webhook subscription. func (r *WebhookSubscriptionRepo) Delete(ctx context.Context, id uint) error { return r.db.WithContext(ctx).Delete(&model.WebhookSubscription{}, id).Error } // --- WebhookDelivery repository operations (embedded for simplicity) --- // CreateDelivery inserts a webhook delivery record. func (r *WebhookSubscriptionRepo) CreateDelivery(ctx context.Context, delivery *model.WebhookDelivery) error { return r.db.WithContext(ctx).Create(delivery).Error } // UpdateDelivery updates a webhook delivery record. func (r *WebhookSubscriptionRepo) UpdateDelivery(ctx context.Context, delivery *model.WebhookDelivery) error { return r.db.WithContext(ctx).Save(delivery).Error } // ListDeliveriesBySubscription retrieves recent delivery records for a subscription. func (r *WebhookSubscriptionRepo) ListDeliveriesBySubscription(ctx context.Context, subscriptionID uint, limit int) ([]model.WebhookDelivery, error) { var deliveries []model.WebhookDelivery err := r.db.WithContext(ctx). Where("subscription_id = ?", subscriptionID). Order("created_at DESC"). Limit(limit). Find(&deliveries).Error return deliveries, err }