store

package
v0.0.0-...-7f6939c Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 6, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

File: backend/internal/store/interfaces.go

File: backend/internal/store/pagination.go

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrNotFound is returned when a requested record is not found in the database.
	ErrNotFound = errors.New("requested record not found")

	// ErrDuplicateEntry is returned when an insert or update operation violates a unique constraint.
	ErrDuplicateEntry = errors.New("database record already exists or violates unique constraint")

	// ErrUpdateFailed is returned when an update operation does not affect any rows,
	// potentially because the record does not exist or the data hasn't changed.
	ErrUpdateFailed = errors.New("database record update failed")
)

Functions

func BoolPtr

func BoolPtr(b bool) *bool

func EncodeCursor

func EncodeCursor(info CursorInfo) string

EncodeCursor encodes cursor information into a base64 string

Types

type ArchitectureStore

type ArchitectureStore interface {
	Transactor
	CreateServiceArchitectureMetric(ctx context.Context, exec Querier, m *models.ServiceArchitectureMetric) error
	GetServiceArchitectureMetrics(ctx context.Context, exec Querier, serviceName string) ([]*models.ServiceArchitectureMetric, error)
	CreateServiceDependency(ctx context.Context, exec Querier, dep *models.ServiceDependency) error
	ListServiceDependencies(ctx context.Context, exec Querier, sourceService string) ([]*models.ServiceDependency, error)
	CreateArchitectureRefactorLog(ctx context.Context, exec Querier, log *models.ArchitectureRefactorLog) error
	CreateCommunicationPattern(ctx context.Context, exec Querier, p *models.CommunicationPattern) error
	CreateServiceCapacityMetric(ctx context.Context, exec Querier, m *models.ServiceCapacityMetric) error
}

ArchitectureStore defines operations for service architecture monitoring and related tables.

type AuditLogStore

type AuditLogStore interface {
	// Audit logs are often single, append-only operations.
	// No Transactor needed. exec Querier allows running in existing Tx if caller provides one.
	CreateAuditLog(ctx context.Context, exec Querier, logEntry *models.AuditLog) error
	ListAuditLogs(ctx context.Context, exec Querier, filter ListAuditLogsFilter) ([]*models.AuditLog, error)
}

type CampaignActivityEvent

type CampaignActivityEvent struct {
	ID               int64           `db:"id" json:"-"`
	SequenceNumber   int64           `db:"sequence_number" json:"sequenceNumber"`
	CampaignID       uuid.UUID       `db:"campaign_id" json:"campaignId"`
	EventType        string          `db:"event_type" json:"eventType"`
	SourceState      string          `db:"source_state" json:"sourceState"`
	TargetState      string          `db:"target_state" json:"targetState"`
	Reason           sql.NullString  `db:"reason" json:"-"`
	TriggeredBy      sql.NullString  `db:"triggered_by" json:"-"`
	EventData        json.RawMessage `db:"event_data" json:"eventData,omitempty"`
	OperationContext json.RawMessage `db:"operation_context" json:"operationContext,omitempty"`
	CreatedAt        time.Time       `db:"created_at" json:"timestamp"`
}

CampaignActivityEvent represents a lifecycle event in the campaign timeline

type CampaignJobStore

type CampaignJobStore interface {
	Transactor // For potential service-managed transactions involving multiple job ops

	CreateJob(ctx context.Context, exec Querier, job *models.CampaignJob) error
	GetJobByID(ctx context.Context, jobID uuid.UUID) (*models.CampaignJob, error)
	UpdateJob(ctx context.Context, exec Querier, job *models.CampaignJob) error
	GetNextQueuedJob(ctx context.Context, campaignTypes []models.JobTypeEnum, workerID string) (*models.CampaignJob, error)
	DeleteJob(ctx context.Context, jobID uuid.UUID) error
	ListJobs(ctx context.Context, filter ListJobsFilter) ([]*models.CampaignJob, error)
}

