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 }