Initial commit: Open sourcing all of the Maple Open Technologies code.

This commit is contained in:
Bartlomiej Mika 2025-12-02 14:33:08 -05:00
commit 755d54a99d
2010 changed files with 448675 additions and 0 deletions

View file

@ -0,0 +1,155 @@
// monorepo/cloud/maplefile-backend/internal/maplefile/service/storagedailyusage/get_trend.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/config/constants"
uc_storagedailyusage "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/storagedailyusage"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)
type GetStorageDailyUsageTrendRequestDTO struct {
TrendPeriod string `json:"trend_period"` // "7days", "monthly", "yearly"
Year *int `json:"year,omitempty"`
Month *time.Month `json:"month,omitempty"`
}
type StorageDailyUsageResponseDTO struct {
UserID gocql.UUID `json:"user_id"`
UsageDay time.Time `json:"usage_day"`
TotalBytes int64 `json:"total_bytes"`
TotalAddBytes int64 `json:"total_add_bytes"`
TotalRemoveBytes int64 `json:"total_remove_bytes"`
}
type StorageUsageTrendResponseDTO struct {
UserID gocql.UUID `json:"user_id"`
StartDate time.Time `json:"start_date"`
EndDate time.Time `json:"end_date"`
DailyUsages []*StorageDailyUsageResponseDTO `json:"daily_usages"`
TotalAdded int64 `json:"total_added"`
TotalRemoved int64 `json:"total_removed"`
NetChange int64 `json:"net_change"`
AverageDailyAdd int64 `json:"average_daily_add"`
PeakUsageDay *time.Time `json:"peak_usage_day,omitempty"`
PeakUsageBytes int64 `json:"peak_usage_bytes"`
}
type GetStorageDailyUsageTrendResponseDTO struct {
TrendPeriod string `json:"trend_period"`
Trend *StorageUsageTrendResponseDTO `json:"trend"`
Success bool `json:"success"`
Message string `json:"message"`
}
type GetStorageDailyUsageTrendService interface {
Execute(ctx context.Context, req *GetStorageDailyUsageTrendRequestDTO) (*GetStorageDailyUsageTrendResponseDTO, error)
}
type getStorageDailyUsageTrendServiceImpl struct {
config *config.Configuration
logger *zap.Logger
getStorageDailyUsageTrendUseCase uc_storagedailyusage.GetStorageDailyUsageTrendUseCase
}
func NewGetStorageDailyUsageTrendService(
config *config.Configuration,
logger *zap.Logger,
getStorageDailyUsageTrendUseCase uc_storagedailyusage.GetStorageDailyUsageTrendUseCase,
) GetStorageDailyUsageTrendService {
logger = logger.Named("GetStorageDailyUsageTrendService")
return &getStorageDailyUsageTrendServiceImpl{
config: config,
logger: logger,
getStorageDailyUsageTrendUseCase: getStorageDailyUsageTrendUseCase,
}
}
func (svc *getStorageDailyUsageTrendServiceImpl) Execute(ctx context.Context, req *GetStorageDailyUsageTrendRequestDTO) (*GetStorageDailyUsageTrendResponseDTO, error) {
//
// STEP 1: Validation
//
if req == nil {
svc.logger.Warn("Failed validation with nil request")
return nil, httperror.NewForBadRequestWithSingleField("non_field_error", "Request details are required")
}
//
// STEP 2: Get user ID from context
//
userID, ok := ctx.Value(constants.SessionUserID).(gocql.UUID)
if !ok {
svc.logger.Error("Failed getting user ID from context")
return nil, httperror.NewForInternalServerErrorWithSingleField("message", "Authentication context error")
}
//
// STEP 3: Build use case request
//
useCaseReq := &uc_storagedailyusage.GetStorageDailyUsageTrendRequest{
UserID: userID,
TrendPeriod: req.TrendPeriod,
Year: req.Year,
Month: req.Month,
}
//
// STEP 4: Execute use case
//
trend, err := svc.getStorageDailyUsageTrendUseCase.Execute(ctx, useCaseReq)
if err != nil {
svc.logger.Error("Failed to get storage daily usage trend",
zap.String("user_id", userID.String()),
zap.String("trend_period", req.TrendPeriod),
zap.Error(err))
return nil, err
}
//
// STEP 5: Map domain models to response DTOs
//
dailyUsages := make([]*StorageDailyUsageResponseDTO, len(trend.DailyUsages))
for i, usage := range trend.DailyUsages {
dailyUsages[i] = &StorageDailyUsageResponseDTO{
UserID: usage.UserID,
UsageDay: usage.UsageDay,
TotalBytes: usage.TotalBytes,
TotalAddBytes: usage.TotalAddBytes,
TotalRemoveBytes: usage.TotalRemoveBytes,
}
}
trendResponse := &StorageUsageTrendResponseDTO{
UserID: trend.UserID,
StartDate: trend.StartDate,
EndDate: trend.EndDate,
DailyUsages: dailyUsages,
TotalAdded: trend.TotalAdded,
TotalRemoved: trend.TotalRemoved,
NetChange: trend.NetChange,
AverageDailyAdd: trend.AverageDailyAdd,
PeakUsageDay: trend.PeakUsageDay,
PeakUsageBytes: trend.PeakUsageBytes,
}
response := &GetStorageDailyUsageTrendResponseDTO{
TrendPeriod: req.TrendPeriod,
Trend: trendResponse,
Success: true,
Message: "Storage daily usage trend retrieved successfully",
}
svc.logger.Debug("Storage daily usage trend retrieved successfully",
zap.String("user_id", userID.String()),
zap.String("trend_period", req.TrendPeriod),
zap.Int("daily_usages_count", len(dailyUsages)),
zap.Int64("net_change", trend.NetChange))
return response, nil
}

View file

@ -0,0 +1,153 @@
// monorepo/cloud/maplefile-backend/internal/maplefile/service/storagedailyusage/get_usage_by_date_range.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/config/constants"
uc_storagedailyusage "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/storagedailyusage"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)
type GetStorageUsageByDateRangeRequestDTO struct {
StartDate time.Time `json:"start_date"`
EndDate time.Time `json:"end_date"`
}
type DateRangeSummaryResponseDTO struct {
TotalDays int `json:"total_days"`
DaysWithData int `json:"days_with_data"`
TotalAdded int64 `json:"total_added"`
TotalRemoved int64 `json:"total_removed"`
NetChange int64 `json:"net_change"`
AverageDailyAdd float64 `json:"average_daily_add"`
PeakUsageDay *time.Time `json:"peak_usage_day,omitempty"`
PeakUsageBytes int64 `json:"peak_usage_bytes"`
LowestUsageDay *time.Time `json:"lowest_usage_day,omitempty"`
LowestUsageBytes int64 `json:"lowest_usage_bytes"`
}
type GetStorageUsageByDateRangeResponseDTO struct {
UserID gocql.UUID `json:"user_id"`
StartDate time.Time `json:"start_date"`
EndDate time.Time `json:"end_date"`
DailyUsages []*StorageDailyUsageResponseDTO `json:"daily_usages"`
Summary *DateRangeSummaryResponseDTO `json:"summary"`
Success bool `json:"success"`
Message string `json:"message"`
}
type GetStorageUsageByDateRangeService interface {
Execute(ctx context.Context, req *GetStorageUsageByDateRangeRequestDTO) (*GetStorageUsageByDateRangeResponseDTO, error)
}
type getStorageUsageByDateRangeServiceImpl struct {
config *config.Configuration
logger *zap.Logger
getStorageUsageByDateRangeUseCase uc_storagedailyusage.GetStorageUsageByDateRangeUseCase
}
func NewGetStorageUsageByDateRangeService(
config *config.Configuration,
logger *zap.Logger,
getStorageUsageByDateRangeUseCase uc_storagedailyusage.GetStorageUsageByDateRangeUseCase,
) GetStorageUsageByDateRangeService {
logger = logger.Named("GetStorageUsageByDateRangeService")
return &getStorageUsageByDateRangeServiceImpl{
config: config,
logger: logger,
getStorageUsageByDateRangeUseCase: getStorageUsageByDateRangeUseCase,
}
}
func (svc *getStorageUsageByDateRangeServiceImpl) Execute(ctx context.Context, req *GetStorageUsageByDateRangeRequestDTO) (*GetStorageUsageByDateRangeResponseDTO, error) {
//
// STEP 1: Validation
//
if req == nil {
svc.logger.Warn("Failed validation with nil request")
return nil, httperror.NewForBadRequestWithSingleField("non_field_error", "Request details are required")
}
//
// STEP 2: Get user ID from context
//
userID, ok := ctx.Value(constants.SessionUserID).(gocql.UUID)
if !ok {
svc.logger.Error("Failed getting user ID from context")
return nil, httperror.NewForInternalServerErrorWithSingleField("message", "Authentication context error")
}
//
// STEP 3: Build use case request
//
useCaseReq := &uc_storagedailyusage.GetStorageUsageByDateRangeRequest{
UserID: userID,
StartDate: req.StartDate,
EndDate: req.EndDate,
}
//
// STEP 4: Execute use case
//
useCaseResp, err := svc.getStorageUsageByDateRangeUseCase.Execute(ctx, useCaseReq)
if err != nil {
svc.logger.Error("Failed to get storage usage by date range",
zap.String("user_id", userID.String()),
zap.Time("start_date", req.StartDate),
zap.Time("end_date", req.EndDate),
zap.Error(err))
return nil, err
}
//
// STEP 5: Map domain models to response DTOs
//
dailyUsages := make([]*StorageDailyUsageResponseDTO, len(useCaseResp.DailyUsages))
for i, usage := range useCaseResp.DailyUsages {
dailyUsages[i] = &StorageDailyUsageResponseDTO{
UserID: usage.UserID,
UsageDay: usage.UsageDay,
TotalBytes: usage.TotalBytes,
TotalAddBytes: usage.TotalAddBytes,
TotalRemoveBytes: usage.TotalRemoveBytes,
}
}
summaryResponse := &DateRangeSummaryResponseDTO{
TotalDays: useCaseResp.Summary.TotalDays,
DaysWithData: useCaseResp.Summary.DaysWithData,
TotalAdded: useCaseResp.Summary.TotalAdded,
TotalRemoved: useCaseResp.Summary.TotalRemoved,
NetChange: useCaseResp.Summary.NetChange,
AverageDailyAdd: useCaseResp.Summary.AverageDailyAdd,
PeakUsageDay: useCaseResp.Summary.PeakUsageDay,
PeakUsageBytes: useCaseResp.Summary.PeakUsageBytes,
LowestUsageDay: useCaseResp.Summary.LowestUsageDay,
LowestUsageBytes: useCaseResp.Summary.LowestUsageBytes,
}
response := &GetStorageUsageByDateRangeResponseDTO{
UserID: useCaseResp.UserID,
StartDate: useCaseResp.StartDate,
EndDate: useCaseResp.EndDate,
DailyUsages: dailyUsages,
Summary: summaryResponse,
Success: true,
Message: "Storage usage by date range retrieved successfully",
}
svc.logger.Debug("Storage usage by date range retrieved successfully",
zap.String("user_id", userID.String()),
zap.Time("start_date", req.StartDate),
zap.Time("end_date", req.EndDate),
zap.Int("daily_usages_count", len(dailyUsages)),
zap.Int64("net_change", useCaseResp.Summary.NetChange))
return response, nil
}