CampaignJobStore: Most methods will use internal client/db directly. GetNextQueuedJob manages its own transaction for atomicity. Transactor is kept if a service needs to batch multiple job store operations into one Tx.

type CampaignStore

type CampaignStore interface {
	Transactor // Only Postgres store will meaningfully implement this

	// UnderlyingDB returns the concrete *sqlx.DB for cases where a caller must explicitly
	// pass a non-nil exec (e.g., to avoid ambiguous nil interfaces during instrumentation
	// or when defensive store fallbacks are insufficient). This should be used sparingly
	// to keep higher layers abstracted from the persistence layer.
	UnderlyingDB() *sqlx.DB

	CreateCampaign(ctx context.Context, exec Querier, campaign *models.LeadGenerationCampaign) error
	GetCampaignByID(ctx context.Context, exec Querier, id uuid.UUID) (*models.LeadGenerationCampaign, error)
	UpdateCampaign(ctx context.Context, exec Querier, campaign *models.LeadGenerationCampaign) error
	DeleteCampaign(ctx context.Context, exec Querier, id uuid.UUID) error
	ListCampaigns(ctx context.Context, exec Querier, filter ListCampaignsFilter) ([]*models.LeadGenerationCampaign, error)
	CountCampaigns(ctx context.Context, exec Querier, filter ListCampaignsFilter) (int64, error)
	UpdateCampaignStatus(ctx context.Context, exec Querier, id uuid.UUID, status models.PhaseStatusEnum, errorMessage sql.NullString) error
	UpdateCampaignProgress(ctx context.Context, exec Querier, id uuid.UUID, processedItems, totalItems int64, progressPercentage float64) error
	UpdateCampaignPhaseFields(ctx context.Context, exec Querier, id uuid.UUID, currentPhase *models.PhaseTypeEnum, phaseStatus *models.PhaseStatusEnum) error

	// Methods for DomainGenerationPhaseConfigState
	GetDomainGenerationPhaseConfigStateByHash(ctx context.Context, exec Querier, configHash string) (*models.DomainGenerationPhaseConfigState, error)
	CreateOrUpdateDomainGenerationPhaseConfigState(ctx context.Context, exec Querier, state *models.DomainGenerationPhaseConfigState) error
	DeleteDomainGenerationPhaseConfigState(ctx context.Context, exec Querier, configHash string) error

	// Methods for pattern reference counting and cleanup
	CountCampaignsWithPatternHash(ctx context.Context, exec Querier, patternHash string) (int, error)
	CleanupUnusedPatternConfigState(ctx context.Context, exec Querier, patternHash string) error

	// Campaign Phase Management Methods
	CreateCampaignPhases(ctx context.Context, exec Querier, campaignID uuid.UUID) error
	GetCampaignPhases(ctx context.Context, exec Querier, campaignID uuid.UUID) ([]*models.CampaignPhase, error)
	GetCampaignPhase(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum) (*models.CampaignPhase, error)
	UpdatePhaseStatus(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum, status models.PhaseStatusEnum) error
	UpdatePhaseProgress(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum, progress float64, totalItems, processedItems, successfulItems, failedItems *int64) error
	UpdatePhaseConfiguration(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum, config json.RawMessage) error
	CompletePhase(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum) error
	SkipPhase(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum, reason string) error
	StartPhase(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum) error
	PausePhase(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum) error
	ResumePhase(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum) error
	FailPhase(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum, errorMessage string, errorDetails map[string]interface{}) error

	// P2: Lifecycle event persistence with sequence tracking
	// RecordLifecycleEvent inserts a state event and returns the auto-generated sequence number.
	// eventType: phase_started, phase_paused, phase_resumed, phase_completed, phase_failed
	RecordLifecycleEvent(ctx context.Context, exec Querier, campaignID uuid.UUID, eventType string, phase models.PhaseTypeEnum, fromStatus, toStatus models.PhaseStatusEnum, metadata map[string]interface{}) (int64, error)
	// GetLastLifecycleSequence returns the most recent sequence number for a campaign's lifecycle events.
	GetLastLifecycleSequence(ctx context.Context, exec Querier, campaignID uuid.UUID) (int64, error)
	// GetCampaignActivity returns lifecycle events for a campaign as activity timeline
	GetCampaignActivity(ctx context.Context, exec Querier, campaignID uuid.UUID, limit int) ([]*CampaignActivityEvent, error)

	CreateGeneratedDomains(ctx context.Context, exec Querier, domains []*models.GeneratedDomain) error
	GetGeneratedDomainsByCampaign(ctx context.Context, exec Querier, campaignID uuid.UUID, limit int, lastOffsetIndex int64, filter *ListCampaignDomainsFilter) ([]*models.GeneratedDomain, error)
	CountGeneratedDomainsByCampaign(ctx context.Context, exec Querier, campaignID uuid.UUID) (int64, error)

	// Domain counters (Phase A optimization)
	GetCampaignDomainCounters(ctx context.Context, exec Querier, campaignID uuid.UUID) (*models.CampaignDomainCounters, error)

	CreateDNSValidationResults(ctx context.Context, exec Querier, results []*models.DNSValidationResult) error
	GetDNSValidationResultsByCampaign(ctx context.Context, exec Querier, campaignID uuid.UUID, filter ListValidationResultsFilter) ([]*models.DNSValidationResult, error)
	CountDNSValidationResults(ctx context.Context, exec Querier, campaignID uuid.UUID, onlyValid bool) (int64, error)
	DeleteDNSValidationResults(ctx context.Context, exec Querier, campaignID uuid.UUID) (int64, error)

	CreateHTTPKeywordParams(ctx context.Context, exec Querier, params *models.HTTPKeywordCampaignParams) error
	GetHTTPKeywordParams(ctx context.Context, exec Querier, campaignID uuid.UUID) (*models.HTTPKeywordCampaignParams, error)

	CreateHTTPKeywordResults(ctx context.Context, exec Querier, results []*models.HTTPKeywordResult) error
	GetHTTPKeywordResultsByCampaign(ctx context.Context, exec Querier, campaignID uuid.UUID, filter ListValidationResultsFilter) ([]*models.HTTPKeywordResult, error)
	GetDomainsForHTTPValidation(ctx context.Context, exec Querier, httpKeywordCampaignID uuid.UUID, sourceCampaignID uuid.UUID, limit int, lastDomainName string) ([]*models.DNSValidationResult, error)

	// Enhanced cursor-based pagination methods for enterprise scale
	GetGeneratedDomainsWithCursor(ctx context.Context, exec Querier, filter ListGeneratedDomainsFilter) (*PaginatedResult[*models.GeneratedDomain], error)

	// Performance monitoring methods
	RecordQueryPerformance(ctx context.Context, exec Querier, metric *models.QueryPerformanceMetric) error
	RecordConnectionPoolMetrics(ctx context.Context, exec Querier, metrics *models.ConnectionPoolMetrics) error

	// Phase 2: New state management methods
	// Campaign state operations
	CreateCampaignState(ctx context.Context, exec Querier, state *models.CampaignState) error
	GetCampaignState(ctx context.Context, exec Querier, campaignID uuid.UUID) (*models.CampaignState, error)
	UpdateCampaignState(ctx context.Context, exec Querier, state *models.CampaignState) error
	DeleteCampaignState(ctx context.Context, exec Querier, campaignID uuid.UUID) error

	// Phase execution operations
	CreatePhaseExecution(ctx context.Context, exec Querier, execution *models.PhaseExecution) error
	GetPhaseExecution(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum) (*models.PhaseExecution, error)
	GetPhaseExecutionsByCampaign(ctx context.Context, exec Querier, campaignID uuid.UUID) ([]*models.PhaseExecution, error)
	UpdatePhaseExecution(ctx context.Context, exec Querier, execution *models.PhaseExecution) error
	DeletePhaseExecution(ctx context.Context, exec Querier, id uuid.UUID) error

	// Combined operations
	GetCampaignStateWithExecutions(ctx context.Context, exec Querier, campaignID uuid.UUID) (*models.CampaignStateWithExecution, error)

	UpdateDNSResults(ctx context.Context, exec Querier, campaignID uuid.UUID, dnsResults interface{}) error
	GetDNSResults(ctx context.Context, exec Querier, campaignID uuid.UUID) (interface{}, error)

	UpdateHTTPResults(ctx context.Context, exec Querier, campaignID uuid.UUID, httpResults interface{}) error
	GetHTTPResults(ctx context.Context, exec Querier, campaignID uuid.UUID) (interface{}, error)

	UpdateAnalysisResults(ctx context.Context, exec Querier, campaignID uuid.UUID, analysisResults interface{}) error
	GetAnalysisResults(ctx context.Context, exec Querier, campaignID uuid.UUID) (interface{}, error)

	// Bulk operations for N+1 optimization
	GetCampaignsByIDs(ctx context.Context, exec Querier, campaignIDs []uuid.UUID) ([]*models.LeadGenerationCampaign, error)
	BulkDeleteCampaignsByIDs(ctx context.Context, exec Querier, campaignIDs []uuid.UUID) error
	UpdateDomainsBulkDNSStatus(ctx context.Context, exec Querier, results []models.DNSValidationResult) error
	UpdateDomainsBulkHTTPStatus(ctx context.Context, exec Querier, results []models.HTTPKeywordResult) error
	// UpdateDomainLeadStatus updates lead status and rejection reason for a domain (P0-3)
	UpdateDomainLeadStatus(ctx context.Context, exec Querier, domainID uuid.UUID, status models.DomainLeadStatusEnum, score *float64, rejectionReason models.DomainRejectionReasonEnum) error

	// Phase configuration storage (explicit per-phase user config)
	UpsertPhaseConfig(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum, config json.RawMessage) error
	GetPhaseConfig(ctx context.Context, exec Querier, campaignID uuid.UUID, phaseType models.PhaseTypeEnum) (*json.RawMessage, error)
	ListPhaseConfigs(ctx context.Context, exec Querier, campaignID uuid.UUID) (map[models.PhaseTypeEnum]json.RawMessage, error)

	// Mode update (full_sequence | step_by_step)
	UpdateCampaignMode(ctx context.Context, exec Querier, campaignID uuid.UUID, mode string) error
	// GetCampaignMode returns the execution mode (step_by_step or full_sequence) for a campaign.
	GetCampaignMode(ctx context.Context, exec Querier, campaignID uuid.UUID) (string, error)

	// Discovery lineage tracking
	// UpdateCampaignDiscoveryLineage sets the config hash and offset range for a campaign
	UpdateCampaignDiscoveryLineage(ctx context.Context, exec Querier, campaignID uuid.UUID, configHash string, offsetStart, offsetEnd int64) error
	// GetDiscoveryLineage returns prior campaigns sharing the same config_hash with their stats
	GetDiscoveryLineage(ctx context.Context, exec Querier, configHash string, excludeCampaignID *uuid.UUID, userID *string, limit int) ([]*DiscoveryLineageCampaign, error)

	// P0-4: Rejection summary for audit equation compliance
	GetRejectionSummary(ctx context.Context, exec Querier, campaignID uuid.UUID) (*RejectionSummary, error)

	// Dashboard aggregated statistics
	GetDashboardStats(ctx context.Context, exec Querier, monthStart time.Time) (*models.DashboardStats, error)

	// Entity campaign counts for UI display
	GetKeywordSetCampaignCounts(ctx context.Context, exec Querier) (map[uuid.UUID]int, error)
	GetPersonaCampaignCounts(ctx context.Context, exec Querier) (map[uuid.UUID]int, error)
	GetScoringProfileCampaignCounts(ctx context.Context, exec Querier) (map[uuid.UUID]int, error)
}

