Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
134
cloud/maplepress-backend/internal/usecase/page/search.go
Normal file
134
cloud/maplepress-backend/internal/usecase/page/search.go
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
package page
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gocql/gocql"
|
||||
"go.uber.org/zap"
|
||||
|
||||
domainsite "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/site"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/search"
|
||||
)
|
||||
|
||||
// SearchPagesUseCase handles page search functionality
|
||||
type SearchPagesUseCase struct {
|
||||
siteRepo domainsite.Repository
|
||||
searchClient *search.Client
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// ProvideSearchPagesUseCase creates a new SearchPagesUseCase
|
||||
func ProvideSearchPagesUseCase(
|
||||
siteRepo domainsite.Repository,
|
||||
searchClient *search.Client,
|
||||
logger *zap.Logger,
|
||||
) *SearchPagesUseCase {
|
||||
return &SearchPagesUseCase{
|
||||
siteRepo: siteRepo,
|
||||
searchClient: searchClient,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// SearchPagesInput is the input for searching pages
|
||||
type SearchPagesInput struct {
|
||||
Query string `json:"query"`
|
||||
Limit int64 `json:"limit"`
|
||||
Offset int64 `json:"offset"`
|
||||
Filter string `json:"filter,omitempty"` // e.g., "status = publish AND post_type = post"
|
||||
}
|
||||
|
||||
// SearchPagesOutput is the output after searching pages
|
||||
type SearchPagesOutput struct {
|
||||
Hits interface{} `json:"hits"` // meilisearch.Hits
|
||||
Query string `json:"query"`
|
||||
ProcessingTimeMs int64 `json:"processing_time_ms"`
|
||||
TotalHits int64 `json:"total_hits"`
|
||||
Limit int64 `json:"limit"`
|
||||
Offset int64 `json:"offset"`
|
||||
}
|
||||
|
||||
// Execute performs a search on the site's indexed pages
|
||||
func (uc *SearchPagesUseCase) Execute(ctx context.Context, tenantID, siteID gocql.UUID, input *SearchPagesInput) (*SearchPagesOutput, error) {
|
||||
uc.logger.Info("executing search pages use case",
|
||||
zap.String("tenant_id", tenantID.String()),
|
||||
zap.String("site_id", siteID.String()),
|
||||
zap.String("query", input.Query))
|
||||
|
||||
// Get site to validate and check quotas
|
||||
site, err := uc.siteRepo.GetByID(ctx, tenantID, siteID)
|
||||
if err != nil {
|
||||
uc.logger.Error("failed to get site", zap.Error(err))
|
||||
return nil, domainsite.ErrSiteNotFound
|
||||
}
|
||||
|
||||
// Verify site is verified (skip for test mode)
|
||||
if site.RequiresVerification() && !site.IsVerified {
|
||||
uc.logger.Warn("site not verified", zap.String("site_id", siteID.String()))
|
||||
return nil, domainsite.ErrSiteNotVerified
|
||||
}
|
||||
|
||||
// No quota checking - usage-based billing (anti-abuse via rate limiting only)
|
||||
|
||||
// Set default limits if not provided
|
||||
limit := input.Limit
|
||||
if limit <= 0 || limit > 100 {
|
||||
limit = 20 // Default to 20 results
|
||||
}
|
||||
|
||||
offset := input.Offset
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
|
||||
// Build search request
|
||||
searchReq := search.SearchRequest{
|
||||
Query: input.Query,
|
||||
Limit: limit,
|
||||
Offset: offset,
|
||||
Filter: input.Filter,
|
||||
}
|
||||
|
||||
// If no filter provided, default to only published pages
|
||||
if searchReq.Filter == "" {
|
||||
searchReq.Filter = "status = publish"
|
||||
}
|
||||
|
||||
// Perform search
|
||||
result, err := uc.searchClient.Search(siteID.String(), searchReq)
|
||||
if err != nil {
|
||||
uc.logger.Error("failed to search pages", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to search pages: %w", err)
|
||||
}
|
||||
|
||||
// Increment search request count (for usage tracking/billing)
|
||||
site.IncrementSearchCount()
|
||||
uc.logger.Info("incremented search count",
|
||||
zap.String("site_id", siteID.String()),
|
||||
zap.Int64("new_count", site.SearchRequestsCount))
|
||||
|
||||
if err := uc.siteRepo.UpdateUsage(ctx, site); err != nil {
|
||||
uc.logger.Error("failed to update search usage", zap.Error(err))
|
||||
// Don't fail the search, just log the error
|
||||
} else {
|
||||
uc.logger.Info("search usage updated successfully",
|
||||
zap.String("site_id", siteID.String()),
|
||||
zap.Int64("search_count", site.SearchRequestsCount))
|
||||
}
|
||||
|
||||
uc.logger.Info("search completed successfully",
|
||||
zap.String("site_id", siteID.String()),
|
||||
zap.String("query", input.Query),
|
||||
zap.Int64("total_hits", result.TotalHits),
|
||||
zap.Int64("processing_time_ms", result.ProcessingTimeMs))
|
||||
|
||||
return &SearchPagesOutput{
|
||||
Hits: result.Hits,
|
||||
Query: result.Query,
|
||||
ProcessingTimeMs: result.ProcessingTimeMs,
|
||||
TotalHits: result.TotalHits,
|
||||
Limit: result.Limit,
|
||||
Offset: result.Offset,
|
||||
}, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue