monorepo/cloud/maplepress-backend/internal/usecase/tenant/delete.go

60 lines
1.6 KiB
Go

package tenant
import (
"context"
"fmt"
"go.uber.org/zap"
"codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/tenant"
)
// DeleteTenantUseCase handles tenant deletion operations
// Used as compensating transaction in SAGA pattern
type DeleteTenantUseCase struct {
repo tenant.Repository
logger *zap.Logger
}
// ProvideDeleteTenantUseCase creates a new DeleteTenantUseCase for dependency injection
func ProvideDeleteTenantUseCase(
repo tenant.Repository,
logger *zap.Logger,
) *DeleteTenantUseCase {
return &DeleteTenantUseCase{
repo: repo,
logger: logger.Named("delete-tenant-usecase"),
}
}
// Execute deletes a tenant by ID
// This is used as a compensating transaction when registration fails
//
// IMPORTANT: This operation must be idempotent!
// If called multiple times with the same ID, it should not error
func (uc *DeleteTenantUseCase) Execute(ctx context.Context, tenantID string) error {
uc.logger.Info("deleting tenant",
zap.String("tenant_id", tenantID))
// Validate input
if tenantID == "" {
return fmt.Errorf("tenant ID cannot be empty")
}
// Execute deletion using existing repository method
// The repository handles deletion from all denormalized tables:
// - tenants_by_id
// - tenants_by_slug
// - tenants_by_status
if err := uc.repo.Delete(ctx, tenantID); err != nil {
uc.logger.Error("failed to delete tenant",
zap.String("tenant_id", tenantID),
zap.Error(err))
return fmt.Errorf("failed to delete tenant: %w", err)
}
uc.logger.Info("tenant deleted successfully",
zap.String("tenant_id", tenantID))
return nil
}