CampaignStore defines the interface for campaign data operations Methods that can be part of a larger transaction accept an exec Querier. If exec is nil, the implementation should use its internal *sqlx.DB.

type CursorDirection

type CursorDirection string

CursorDirection represents the direction for cursor-based pagination

const (
	CursorDirectionForward  CursorDirection = "forward"
	CursorDirectionBackward CursorDirection = "backward"
)

type CursorInfo

type CursorInfo struct {
	ID        uuid.UUID `json:"id"`
	Timestamp time.Time `json:"timestamp"`
	Offset    int64     `json:"offset,omitempty"` // For offset-based cursors
	Name      string    `json:"name,omitempty"`   // For name-based cursors
}

CursorInfo represents cursor information for pagination

func DecodeCursor

func DecodeCursor(cursor string) (*CursorInfo, error)

DecodeCursor decodes a base64 cursor string back to CursorInfo

type CursorPaginationFilter

type CursorPaginationFilter struct {
	First     int             `json:"first,omitempty"`     // Number of items to fetch forward
	Last      int             `json:"last,omitempty"`      // Number of items to fetch backward
	After     string          `json:"after,omitempty"`     // Cursor to paginate after
	Before    string          `json:"before,omitempty"`    // Cursor to paginate before
	Direction CursorDirection `json:"direction,omitempty"` // Pagination direction
	SortBy    string          `json:"sortBy,omitempty"`    // Sort field (created_at, offset_index, domain_name)
	SortOrder string          `json:"sortOrder,omitempty"` // Sort order (ASC, DESC)
}