View file

@ -0,0 +1,129 @@
// monorepo/cloud/maplefile-backend/internal/maplefile/service/storagedailyusage/get_usage_summary.go
package storagedailyusage
import (
"context"
"go.uber.org/zap"
"github.com/gocql/gocql"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config/constants"
uc_storagedailyusage "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/storagedailyusage"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)
type GetStorageUsageSummaryRequestDTO struct {
SummaryType string `json:"summary_type"` // "current_month", "current_year"
}
type StorageUsageSummaryResponseDTO struct {
UserID gocql.UUID `json:"user_id"`
Period string `json:"period"`
StartDate string `json:"start_date"`
EndDate string `json:"end_date"`
CurrentUsage int64 `json:"current_usage_bytes"`
TotalAdded int64 `json:"total_added_bytes"`
TotalRemoved int64 `json:"total_removed_bytes"`
NetChange int64 `json:"net_change_bytes"`
DaysWithData int `json:"days_with_data"`
}
type GetStorageUsageSummaryResponseDTO struct {
SummaryType string `json:"summary_type"`
Summary *StorageUsageSummaryResponseDTO `json:"summary"`
Success bool `json:"success"`
Message string `json:"message"`
}
type GetStorageUsageSummaryService interface {
Execute(ctx context.Context, req *GetStorageUsageSummaryRequestDTO) (*GetStorageUsageSummaryResponseDTO, error)
}
type getStorageUsageSummaryServiceImpl struct {
config *config.Configuration
logger *zap.Logger
getStorageUsageSummaryUseCase uc_storagedailyusage.GetStorageUsageSummaryUseCase
}
func NewGetStorageUsageSummaryService(
config *config.Configuration,
logger *zap.Logger,
getStorageUsageSummaryUseCase uc_storagedailyusage.GetStorageUsageSummaryUseCase,
) GetStorageUsageSummaryService {
logger = logger.Named("GetStorageUsageSummaryService")
return &getStorageUsageSummaryServiceImpl{
config: config,
logger: logger,
getStorageUsageSummaryUseCase: getStorageUsageSummaryUseCase,
}
}
func (svc *getStorageUsageSummaryServiceImpl) Execute(ctx context.Context, req *GetStorageUsageSummaryRequestDTO) (*GetStorageUsageSummaryResponseDTO, error) {
//
// STEP 1: Validation
//
if req == nil {
svc.logger.Warn("Failed validation with nil request")
return nil, httperror.NewForBadRequestWithSingleField("non_field_error", "Request details are required")
}
//
// STEP 2: Get user ID from context
//
userID, ok := ctx.Value(constants.SessionUserID).(gocql.UUID)
if !ok {
svc.logger.Error("Failed getting user ID from context")
return nil, httperror.NewForInternalServerErrorWithSingleField("message", "Authentication context error")
}
//
// STEP 3: Build use case request
//
useCaseReq := &uc_storagedailyusage.GetStorageUsageSummaryRequest{
UserID: userID,
SummaryType: req.SummaryType,
}
//
// STEP 4: Execute use case
//
summary, err := svc.getStorageUsageSummaryUseCase.Execute(ctx, useCaseReq)
if err != nil {
svc.logger.Error("Failed to get storage usage summary",
zap.String("user_id", userID.String()),
zap.String("summary_type", req.SummaryType),
zap.Error(err))
return nil, err
}
//
// STEP 5: Map domain model to response DTO
//
summaryResponse := &StorageUsageSummaryResponseDTO{
UserID: summary.UserID,
Period: summary.Period,
StartDate: summary.StartDate.Format("2006-01-02"),
EndDate: summary.EndDate.Format("2006-01-02"),
CurrentUsage: summary.CurrentUsage,
TotalAdded: summary.TotalAdded,
TotalRemoved: summary.TotalRemoved,
NetChange: summary.NetChange,
DaysWithData: summary.DaysWithData,
}
response := &GetStorageUsageSummaryResponseDTO{
SummaryType: req.SummaryType,
Summary: summaryResponse,
Success: true,
Message: "Storage usage summary retrieved successfully",
}
svc.logger.Debug("Storage usage summary retrieved successfully",
zap.String("user_id", userID.String()),
zap.String("summary_type", req.SummaryType),
zap.Int64("current_usage", summary.CurrentUsage),
zap.Int64("net_change", summary.NetChange))
return response, nil
}

