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
190
cloud/maplepress-backend/internal/usecase/page/delete.go
Normal file
190
cloud/maplepress-backend/internal/usecase/page/delete.go
Normal file
|
|
@ -0,0 +1,190 @@
|
|||
package page
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/gocql/gocql"
|
||||
"go.uber.org/zap"
|
||||
|
||||
domainpage "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/page"
|
||||
domainsite "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/site"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/pkg/search"
|
||||
)
|
||||
|
||||
// DeletePagesUseCase handles page deletion
|
||||
type DeletePagesUseCase struct {
|
||||
pageRepo domainpage.Repository
|
||||
siteRepo domainsite.Repository
|
||||
searchClient *search.Client
|
||||
logger *zap.Logger
|
||||
}
|
||||
|
||||
// ProvideDeletePagesUseCase creates a new DeletePagesUseCase
|
||||
func ProvideDeletePagesUseCase(
|
||||
pageRepo domainpage.Repository,
|
||||
siteRepo domainsite.Repository,
|
||||
searchClient *search.Client,
|
||||
logger *zap.Logger,
|
||||
) *DeletePagesUseCase {
|
||||
return &DeletePagesUseCase{
|
||||
pageRepo: pageRepo,
|
||||
siteRepo: siteRepo,
|
||||
searchClient: searchClient,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// DeletePagesInput is the input for deleting pages
|
||||
type DeletePagesInput struct {
|
||||
PageIDs []string `json:"page_ids"`
|
||||
}
|
||||
|
||||
// DeletePagesOutput is the output after deleting pages
|
||||
type DeletePagesOutput struct {
|
||||
DeletedCount int `json:"deleted_count"`
|
||||
DeindexedCount int `json:"deindexed_count"`
|
||||
FailedPages []string `json:"failed_pages,omitempty"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
// Execute deletes pages from both database and search index
|
||||
func (uc *DeletePagesUseCase) Execute(ctx context.Context, tenantID, siteID gocql.UUID, input *DeletePagesInput) (*DeletePagesOutput, error) {
|
||||
uc.logger.Info("executing delete pages use case",
|
||||
zap.String("tenant_id", tenantID.String()),
|
||||
zap.String("site_id", siteID.String()),
|
||||
zap.Int("page_count", len(input.PageIDs)))
|
||||
|
||||
// Get site to validate
|
||||
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
|
||||
}
|
||||
|
||||
deletedCount := 0
|
||||
deindexedCount := 0
|
||||
var failedPages []string
|
||||
|
||||
// Delete pages from database
|
||||
if len(input.PageIDs) > 1 {
|
||||
// Use batch delete for multiple pages
|
||||
if err := uc.pageRepo.DeleteMultiple(ctx, siteID, input.PageIDs); err != nil {
|
||||
uc.logger.Error("failed to batch delete pages", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to delete pages: %w", err)
|
||||
}
|
||||
deletedCount = len(input.PageIDs)
|
||||
} else if len(input.PageIDs) == 1 {
|
||||
// Single page delete
|
||||
if err := uc.pageRepo.Delete(ctx, siteID, input.PageIDs[0]); err != nil {
|
||||
uc.logger.Error("failed to delete page",
|
||||
zap.String("page_id", input.PageIDs[0]),
|
||||
zap.Error(err))
|
||||
failedPages = append(failedPages, input.PageIDs[0])
|
||||
} else {
|
||||
deletedCount = 1
|
||||
}
|
||||
}
|
||||
|
||||
// Delete from search index
|
||||
if deletedCount > 0 {
|
||||
if len(input.PageIDs) > 1 {
|
||||
// Batch delete from Meilisearch
|
||||
_, err := uc.searchClient.DeleteDocuments(siteID.String(), input.PageIDs)
|
||||
if err != nil {
|
||||
uc.logger.Error("failed to delete documents from search index", zap.Error(err))
|
||||
// Don't fail the whole operation since database delete succeeded
|
||||
} else {
|
||||
deindexedCount = len(input.PageIDs)
|
||||
}
|
||||
} else if len(input.PageIDs) == 1 && len(failedPages) == 0 {
|
||||
// Single document delete
|
||||
_, err := uc.searchClient.DeleteDocument(siteID.String(), input.PageIDs[0])
|
||||
if err != nil {
|
||||
uc.logger.Error("failed to delete document from search index",
|
||||
zap.String("page_id", input.PageIDs[0]),
|
||||
zap.Error(err))
|
||||
// Don't fail the whole operation since database delete succeeded
|
||||
} else {
|
||||
deindexedCount = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uc.logger.Info("pages deleted successfully",
|
||||
zap.String("site_id", siteID.String()),
|
||||
zap.Int("deleted", deletedCount),
|
||||
zap.Int("deindexed", deindexedCount),
|
||||
zap.Int("failed", len(failedPages)))
|
||||
|
||||
message := fmt.Sprintf("Successfully deleted %d pages from database, removed %d from search index", deletedCount, deindexedCount)
|
||||
if len(failedPages) > 0 {
|
||||
message += fmt.Sprintf(", failed %d pages", len(failedPages))
|
||||
}
|
||||
|
||||
return &DeletePagesOutput{
|
||||
DeletedCount: deletedCount,
|
||||
DeindexedCount: deindexedCount,
|
||||
FailedPages: failedPages,
|
||||
Message: message,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// DeleteAllPagesInput is the input for deleting all pages for a site
|
||||
type DeleteAllPagesInput struct{}
|
||||
|
||||
// ExecuteDeleteAll deletes all pages for a site
|
||||
func (uc *DeletePagesUseCase) ExecuteDeleteAll(ctx context.Context, tenantID, siteID gocql.UUID) (*DeletePagesOutput, error) {
|
||||
uc.logger.Info("executing delete all pages use case",
|
||||
zap.String("tenant_id", tenantID.String()),
|
||||
zap.String("site_id", siteID.String()))
|
||||
|
||||
// Get site to validate
|
||||
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
|
||||
}
|
||||
|
||||
// Count pages before deletion
|
||||
count, err := uc.pageRepo.CountBySiteID(ctx, siteID)
|
||||
if err != nil {
|
||||
uc.logger.Error("failed to count pages", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to count pages: %w", err)
|
||||
}
|
||||
|
||||
// Delete all pages from database
|
||||
if err := uc.pageRepo.DeleteBySiteID(ctx, siteID); err != nil {
|
||||
uc.logger.Error("failed to delete all pages", zap.Error(err))
|
||||
return nil, fmt.Errorf("failed to delete pages: %w", err)
|
||||
}
|
||||
|
||||
// Delete all documents from search index
|
||||
_, err = uc.searchClient.DeleteAllDocuments(siteID.String())
|
||||
if err != nil {
|
||||
uc.logger.Error("failed to delete all documents from search index", zap.Error(err))
|
||||
// Don't fail the whole operation since database delete succeeded
|
||||
}
|
||||
|
||||
uc.logger.Info("all pages deleted successfully",
|
||||
zap.String("site_id", siteID.String()),
|
||||
zap.Int64("count", count))
|
||||
|
||||
return &DeletePagesOutput{
|
||||
DeletedCount: int(count),
|
||||
DeindexedCount: int(count),
|
||||
Message: fmt.Sprintf("Successfully deleted all %d pages", count),
|
||||
}, nil
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue