mirror of
https://github.com/warmbly/warmbly.git
synced 2026-08-19 16:01:16 +00:00
03dc3bce95
- fix 500 on POST /campaigns: insert now sets NOT NULL created_at/updated_at - atomic create writes campaign + sequences + ab variants + tag/folder links + advanced overrides in one tx - create accepts full optional config (schedule, sender pool, tracking, sequences, variants) - handler forwards orgID so future start/stop and org-scoped routes resolve - fix Get/GetByID joining campaign_email_tags/campaign_folders on wrong column - publish CAMPAIGN_CREATED realtime event after successful create - replace name+description modal with 4-step wizard (basics, schedule, sender pool, first email + follow-ups)
57 lines
2.0 KiB
Go
57 lines
2.0 KiB
Go
package campaign
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/google/uuid"
|
|
"github.com/warmbly/warmbly/internal/app/feature"
|
|
"github.com/warmbly/warmbly/internal/errx"
|
|
"github.com/warmbly/warmbly/internal/infrastructure/pubsub"
|
|
"github.com/warmbly/warmbly/internal/models"
|
|
"github.com/warmbly/warmbly/internal/repository"
|
|
)
|
|
|
|
const campaignCooldownSeconds = 60
|
|
|
|
type CampaignService interface {
|
|
Create(ctx context.Context, userID string, orgID *uuid.UUID, data *models.CreateCampaign) (*models.Campaign, *errx.Error)
|
|
Get(ctx context.Context, userID, id string) (*models.Campaign, *errx.Error)
|
|
Search(ctx context.Context, userID, query, cursor, folder, limit string) (*models.CampaignsResult, *errx.Error)
|
|
Update(ctx context.Context, userID, id string, data *models.UpdateCampaign) (*models.Campaign, *errx.Error)
|
|
Delete(ctx context.Context, userID, id string) *errx.Error
|
|
|
|
// Start/Stop
|
|
StartCampaign(ctx context.Context, orgID uuid.UUID, campaignID string) *errx.Error
|
|
StopCampaign(ctx context.Context, orgID uuid.UUID, campaignID string) *errx.Error
|
|
|
|
// Logs
|
|
GetLogs(ctx context.Context, userID, campaignID string, limit int, cursor *string) (*models.CampaignLogsResult, *errx.Error)
|
|
}
|
|
|
|
type campaignService struct {
|
|
campaignRepository repository.CampaignRepository
|
|
taskRepo repository.TaskRepository
|
|
emailRepo repository.EmailRepository
|
|
campaignLogRepo repository.CampaignLogRepository
|
|
featureGate feature.FeatureGateService
|
|
streamingPublisher *pubsub.StreamingPublisher
|
|
}
|
|
|
|
func NewService(
|
|
campaignRepository repository.CampaignRepository,
|
|
taskRepo repository.TaskRepository,
|
|
emailRepo repository.EmailRepository,
|
|
campaignLogRepo repository.CampaignLogRepository,
|
|
featureGate feature.FeatureGateService,
|
|
streamingPublisher *pubsub.StreamingPublisher,
|
|
) CampaignService {
|
|
return &campaignService{
|
|
campaignRepository: campaignRepository,
|
|
taskRepo: taskRepo,
|
|
emailRepo: emailRepo,
|
|
campaignLogRepo: campaignLogRepo,
|
|
featureGate: featureGate,
|
|
streamingPublisher: streamingPublisher,
|
|
}
|
|
}
|