CursorPaginationFilter represents cursor-based pagination parameters

func (*CursorPaginationFilter) GetDirection

func (f *CursorPaginationFilter) GetDirection() CursorDirection

GetDirection returns the effective direction for pagination

func (*CursorPaginationFilter) GetLimit

func (f *CursorPaginationFilter) GetLimit() int

GetLimit returns the effective limit for the pagination

func (*CursorPaginationFilter) GetSortBy

func (f *CursorPaginationFilter) GetSortBy() string

GetSortBy returns the effective sort field

func (*CursorPaginationFilter) GetSortOrder

func (f *CursorPaginationFilter) GetSortOrder() string

GetSortOrder returns the effective sort order

type DiscoveryLineageCampaign

type DiscoveryLineageCampaign struct {
	ID             uuid.UUID                       `db:"id" json:"id"`
	Name           string                          `db:"name" json:"name"`
	CreatedAt      time.Time                       `db:"created_at" json:"createdAt"`
	OffsetStart    *int64                          `db:"discovery_offset_start" json:"offsetStart,omitempty"`
	OffsetEnd      *int64                          `db:"discovery_offset_end" json:"offsetEnd,omitempty"`
	DomainsCount   int64                           `db:"domains_count" json:"domainsCount"`
	DNSValidCount  int64                           `db:"dns_valid_count" json:"dnsValidCount"`
	KeywordMatches int64                           `db:"keyword_matches" json:"keywordMatches"`
	LeadCount      int64                           `db:"lead_count" json:"leadCount"`
	Completeness   models.CampaignCompletenessEnum `db:"completeness" json:"completeness"`
}

