148 lines
4.9 KiB
Go
148 lines
4.9 KiB
Go
package page
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"github.com/gocql/gocql"
|
|
"go.uber.org/zap"
|
|
|
|
pageusecase "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/usecase/page"
|
|
)
|
|
|
|
// DeletePagesService handles page deletion operations
|
|
type DeletePagesService interface {
|
|
DeletePages(ctx context.Context, tenantID, siteID gocql.UUID, input *pageusecase.DeletePagesInput) (*pageusecase.DeletePagesOutput, error)
|
|
DeleteAllPages(ctx context.Context, tenantID, siteID gocql.UUID) (*pageusecase.DeletePagesOutput, error)
|
|
}
|
|
|
|
type deletePagesService struct {
|
|
// Focused usecases
|
|
validateSiteUC *pageusecase.ValidateSiteForDeletionUseCase
|
|
deletePagesRepoUC *pageusecase.DeletePagesFromRepoUseCase
|
|
deletePagesSearchUC *pageusecase.DeletePagesFromSearchUseCase
|
|
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// NewDeletePagesService creates a new DeletePagesService
|
|
func NewDeletePagesService(
|
|
validateSiteUC *pageusecase.ValidateSiteForDeletionUseCase,
|
|
deletePagesRepoUC *pageusecase.DeletePagesFromRepoUseCase,
|
|
deletePagesSearchUC *pageusecase.DeletePagesFromSearchUseCase,
|
|
logger *zap.Logger,
|
|
) DeletePagesService {
|
|
return &deletePagesService{
|
|
validateSiteUC: validateSiteUC,
|
|
deletePagesRepoUC: deletePagesRepoUC,
|
|
deletePagesSearchUC: deletePagesSearchUC,
|
|
logger: logger.Named("delete-pages-service"),
|
|
}
|
|
}
|
|
|
|
// DeletePages orchestrates the deletion of specific pages
|
|
func (s *deletePagesService) DeletePages(ctx context.Context, tenantID, siteID gocql.UUID, input *pageusecase.DeletePagesInput) (*pageusecase.DeletePagesOutput, error) {
|
|
s.logger.Info("deleting pages",
|
|
zap.String("tenant_id", tenantID.String()),
|
|
zap.String("site_id", siteID.String()),
|
|
zap.Int("page_count", len(input.PageIDs)))
|
|
|
|
// 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: Delete pages from database
|
|
deleteResult, err := s.deletePagesRepoUC.Execute(ctx, siteID, input.PageIDs)
|
|
if err != nil {
|
|
s.logger.Error("failed to delete pages from database", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
// Step 3: Delete pages from search index (only if database delete succeeded)
|
|
deindexedCount := 0
|
|
if deleteResult.DeletedCount > 0 {
|
|
// Only delete pages that were successfully deleted from database
|
|
successfulPageIDs := s.getSuccessfulPageIDs(input.PageIDs, deleteResult.FailedPages)
|
|
if len(successfulPageIDs) > 0 {
|
|
deindexedCount, _ = s.deletePagesSearchUC.Execute(ctx, siteID, successfulPageIDs)
|
|
}
|
|
}
|
|
|
|
// Step 4: Build output
|
|
message := fmt.Sprintf("Successfully deleted %d pages from database, removed %d from search index",
|
|
deleteResult.DeletedCount, deindexedCount)
|
|
if len(deleteResult.FailedPages) > 0 {
|
|
message += fmt.Sprintf(", failed %d pages", len(deleteResult.FailedPages))
|
|
}
|
|
|
|
s.logger.Info("pages deleted successfully",
|
|
zap.String("site_id", siteID.String()),
|
|
zap.Int("deleted", deleteResult.DeletedCount),
|
|
zap.Int("deindexed", deindexedCount),
|
|
zap.Int("failed", len(deleteResult.FailedPages)))
|
|
|
|
return &pageusecase.DeletePagesOutput{
|
|
DeletedCount: deleteResult.DeletedCount,
|
|
DeindexedCount: deindexedCount,
|
|
FailedPages: deleteResult.FailedPages,
|
|
Message: message,
|
|
}, nil
|
|
}
|
|
|
|
// DeleteAllPages orchestrates the deletion of all pages for a site
|
|
func (s *deletePagesService) DeleteAllPages(ctx context.Context, tenantID, siteID gocql.UUID) (*pageusecase.DeletePagesOutput, error) {
|
|
s.logger.Info("deleting all pages",
|
|
zap.String("tenant_id", tenantID.String()),
|
|
zap.String("site_id", siteID.String()))
|
|
|
|
// 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: Delete all pages from database
|
|
count, err := s.deletePagesRepoUC.ExecuteDeleteAll(ctx, siteID)
|
|
if err != nil {
|
|
s.logger.Error("failed to delete all pages from database", zap.Error(err))
|
|
return nil, err
|
|
}
|
|
|
|
// Step 3: Delete all documents from search index
|
|
_ = s.deletePagesSearchUC.ExecuteDeleteAll(ctx, siteID)
|
|
|
|
s.logger.Info("all pages deleted successfully",
|
|
zap.String("site_id", siteID.String()),
|
|
zap.Int64("count", count))
|
|
|
|
return &pageusecase.DeletePagesOutput{
|
|
DeletedCount: int(count),
|
|
DeindexedCount: int(count),
|
|
Message: fmt.Sprintf("Successfully deleted all %d pages", count),
|
|
}, nil
|
|
}
|
|
|
|
// Helper: Get list of page IDs that were successfully deleted (exclude failed ones)
|
|
func (s *deletePagesService) getSuccessfulPageIDs(allPageIDs, failedPageIDs []string) []string {
|
|
if len(failedPageIDs) == 0 {
|
|
return allPageIDs
|
|
}
|
|
|
|
failedMap := make(map[string]bool, len(failedPageIDs))
|
|
for _, id := range failedPageIDs {
|
|
failedMap[id] = true
|
|
}
|
|
|
|
successful := make([]string, 0, len(allPageIDs)-len(failedPageIDs))
|
|
for _, id := range allPageIDs {
|
|
if !failedMap[id] {
|
|
successful = append(successful, id)
|
|
}
|
|
}
|
|
|
|
return successful
|
|
}
|