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,198 @@
// monorepo/cloud/maplefile-backend/internal/maplefile/usecase/collection/count_collections.go
package collection
import (
"context"
"go.uber.org/zap"
"github.com/gocql/gocql"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/config"
dom_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/collection"
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/httperror"
)
// CountCollectionsResponse contains the collection counts for a user
type CountCollectionsResponse struct {
OwnedCollections int `json:"owned_collections"`
SharedCollections int `json:"shared_collections"`
TotalCollections int `json:"total_collections"`
}
// CountFoldersResponse contains the folder counts for a user (folders only, not albums)
type CountFoldersResponse struct {
OwnedFolders int `json:"owned_folders"`
SharedFolders int `json:"shared_folders"`
TotalFolders int `json:"total_folders"`
}
type CountUserCollectionsUseCase interface {
Execute(ctx context.Context, userID gocql.UUID) (*CountCollectionsResponse, error)
}
// NEW: Use case specifically for counting folders only
type CountUserFoldersUseCase interface {
Execute(ctx context.Context, userID gocql.UUID) (*CountFoldersResponse, error)
}
type countUserCollectionsUseCaseImpl struct {
config *config.Configuration
logger *zap.Logger
repo dom_collection.CollectionRepository
}
type countUserFoldersUseCaseImpl struct {
config *config.Configuration
logger *zap.Logger
repo dom_collection.CollectionRepository
}
func NewCountUserCollectionsUseCase(
config *config.Configuration,
logger *zap.Logger,
repo dom_collection.CollectionRepository,
) CountUserCollectionsUseCase {
logger = logger.Named("CountUserCollectionsUseCase")
return &countUserCollectionsUseCaseImpl{config, logger, repo}
}
func NewCountUserFoldersUseCase(
config *config.Configuration,
logger *zap.Logger,
repo dom_collection.CollectionRepository,
) CountUserFoldersUseCase {
logger = logger.Named("CountUserFoldersUseCase")
return &countUserFoldersUseCaseImpl{config, logger, repo}
}
func (uc *countUserCollectionsUseCaseImpl) Execute(ctx context.Context, userID gocql.UUID) (*CountCollectionsResponse, error) {
//
// STEP 1: Validation.
//
e := make(map[string]string)
if userID.String() == "" {
e["user_id"] = "User ID is required"
}
if len(e) != 0 {
uc.logger.Warn("Failed validating count user collections",
zap.Any("error", e))
return nil, httperror.NewForBadRequest(&e)
}
//
// STEP 2: Count collections.
//
ownedCollections, err := uc.repo.CountOwnedCollections(ctx, userID)
if err != nil {
uc.logger.Error("Failed to count owned collections",
zap.String("user_id", userID.String()),
zap.Error(err))
return nil, err
}
sharedCollections, err := uc.repo.CountSharedCollections(ctx, userID)
if err != nil {
uc.logger.Error("Failed to count shared collections",
zap.String("user_id", userID.String()),
zap.Error(err))
return nil, err
}
response := &CountCollectionsResponse{
OwnedCollections: ownedCollections,
SharedCollections: sharedCollections,
TotalCollections: ownedCollections + sharedCollections,
}
uc.logger.Debug("Successfully counted user collections",
zap.String("user_id", userID.String()),
zap.Int("owned_collections", ownedCollections),
zap.Int("shared_collections", sharedCollections),
zap.Int("total_collections", response.TotalCollections))
return response, nil
}
func (uc *countUserFoldersUseCaseImpl) Execute(ctx context.Context, userID gocql.UUID) (*CountFoldersResponse, error) {
//
// STEP 1: Validation.
//
e := make(map[string]string)
if userID.String() == "" {
e["user_id"] = "User ID is required"
}
if len(e) != 0 {
uc.logger.Warn("Failed validating count user folders",
zap.Any("error", e))
return nil, httperror.NewForBadRequest(&e)
}
//
// STEP 2: DEBUG - Check what's actually in the database
//
// ADD DEBUG LOGGING - Cast to concrete type to access debug method
if debugRepo, ok := uc.repo.(interface {
DebugCollectionRecords(context.Context, gocql.UUID) error
}); ok {
if debugErr := debugRepo.DebugCollectionRecords(ctx, userID); debugErr != nil {
uc.logger.Warn("Failed to debug collection records", zap.Error(debugErr))
}
}
//
// STEP 3: Count folders with separate owned/shared counts AND total unique count
//
ownedFolders, err := uc.repo.CountOwnedFolders(ctx, userID)
if err != nil {
uc.logger.Error("Failed to count owned folders",
zap.String("user_id", userID.String()),
zap.Error(err))
return nil, err
}
sharedFolders, err := uc.repo.CountSharedFolders(ctx, userID)
if err != nil {
uc.logger.Error("Failed to count shared folders",
zap.String("user_id", userID.String()),
zap.Error(err))
return nil, err
}
// NEW: Get the deduplicated total count
var totalUniqueFolders int
if uniqueRepo, ok := uc.repo.(interface {
CountTotalUniqueFolders(context.Context, gocql.UUID) (int, error)
}); ok {
totalUniqueFolders, err = uniqueRepo.CountTotalUniqueFolders(ctx, userID)
if err != nil {
uc.logger.Error("Failed to count unique total folders",
zap.String("user_id", userID.String()),
zap.Error(err))
return nil, err
}
} else {
// Fallback to simple addition if the method is not available
uc.logger.Warn("CountTotalUniqueFolders method not available, using simple addition")
totalUniqueFolders = ownedFolders + sharedFolders
}
response := &CountFoldersResponse{
OwnedFolders: ownedFolders,
SharedFolders: sharedFolders,
TotalFolders: totalUniqueFolders, // Use deduplicated count
}
uc.logger.Info("Successfully counted user folders with deduplication",
zap.String("user_id", userID.String()),
zap.Int("owned_folders", ownedFolders),
zap.Int("shared_folders", sharedFolders),
zap.Int("total_unique_folders", totalUniqueFolders),
zap.Int("would_be_simple_sum", ownedFolders+sharedFolders))
return response, nil
}