DiscoveryLineageCampaign represents a campaign in the discovery lineage with aggregated stats

type KeywordStore

type KeywordStore interface {
	Transactor

	CreateKeywordSet(ctx context.Context, exec Querier, keywordSet *models.KeywordSet) error
	GetKeywordSetByID(ctx context.Context, exec Querier, id uuid.UUID) (*models.KeywordSet, error)
	GetKeywordSetByName(ctx context.Context, exec Querier, name string) (*models.KeywordSet, error)
	UpdateKeywordSet(ctx context.Context, exec Querier, keywordSet *models.KeywordSet) error
	DeleteKeywordSet(ctx context.Context, exec Querier, id uuid.UUID) error
	ListKeywordSets(ctx context.Context, exec Querier, filter ListKeywordSetsFilter) ([]*models.KeywordSet, error)

	CreateKeywordRules(ctx context.Context, exec Querier, rules []*models.KeywordRule) error
	GetKeywordRulesBySetID(ctx context.Context, exec Querier, keywordSetID uuid.UUID) ([]models.KeywordRule, error)
	UpdateKeywordRule(ctx context.Context, exec Querier, rule *models.KeywordRule) error
	DeleteKeywordRule(ctx context.Context, exec Querier, id uuid.UUID) error
	DeleteKeywordRulesBySetID(ctx context.Context, exec Querier, keywordSetID uuid.UUID) error

	// Batch query methods for N+1 optimization
	GetKeywordSetsByIDs(ctx context.Context, exec Querier, ids []uuid.UUID) ([]*models.KeywordSet, error)
	GetKeywordSetsWithKeywordsByIDs(ctx context.Context, exec Querier, ids []uuid.UUID) ([]*models.KeywordSet, error)
	GetKeywordsByKeywordSetIDs(ctx context.Context, exec Querier, keywordSetIDs []uuid.UUID) ([]*models.KeywordRule, error)
	GetKeywordsByIDs(ctx context.Context, exec Querier, ids []uuid.UUID) ([]*models.KeywordRule, error)
}

type ListAuditLogsFilter

type ListAuditLogsFilter struct {
	UserID     string
	EntityType string
	EntityID   uuid.NullUUID
	Action     string
	StartDate  time.Time
	EndDate    time.Time
	Limit      int
	Offset     int
}

type ListCampaignDomainsFilter

type ListCampaignDomainsFilter struct {
	DNSStatus        *models.DomainDNSStatusEnum        // Filter by DNS status
	HTTPStatus       *models.DomainHTTPStatusEnum       // Filter by HTTP status
	DNSReason        *string                            // Filter by DNS reason text
	HTTPReason       *string                            // Filter by HTTP reason text
	LeadStatus       *models.DomainLeadStatusEnum       // Filter by lead status
	RejectionReason  *models.DomainRejectionReasonEnum  // Filter by single rejection reason (P0-1)
	RejectionReasons []models.DomainRejectionReasonEnum // Filter by multiple rejection reasons (P0-8)
}

ListCampaignDomainsFilter holds optional filters for generated domains listing. All enum fields use strong types - no raw strings for business states.

type ListCampaignsFilter

type ListCampaignsFilter struct {
	CurrentPhase *models.PhaseTypeEnum   // Phases-based filtering
	PhaseStatus  *models.PhaseStatusEnum // Status of current phase
	UserID       string
	Limit        int
	Offset       int
	SortBy       string
	SortOrder    string
}

type ListGeneratedDomainsFilter

type ListGeneratedDomainsFilter struct {
	CursorPaginationFilter
	CampaignID       uuid.UUID `json:"campaignId"`
	ValidationStatus string    `json:"validationStatus,omitempty"`

	// Phase 2 filtering extensions
	// MinScore filters domains with domain_score >= MinScore (inclusive)
	MinScore *float64 `json:"minScore,omitempty"`
	// Keyword filters domains whose feature_vector indicates keyword presence. Implementation detail: relies on kw_unique > 0 extracted during HTTP enrichment/scoring.
	Keyword *string `json:"keyword,omitempty"`
	// HasContact when true returns only domains whose feature_vector contains contact signal (kw_contact > 0 or similar). If false (nil) ignored.
	HasContact *bool `json:"hasContact,omitempty"`
	// NotParked excludes domains classified as parked (is_parked IS TRUE) when set true.
	NotParked *bool `json:"notParked,omitempty"`
	// ScoreNotNull enforces domain_score IS NOT NULL when true (used implicitly when MinScore provided)
	ScoreNotNull *bool `json:"scoreNotNull,omitempty"`
}

