package page import ( "context" "github.com/gocql/gocql" "go.uber.org/zap" pageusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/page" ) // SearchPagesService handles page search operations type SearchPagesService interface { SearchPages(ctx context.Context, tenantID, siteID gocql.UUID, input *pageusecase.SearchPagesInput) (*pageusecase.SearchPagesOutput, error) } type searchPagesService struct { // Focused usecases validateSiteUC *pageusecase.ValidateSiteForSearchUseCase executeSearchUC *pageusecase.ExecuteSearchQueryUseCase incrementCountUC *pageusecase.IncrementSearchCountUseCase logger *zap.Logger } // NewSearchPagesService creates a new SearchPagesService func NewSearchPagesService( validateSiteUC *pageusecase.ValidateSiteForSearchUseCase, executeSearchUC *pageusecase.ExecuteSearchQueryUseCase, incrementCountUC *pageusecase.IncrementSearchCountUseCase, logger *zap.Logger, ) SearchPagesService { return &searchPagesService{ validateSiteUC: validateSiteUC, executeSearchUC: executeSearchUC, incrementCountUC: incrementCountUC, logger: logger.Named("search-pages-service"), } } // SearchPages orchestrates the page search workflow func (s *searchPagesService) SearchPages(ctx context.Context, tenantID, siteID gocql.UUID, input *pageusecase.SearchPagesInput) (*pageusecase.SearchPagesOutput, error) { s.logger.Info("searching pages", zap.String("tenant_id", tenantID.String()), zap.String("site_id", siteID.String()), zap.String("query", input.Query)) // Step 1: Validate site (no quota check - usage-based billing) site, err := s.validateSiteUC.Execute(ctx, tenantID, siteID) if err != nil { s.logger.Error("failed to validate site", zap.Error(err)) return nil, err } // Step 2: Execute search query result, err := s.executeSearchUC.Execute(ctx, siteID, input.Query, input.Limit, input.Offset, input.Filter) if err != nil { s.logger.Error("failed to execute search", zap.Error(err)) return nil, err } // Step 3: Increment search count (for billing tracking) if err := s.incrementCountUC.Execute(ctx, site); err != nil { s.logger.Warn("failed to increment search count (non-fatal)", zap.Error(err)) // Don't fail the search operation } s.logger.Info("pages searched successfully", zap.String("site_id", siteID.String()), zap.Int64("total_hits", result.TotalHits)) return &pageusecase.SearchPagesOutput{ Hits: result.Hits, Query: result.Query, ProcessingTimeMs: result.ProcessingTimeMs, TotalHits: result.TotalHits, Limit: result.Limit, Offset: result.Offset, }, nil }