Initial commit: Open sourcing all of the Maple Open Technologies code.
This commit is contained in:
commit
755d54a99d
2010 changed files with 448675 additions and 0 deletions
158
cloud/maplefile-backend/internal/service/collection/utils.go
Normal file
158
cloud/maplefile-backend/internal/service/collection/utils.go
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
// monorepo/cloud/backend/internal/maplefile/service/collection/utils.go
|
||||
package collection
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gocql/gocql"
|
||||
"go.uber.org/zap"
|
||||
|
||||
dom_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/collection"
|
||||
"codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/validation"
|
||||
)
|
||||
|
||||
// Helper function to get owner email from members list
|
||||
// The owner is always a member with their email, so we can look them up
|
||||
func getOwnerEmailFromMembers(collection *dom_collection.Collection) string {
|
||||
if collection == nil {
|
||||
return ""
|
||||
}
|
||||
for _, member := range collection.Members {
|
||||
if member.RecipientID == collection.OwnerID {
|
||||
return member.RecipientEmail
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Helper function to map a CollectionMembershipDTO to a CollectionMembership domain model
|
||||
// This assumes a direct field-by-field copy is intended by the DTO structure.
|
||||
func mapMembershipDTOToDomain(dto *CollectionMembershipDTO) dom_collection.CollectionMembership {
|
||||
return dom_collection.CollectionMembership{
|
||||
ID: dto.ID, // Copy DTO ID
|
||||
CollectionID: dto.CollectionID, // Copy DTO CollectionID
|
||||
RecipientID: dto.RecipientID, // Copy DTO RecipientID
|
||||
RecipientEmail: dto.RecipientEmail, // Copy DTO RecipientEmail
|
||||
GrantedByID: dto.GrantedByID, // Copy DTO GrantedByID
|
||||
EncryptedCollectionKey: dto.EncryptedCollectionKey, // Copy DTO EncryptedCollectionKey
|
||||
PermissionLevel: dto.PermissionLevel, // Copy DTO PermissionLevel
|
||||
CreatedAt: dto.CreatedAt, // Copy DTO CreatedAt
|
||||
IsInherited: dto.IsInherited, // Copy DTO IsInherited
|
||||
InheritedFromID: dto.InheritedFromID, // Copy DTO InheritedFromID
|
||||
// Note: ModifiedAt/By, Version are not in Membership DTO/Domain
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to map a CreateCollectionRequestDTO to a Collection domain model.
|
||||
// This function recursively maps all fields, including nested members and children,
|
||||
// copying values directly from the DTO. Server-side overrides for fields like
|
||||
// ID, OwnerID, timestamps, and version are applied *after* this mapping in the Execute method.
|
||||
// userID and now are passed for potential use in recursive calls if needed for consistency,
|
||||
// though the primary goal here is to copy DTO values.
|
||||
func mapCollectionDTOToDomain(dto *CreateCollectionRequestDTO, userID gocql.UUID, now time.Time) *dom_collection.Collection {
|
||||
if dto == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
collection := &dom_collection.Collection{
|
||||
// Copy all scalar/pointer fields directly from the DTO as requested by the prompt.
|
||||
// Fields like ID, OwnerID, timestamps, and version from the DTO
|
||||
// represent the client's proposed state and will be potentially
|
||||
// overridden by server-managed values later in the Execute method.
|
||||
ID: dto.ID,
|
||||
OwnerID: dto.OwnerID,
|
||||
EncryptedName: dto.EncryptedName,
|
||||
EncryptedCustomIcon: dto.EncryptedCustomIcon,
|
||||
CollectionType: dto.CollectionType,
|
||||
EncryptedCollectionKey: dto.EncryptedCollectionKey,
|
||||
ParentID: dto.ParentID,
|
||||
AncestorIDs: dto.AncestorIDs,
|
||||
CreatedAt: dto.CreatedAt,
|
||||
CreatedByUserID: dto.CreatedByUserID,
|
||||
ModifiedAt: dto.ModifiedAt,
|
||||
ModifiedByUserID: dto.ModifiedByUserID,
|
||||
}
|
||||
|
||||
// Map members slice from DTO to domain model slice
|
||||
if len(dto.Members) > 0 {
|
||||
collection.Members = make([]dom_collection.CollectionMembership, len(dto.Members))
|
||||
for i, memberDTO := range dto.Members {
|
||||
collection.Members[i] = mapMembershipDTOToDomain(memberDTO)
|
||||
}
|
||||
}
|
||||
|
||||
return collection
|
||||
}
|
||||
|
||||
// Helper function to map a Collection domain model to a CollectionResponseDTO
|
||||
// This function should ideally exclude sensitive data (like recipient-specific keys)
|
||||
// that should not be part of a general response.
|
||||
// fileCount is the number of active files in this collection (pass 0 if not known)
|
||||
// ownerEmail is the email address of the collection owner (pass "" if not known)
|
||||
func mapCollectionToDTO(collection *dom_collection.Collection, fileCount int, ownerEmail string) *CollectionResponseDTO {
|
||||
if collection == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
responseDTO := &CollectionResponseDTO{
|
||||
ID: collection.ID,
|
||||
OwnerID: collection.OwnerID,
|
||||
OwnerEmail: ownerEmail,
|
||||
EncryptedName: collection.EncryptedName,
|
||||
EncryptedCustomIcon: collection.EncryptedCustomIcon,
|
||||
CollectionType: collection.CollectionType,
|
||||
ParentID: collection.ParentID,
|
||||
AncestorIDs: collection.AncestorIDs,
|
||||
Tags: collection.Tags,
|
||||
// Note: EncryptedCollectionKey from the domain model is the owner's key.
|
||||
// Including it in the general response DTO might be acceptable if the response
|
||||
// is only sent to the owner and contains *their* key. Otherwise, this field
|
||||
// might need conditional inclusion or exclusion. The prompt does not require
|
||||
// changing this, so we keep the original mapping which copies the owner's key.
|
||||
EncryptedCollectionKey: collection.EncryptedCollectionKey,
|
||||
CreatedAt: collection.CreatedAt,
|
||||
ModifiedAt: collection.ModifiedAt,
|
||||
FileCount: fileCount,
|
||||
Version: collection.Version,
|
||||
// Members slice needs mapping to MembershipResponseDTO
|
||||
Members: make([]MembershipResponseDTO, len(collection.Members)),
|
||||
}
|
||||
|
||||
// Map members
|
||||
for i, member := range collection.Members {
|
||||
responseDTO.Members[i] = MembershipResponseDTO{
|
||||
ID: member.ID,
|
||||
RecipientID: member.RecipientID,
|
||||
RecipientEmail: member.RecipientEmail, // Email for display
|
||||
PermissionLevel: member.PermissionLevel,
|
||||
GrantedByID: member.GrantedByID,
|
||||
CollectionID: member.CollectionID, // Redundant but useful
|
||||
IsInherited: member.IsInherited,
|
||||
InheritedFromID: member.InheritedFromID,
|
||||
CreatedAt: member.CreatedAt,
|
||||
// Note: EncryptedCollectionKey for this member is recipient-specific
|
||||
// and should NOT be included in a general response DTO unless
|
||||
// filtered for the specific recipient receiving the response.
|
||||
// The MembershipResponseDTO does not have a field for this, which is correct.
|
||||
EncryptedCollectionKey: member.EncryptedCollectionKey,
|
||||
}
|
||||
}
|
||||
|
||||
// Debug: Log what we're sending in the DTO
|
||||
logger, _ := zap.NewDevelopment()
|
||||
logger.Info("🔍 mapCollectionToDTO: Mapping collection to DTO",
|
||||
zap.String("collection_id", collection.ID.String()),
|
||||
zap.Int("domain_members_count", len(collection.Members)),
|
||||
zap.Int("dto_members_count", len(responseDTO.Members)),
|
||||
zap.Int("domain_tags_count", len(collection.Tags)),
|
||||
zap.Int("dto_tags_count", len(responseDTO.Tags)))
|
||||
for i, member := range responseDTO.Members {
|
||||
logger.Info("🔍 mapCollectionToDTO: DTO member",
|
||||
zap.Int("index", i),
|
||||
zap.String("recipient_email", validation.MaskEmail(member.RecipientEmail)),
|
||||
zap.String("recipient_id", member.RecipientID.String()),
|
||||
zap.Int("encrypted_key_length", len(member.EncryptedCollectionKey)))
|
||||
}
|
||||
|
||||
return responseDTO
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue