127 lines
3.4 KiB
Go
127 lines
3.4 KiB
Go
package site
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"time"
|
|
|
|
"go.uber.org/zap"
|
|
|
|
domainsite "codeberg.org/mapleopentech/monorepo/cloud/maplepress-backend/internal/domain/site"
|
|
)
|
|
|
|
// ResetMonthlyUsageUseCase handles resetting monthly usage counters for all sites (for billing cycles)
|
|
type ResetMonthlyUsageUseCase struct {
|
|
siteRepo domainsite.Repository
|
|
logger *zap.Logger
|
|
}
|
|
|
|
// ProvideResetMonthlyUsageUseCase creates a new ResetMonthlyUsageUseCase
|
|
func ProvideResetMonthlyUsageUseCase(
|
|
siteRepo domainsite.Repository,
|
|
logger *zap.Logger,
|
|
) *ResetMonthlyUsageUseCase {
|
|
return &ResetMonthlyUsageUseCase{
|
|
siteRepo: siteRepo,
|
|
logger: logger.Named("reset-monthly-usage-usecase"),
|
|
}
|
|
}
|
|
|
|
// ResetUsageOutput is the output after resetting usage counters
|
|
type ResetUsageOutput struct {
|
|
ProcessedSites int `json:"processed_sites"`
|
|
ResetCount int `json:"reset_count"`
|
|
FailedCount int `json:"failed_count"`
|
|
ProcessedAt time.Time `json:"processed_at"`
|
|
}
|
|
|
|
// Execute resets monthly usage counters for all sites (for billing cycles)
|
|
func (uc *ResetMonthlyUsageUseCase) Execute(ctx context.Context) (*ResetUsageOutput, error) {
|
|
uc.logger.Info("starting monthly usage counter reset for all sites")
|
|
|
|
startTime := time.Now()
|
|
processedSites := 0
|
|
resetCount := 0
|
|
failedCount := 0
|
|
|
|
// Pagination settings
|
|
const pageSize = 100
|
|
var pageState []byte
|
|
|
|
// Iterate through all sites using pagination
|
|
for {
|
|
// Get a batch of sites
|
|
sites, nextPageState, err := uc.siteRepo.GetAllSitesForUsageReset(ctx, pageSize, pageState)
|
|
if err != nil {
|
|
uc.logger.Error("failed to get sites for usage reset", zap.Error(err))
|
|
return nil, fmt.Errorf("failed to get sites: %w", err)
|
|
}
|
|
|
|
// Process each site in the batch
|
|
for _, site := range sites {
|
|
processedSites++
|
|
|
|
// Check if usage needs to be reset (monthly billing cycle)
|
|
now := time.Now()
|
|
needsReset := false
|
|
|
|
// Check if it's been a month since last reset
|
|
if site.LastResetAt.AddDate(0, 1, 0).Before(now) {
|
|
needsReset = true
|
|
}
|
|
|
|
if !needsReset {
|
|
uc.logger.Debug("site usage not due for reset",
|
|
zap.String("site_id", site.ID.String()),
|
|
zap.String("domain", site.Domain),
|
|
zap.Time("last_reset_at", site.LastResetAt))
|
|
continue
|
|
}
|
|
|
|
// Reset the usage counters
|
|
site.ResetMonthlyUsage()
|
|
|
|
// Update the site in database
|
|
if err := uc.siteRepo.UpdateUsage(ctx, site); err != nil {
|
|
uc.logger.Error("failed to reset usage for site",
|
|
zap.String("site_id", site.ID.String()),
|
|
zap.String("domain", site.Domain),
|
|
zap.Error(err))
|
|
failedCount++
|
|
continue
|
|
}
|
|
|
|
resetCount++
|
|
uc.logger.Debug("reset usage for site",
|
|
zap.String("site_id", site.ID.String()),
|
|
zap.String("domain", site.Domain),
|
|
zap.Time("last_reset_at", site.LastResetAt))
|
|
}
|
|
|
|
// Check if there are more pages
|
|
if len(nextPageState) == 0 {
|
|
break
|
|
}
|
|
|
|
pageState = nextPageState
|
|
|
|
uc.logger.Info("processed batch of sites",
|
|
zap.Int("batch_size", len(sites)),
|
|
zap.Int("total_processed", processedSites),
|
|
zap.Int("reset_count", resetCount),
|
|
zap.Int("failed_count", failedCount))
|
|
}
|
|
|
|
uc.logger.Info("monthly usage counter reset completed",
|
|
zap.Int("processed_sites", processedSites),
|
|
zap.Int("reset_count", resetCount),
|
|
zap.Int("failed_count", failedCount),
|
|
zap.Duration("duration", time.Since(startTime)))
|
|
|
|
return &ResetUsageOutput{
|
|
ProcessedSites: processedSites,
|
|
ResetCount: resetCount,
|
|
FailedCount: failedCount,
|
|
ProcessedAt: time.Now(),
|
|
}, nil
|
|
}
|