View file

@ -0,0 +1,42 @@
package storagedailyusage
import (
"go.uber.org/zap"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
uc_storagedailyusage "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/storagedailyusage"
)
// Wire providers for storage daily usage services
func ProvideGetStorageDailyUsageTrendService(
cfg *config.Configuration,
logger *zap.Logger,
getStorageDailyUsageTrendUseCase uc_storagedailyusage.GetStorageDailyUsageTrendUseCase,
) GetStorageDailyUsageTrendService {
return NewGetStorageDailyUsageTrendService(cfg, logger, getStorageDailyUsageTrendUseCase)
}
func ProvideGetStorageUsageSummaryService(
cfg *config.Configuration,
logger *zap.Logger,
getStorageUsageSummaryUseCase uc_storagedailyusage.GetStorageUsageSummaryUseCase,
) GetStorageUsageSummaryService {
return NewGetStorageUsageSummaryService(cfg, logger, getStorageUsageSummaryUseCase)
}
func ProvideGetStorageUsageByDateRangeService(
cfg *config.Configuration,
logger *zap.Logger,
getStorageUsageByDateRangeUseCase uc_storagedailyusage.GetStorageUsageByDateRangeUseCase,
) GetStorageUsageByDateRangeService {
return NewGetStorageUsageByDateRangeService(cfg, logger, getStorageUsageByDateRangeUseCase)
}
func ProvideUpdateStorageUsageService(
cfg *config.Configuration,
logger *zap.Logger,
updateStorageUsageUseCase uc_storagedailyusage.UpdateStorageUsageUseCase,
) UpdateStorageUsageService {
return NewUpdateStorageUsageService(cfg, logger, updateStorageUsageUseCase)
}