Enhanced filters with cursor pagination support

func (*ListGeneratedDomainsFilter) WantsHasContact

func (f *ListGeneratedDomainsFilter) WantsHasContact() bool

WantsHasContact returns true if filter requires contact presence.

func (*ListGeneratedDomainsFilter) WantsNotParked

func (f *ListGeneratedDomainsFilter) WantsNotParked() bool

WantsNotParked returns true if caller explicitly requests filtering out parked domains.

func (*ListGeneratedDomainsFilter) WantsScoreNotNull

func (f *ListGeneratedDomainsFilter) WantsScoreNotNull() bool

WantsScoreNotNull returns true if score must be non-null (automatically satisfied if MinScore != nil)

type ListJobsFilter

type ListJobsFilter struct {
	CampaignID   uuid.NullUUID
	CampaignType models.JobTypeEnum
	Status       models.CampaignJobStatusEnum
	Limit        int
	Offset       int
	SortBy       string
	SortOrder    string
}

type ListKeywordSetsFilter

type ListKeywordSetsFilter struct {
	IsEnabled *bool
	Limit     int
	Offset    int
}

type ListPersonasFilter

type ListPersonasFilter struct {
	Type      models.PersonaTypeEnum
	IsEnabled *bool
	Limit     int
	Offset    int
}

type ListProxiesFilter

type ListProxiesFilter struct {
	Protocol  models.ProxyProtocolEnum
	IsEnabled *bool
	IsHealthy *bool
	Limit     int
	Offset    int
}

type ListValidationResultsFilter

type ListValidationResultsFilter struct {
	ValidationStatus string
	HasKeywords      *bool
	Limit            int
	Offset           int
}

type PageInfo

type PageInfo struct {
	HasNextPage     bool   `json:"hasNextPage"`
	HasPreviousPage bool   `json:"hasPreviousPage"`
	StartCursor     string `json:"startCursor,omitempty"`
	EndCursor       string `json:"endCursor,omitempty"`
	TotalCount      int64  `json:"totalCount,omitempty"`
}

PageInfo represents pagination metadata for cursor-based pagination

type PaginatedResult

type PaginatedResult[T any] struct {
	Data     []T      `json:"data"`
	PageInfo PageInfo `json:"pageInfo"`
}

PaginatedResult represents a paginated result with cursor information

type PersonaStore

type PersonaStore interface {
	Transactor
	CreatePersona(ctx context.Context, exec Querier, persona *models.Persona) error
	GetPersonaByID(ctx context.Context, exec Querier, id uuid.UUID) (*models.Persona, error)
	GetPersonaByName(ctx context.Context, exec Querier, name string) (*models.Persona, error)
	UpdatePersona(ctx context.Context, exec Querier, persona *models.Persona) error
	DeletePersona(ctx context.Context, exec Querier, id uuid.UUID) error
	ListPersonas(ctx context.Context, exec Querier, filter ListPersonasFilter) ([]*models.Persona, error)

	// Batch query methods for N+1 optimization
	GetPersonasByIDs(ctx context.Context, exec Querier, ids []uuid.UUID) ([]*models.Persona, error)
	GetPersonasWithKeywordSetsByIDs(ctx context.Context, exec Querier, ids []uuid.UUID) ([]*models.Persona, error)
}

type ProxyPoolStore

