// monorepo/cloud/backend/internal/maplefile/service/collection/find_root_collections.go package collection 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" dom_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/collection" ) type FindRootCollectionsService interface { Execute(ctx context.Context) (*CollectionsResponseDTO, error) } type findRootCollectionsServiceImpl struct { config *config.Configuration logger *zap.Logger repo dom_collection.CollectionRepository } func NewFindRootCollectionsService( config *config.Configuration, logger *zap.Logger, repo dom_collection.CollectionRepository, ) FindRootCollectionsService { logger = logger.Named("FindRootCollectionsService") return &findRootCollectionsServiceImpl{ config: config, logger: logger, repo: repo, } } func (svc *findRootCollectionsServiceImpl) Execute(ctx context.Context) (*CollectionsResponseDTO, error) { // // STEP 1: 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, nil } // // STEP 2: Find root collections for the user // collections, err := svc.repo.FindRootCollections(ctx, userID) if err != nil { svc.logger.Error("Failed to find root collections", zap.Any("error", err), zap.Any("user_id", userID)) return nil, err } // // STEP 3: Filter collections based on permission levels and map to DTOs // // Filter out collections where the user doesn't have at least read_only permission collectionsWithPermission := make([]*CollectionResponseDTO, 0, len(collections)) for _, collection := range collections { // Check if user has at least read_only permission for this collection hasAccess, err := svc.repo.CheckAccess(ctx, collection.ID, userID, dom_collection.CollectionPermissionReadOnly) if err != nil { svc.logger.Warn("Failed to check collection access for root collection, skipping", zap.Error(err), zap.Any("collection_id", collection.ID), zap.Any("user_id", userID)) continue // Skip collections where we can't verify access } if hasAccess { ownerEmail := getOwnerEmailFromMembers(collection) collectionsWithPermission = append(collectionsWithPermission, mapCollectionToDTO(collection, 0, ownerEmail)) } else { svc.logger.Debug("User lacks permission for root collection, filtering out", zap.Any("collection_id", collection.ID), zap.Any("user_id", userID)) } } response := &CollectionsResponseDTO{ Collections: collectionsWithPermission, } svc.logger.Debug("Found root collections", zap.Int("count", len(collections)), zap.Any("user_id", userID)) return response, nil }