View file

@ -0,0 +1,111 @@
// monorepo/cloud/maplefile-backend/internal/maplefile/service/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/config/constants"
uc_storagedailyusage "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/storagedailyusage"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)
type UpdateStorageUsageRequestDTO struct {
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 UpdateStorageUsageResponseDTO struct {
Success bool `json:"success"`
Message string `json:"message"`
}
type UpdateStorageUsageService interface {
Execute(ctx context.Context, req *UpdateStorageUsageRequestDTO) (*UpdateStorageUsageResponseDTO, error)
}
type updateStorageUsageServiceImpl struct {
config *config.Configuration
logger *zap.Logger
updateStorageUsageUseCase uc_storagedailyusage.UpdateStorageUsageUseCase
}
func NewUpdateStorageUsageService(
config *config.Configuration,
logger *zap.Logger,
updateStorageUsageUseCase uc_storagedailyusage.UpdateStorageUsageUseCase,
) UpdateStorageUsageService {
logger = logger.Named("UpdateStorageUsageService")
return &updateStorageUsageServiceImpl{
config: config,
logger: logger,
updateStorageUsageUseCase: updateStorageUsageUseCase,
}
}
func (svc *updateStorageUsageServiceImpl) Execute(ctx context.Context, req *UpdateStorageUsageRequestDTO) (*UpdateStorageUsageResponseDTO, error) {
//
// STEP 1: Validation
//
if req == nil {
svc.logger.Warn("Failed validation with nil request")
return nil, httperror.NewForBadRequestWithSingleField("non_field_error", "Update details are required")
}
//
// STEP 2: Get user ID from context
//
userID, ok := ctx.Value(constants.SessionUserID).(gocql.UUID)
if !ok {
svc.logger.Error("Failed getting user ID from context")
return nil, httperror.NewForInternalServerErrorWithSingleField("message", "Authentication context error")
}
//
// STEP 3: Build use case request
//
useCaseReq := &uc_storagedailyusage.UpdateStorageUsageRequest{
UserID: userID,
UsageDay: req.UsageDay,
TotalBytes: req.TotalBytes,
AddBytes: req.AddBytes,
RemoveBytes: req.RemoveBytes,
IsIncrement: req.IsIncrement,
}
//
// STEP 4: Execute use case
//
err := svc.updateStorageUsageUseCase.Execute(ctx, useCaseReq)
if err != nil {
svc.logger.Error("Failed to update storage usage",
zap.String("user_id", userID.String()),
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 nil, err
}
response := &UpdateStorageUsageResponseDTO{
Success: true,
Message: "Storage usage updated successfully",
}
svc.logger.Debug("Storage usage updated successfully",
zap.String("user_id", userID.String()),
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 response, nil
}