monorepo/cloud/maplepress-backend/internal/service/page/status.go

133 lines
4.3 KiB
Go

package page
import (
"context"
"github.com/gocql/gocql"
"go.uber.org/zap"
pageusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/page"
)
// SyncStatusService handles sync status operations
type SyncStatusService interface {
GetSyncStatus(ctx context.Context, tenantID, siteID gocql.UUID) (*pageusecase.SyncStatusOutput, error)
GetPageDetails(ctx context.Context, tenantID, siteID gocql.UUID, input *pageusecase.GetPageDetailsInput) (*pageusecase.PageDetailsOutput, error)
}
type syncStatusService struct {
// Focused usecases
validateSiteUC *pageusecase.ValidateSiteForStatusUseCase
getStatsUC *pageusecase.GetPageStatisticsUseCase
getIndexStatusUC *pageusecase.GetSearchIndexStatusUseCase
getPageByIDUC *pageusecase.GetPageByIDUseCase
logger *zap.Logger
}
// NewSyncStatusService creates a new SyncStatusService
func NewSyncStatusService(
validateSiteUC *pageusecase.ValidateSiteForStatusUseCase,
getStatsUC *pageusecase.GetPageStatisticsUseCase,
getIndexStatusUC *pageusecase.GetSearchIndexStatusUseCase,
getPageByIDUC *pageusecase.GetPageByIDUseCase,
logger *zap.Logger,
) SyncStatusService {
return &syncStatusService{
validateSiteUC: validateSiteUC,
getStatsUC: getStatsUC,
getIndexStatusUC: getIndexStatusUC,
getPageByIDUC: getPageByIDUC,
logger: logger.Named("sync-status-service"),
}
}
// GetSyncStatus orchestrates retrieving sync status for a site
func (s *syncStatusService) GetSyncStatus(ctx context.Context, tenantID, siteID gocql.UUID) (*pageusecase.SyncStatusOutput, error) {
s.logger.Info("getting sync status",
zap.String("tenant_id", tenantID.String()),
zap.String("site_id", siteID.String()))
// Step 1: Validate site
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: Get page statistics
stats, err := s.getStatsUC.Execute(ctx, siteID)
if err != nil {
s.logger.Error("failed to get page statistics", zap.Error(err))
return nil, err
}
// Step 3: Get search index status
indexStatus, err := s.getIndexStatusUC.Execute(ctx, siteID)
if err != nil {
s.logger.Error("failed to get search index status", zap.Error(err))
return nil, err
}
s.logger.Info("sync status retrieved successfully",
zap.String("site_id", siteID.String()),
zap.Int64("total_pages", stats.TotalPages))
// Step 4: Build output
return &pageusecase.SyncStatusOutput{
SiteID: siteID.String(),
TotalPages: stats.TotalPages,
PublishedPages: stats.PublishedPages,
DraftPages: stats.DraftPages,
LastSyncedAt: site.LastIndexedAt,
PagesIndexedMonth: site.MonthlyPagesIndexed,
SearchRequestsMonth: site.SearchRequestsCount,
LastResetAt: site.LastResetAt,
SearchIndexStatus: indexStatus.Status,
SearchIndexDocCount: indexStatus.DocumentCount,
}, nil
}
// GetPageDetails orchestrates retrieving details for a specific page
func (s *syncStatusService) GetPageDetails(ctx context.Context, tenantID, siteID gocql.UUID, input *pageusecase.GetPageDetailsInput) (*pageusecase.PageDetailsOutput, error) {
s.logger.Info("getting page details",
zap.String("tenant_id", tenantID.String()),
zap.String("site_id", siteID.String()),
zap.String("page_id", input.PageID))
// Step 1: Validate 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: Get page by ID
page, err := s.getPageByIDUC.Execute(ctx, siteID, input.PageID)
if err != nil {
s.logger.Error("failed to get page", zap.Error(err))
return nil, err
}
s.logger.Info("page details retrieved successfully",
zap.String("site_id", siteID.String()),
zap.String("page_id", input.PageID))
// Step 3: Build output
isIndexed := !page.IndexedAt.IsZero()
return &pageusecase.PageDetailsOutput{
PageID: page.PageID,
Title: page.Title,
Excerpt: page.Excerpt,
URL: page.URL,
Status: page.Status,
PostType: page.PostType,
Author: page.Author,
PublishedAt: page.PublishedAt,
ModifiedAt: page.ModifiedAt,
IndexedAt: page.IndexedAt,
MeilisearchDocID: page.MeilisearchDocID,
IsIndexed: isIndexed,
}, nil
}