monorepo/cloud/maplefile-backend/internal/usecase/storagedailyusage/update_usage.go

124 lines
3.6 KiB
Go

// monorepo/cloud/maplefile-backend/internal/maplefile/usecase/storagedailyusage/update_usage.go
package storagedailyusage
import (
"context"
"time"
"go.uber.org/zap"
"github.com/gocql/gocql"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/storagedailyusage"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)
// UpdateStorageUsageRequest contains the update parameters
type UpdateStorageUsageRequest struct {
UserID gocql.UUID `json:"user_id"`
UsageDay *time.Time `json:"usage_day,omitempty"` // Optional, defaults to today
TotalBytes int64 `json:"total_bytes"`
AddBytes int64 `json:"add_bytes"`
RemoveBytes int64 `json:"remove_bytes"`
IsIncrement bool `json:"is_increment"` // If true, increment existing values; if false, set absolute values
}
type UpdateStorageUsageUseCase interface {
Execute(ctx context.Context, req *UpdateStorageUsageRequest) error
}
type updateStorageUsageUseCaseImpl struct {
config *config.Configuration
logger *zap.Logger
repo storagedailyusage.StorageDailyUsageRepository
}
func NewUpdateStorageUsageUseCase(
config *config.Configuration,
logger *zap.Logger,
repo storagedailyusage.StorageDailyUsageRepository,
) UpdateStorageUsageUseCase {
logger = logger.Named("UpdateStorageUsageUseCase")
return &updateStorageUsageUseCaseImpl{config, logger, repo}
}
func (uc *updateStorageUsageUseCaseImpl) Execute(ctx context.Context, req *UpdateStorageUsageRequest) error {
//
// STEP 1: Validation.
//
e := make(map[string]string)
if req == nil {
e["request"] = "Request is required"
} else {
if req.UserID.String() == "" {
e["user_id"] = "User ID is required"
}
if req.AddBytes < 0 {
e["add_bytes"] = "Add bytes cannot be negative"
}
if req.RemoveBytes < 0 {
e["remove_bytes"] = "Remove bytes cannot be negative"
}
if !req.IsIncrement && req.TotalBytes < 0 {
e["total_bytes"] = "Total bytes cannot be negative when setting absolute values"
}
}
if len(e) != 0 {
uc.logger.Warn("Failed validating update storage usage",
zap.Any("error", e))
return httperror.NewForBadRequest(&e)
}
//
// STEP 2: Set usage day if not provided.
//
usageDay := time.Now().Truncate(24 * time.Hour)
if req.UsageDay != nil {
usageDay = req.UsageDay.Truncate(24 * time.Hour)
}
//
// STEP 3: Update or increment usage.
//
var err error
if req.IsIncrement {
// Increment existing values
err = uc.repo.IncrementUsage(ctx, req.UserID, usageDay, req.TotalBytes, req.AddBytes, req.RemoveBytes)
} else {
// Set absolute values
usage := &storagedailyusage.StorageDailyUsage{
UserID: req.UserID,
UsageDay: usageDay,
TotalBytes: req.TotalBytes,
TotalAddBytes: req.AddBytes,
TotalRemoveBytes: req.RemoveBytes,
}
err = uc.repo.UpdateOrCreate(ctx, usage)
}
if err != nil {
uc.logger.Error("Failed to update storage usage",
zap.String("user_id", req.UserID.String()),
zap.Time("usage_day", usageDay),
zap.Int64("total_bytes", req.TotalBytes),
zap.Int64("add_bytes", req.AddBytes),
zap.Int64("remove_bytes", req.RemoveBytes),
zap.Bool("is_increment", req.IsIncrement),
zap.Error(err))
return err
}
uc.logger.Debug("Successfully updated storage usage",
zap.String("user_id", req.UserID.String()),
zap.Time("usage_day", usageDay),
zap.Int64("total_bytes", req.TotalBytes),
zap.Int64("add_bytes", req.AddBytes),
zap.Int64("remove_bytes", req.RemoveBytes),
zap.Bool("is_increment", req.IsIncrement))
return nil
}