type ProxyPoolStore interface {
	Transactor
	CreateProxyPool(ctx context.Context, exec Querier, pool *models.ProxyPool) error
	GetProxyPoolByID(ctx context.Context, exec Querier, id uuid.UUID) (*models.ProxyPool, error)
	UpdateProxyPool(ctx context.Context, exec Querier, pool *models.ProxyPool) error
	DeleteProxyPool(ctx context.Context, exec Querier, id uuid.UUID) error
	ListProxyPools(ctx context.Context, exec Querier) ([]*models.ProxyPool, error)

	AddProxyToPool(ctx context.Context, exec Querier, m *models.ProxyPoolMembership) error
	RemoveProxyFromPool(ctx context.Context, exec Querier, poolID, proxyID uuid.UUID) error
	ListProxiesForPool(ctx context.Context, exec Querier, poolID uuid.UUID) ([]*models.Proxy, error)
}

ProxyPoolStore defines operations for managing proxy pools and their memberships.

type ProxyStore

type ProxyStore interface {
	Transactor
	CreateProxy(ctx context.Context, exec Querier, proxy *models.Proxy) error
	GetProxyByID(ctx context.Context, exec Querier, id uuid.UUID) (*models.Proxy, error)
	UpdateProxy(ctx context.Context, exec Querier, proxy *models.Proxy) error
	DeleteProxy(ctx context.Context, exec Querier, id uuid.UUID) error
	ListProxies(ctx context.Context, exec Querier, filter ListProxiesFilter) ([]*models.Proxy, error)
	UpdateProxyHealth(ctx context.Context, exec Querier, id uuid.UUID, isHealthy bool, latencyMs sql.NullInt32, lastCheckedAt time.Time) error

	// Batch query methods for N+1 optimization
	GetProxiesByIDs(ctx context.Context, exec Querier, ids []uuid.UUID) ([]*models.Proxy, error)
	GetProxiesByPersonaIDs(ctx context.Context, exec Querier, personaIDs []uuid.UUID) ([]*models.Proxy, error)
}

type Querier

type Querier interface {
	GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error
	SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error
	NamedExecContext(ctx context.Context, query string, arg interface{}) (sql.Result, error)
	ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)
	PrepareNamedContext(ctx context.Context, query string) (*sqlx.NamedStmt, error)
}

Querier defines methods that can be executed by both sqlx.DB and sqlx.Tx

type RejectionSummary

type RejectionSummary struct {
	CampaignID uuid.UUID `json:"campaignId"`
	Counts     struct {
		Qualified   int64 `db:"qualified" json:"qualified"`
		LowScore    int64 `db:"low_score" json:"lowScore"`
		NoKeywords  int64 `db:"no_keywords" json:"noKeywords"`
		Parked      int64 `db:"parked" json:"parked"`
		DNSError    int64 `db:"dns_error" json:"dnsError"`
		DNSTimeout  int64 `db:"dns_timeout" json:"dnsTimeout"`
		HTTPError   int64 `db:"http_error" json:"httpError"`
		HTTPTimeout int64 `db:"http_timeout" json:"httpTimeout"`
		Pending     int64 `db:"pending" json:"pending"`
	} `json:"counts"`
	Totals struct {
		Analyzed  int64 `json:"analyzed"`
		Qualified int64 `json:"qualified"`
		Rejected  int64 `json:"rejected"`
		Errors    int64 `json:"errors"`
		Pending   int64 `json:"pending"`
	} `json:"totals"`
	Balanced  bool    `json:"balanced"`
	AuditNote *string `json:"auditNote,omitempty"`
}

P0-4: RejectionSummary holds counts by rejection_reason for audit equation validation

type Transactor

type Transactor interface {
	BeginTxx(ctx context.Context, opts *sql.TxOptions) (*sqlx.Tx, error)
}

Transactor defines an interface for starting and managing transactions for SQL stores.

Directories

Path Synopsis
File: backend/internal/store/cached/keyword_store.go
File: backend/internal/store/cached/keyword_store.go
File: backend/internal/store/postgres/campaign_store.go
File: backend/internal/store/postgres/campaign_store.go

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL