// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/usecase/collection/anonymize_user_references.go package collection import ( "context" "fmt" "github.com/gocql/gocql" "go.uber.org/zap" dom_collection "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/domain/collection" ) // AnonymizeUserReferencesUseCase handles anonymizing CreatedByUserID and ModifiedByUserID // references when a user is deleted, replacing them with a special "deleted user" UUID. type AnonymizeUserReferencesUseCase interface { Execute(ctx context.Context, userID gocql.UUID) (int, error) } type anonymizeUserReferencesUseCaseImpl struct { logger *zap.Logger repo dom_collection.CollectionRepository } // NewAnonymizeUserReferencesUseCase creates a new use case for anonymizing user references in collections func NewAnonymizeUserReferencesUseCase( logger *zap.Logger, repo dom_collection.CollectionRepository, ) AnonymizeUserReferencesUseCase { return &anonymizeUserReferencesUseCaseImpl{ logger: logger, repo: repo, } } // DeletedUserUUID is a well-known UUID representing a deleted user // UUID: 00000000-0000-0000-0000-000000000001 (DELETED_USER) var DeletedUserUUID = gocql.UUID{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} func (uc *anonymizeUserReferencesUseCaseImpl) Execute(ctx context.Context, userID gocql.UUID) (int, error) { uc.logger.Info("Anonymizing user references in collection metadata", zap.String("user_id", userID.String())) // Get all collections owned by this user collections, err := uc.repo.GetAllByUserID(ctx, userID) if err != nil { uc.logger.Error("Failed to get collections by owner", zap.String("user_id", userID.String()), zap.Error(err)) return 0, fmt.Errorf("failed to get collections by owner: %w", err) } updatedCount := 0 // Update each collection to replace user references with deleted user UUID for _, collection := range collections { needsUpdate := false // Check if this collection has references to the deleted user if collection.CreatedByUserID == userID { collection.CreatedByUserID = DeletedUserUUID needsUpdate = true } if collection.ModifiedByUserID == userID { collection.ModifiedByUserID = DeletedUserUUID needsUpdate = true } // Also anonymize GrantedByID in collection memberships for i := range collection.Members { if collection.Members[i].GrantedByID == userID { collection.Members[i].GrantedByID = DeletedUserUUID needsUpdate = true } } if needsUpdate { // Update the collection with anonymized references if err := uc.repo.Update(ctx, collection); err != nil { uc.logger.Error("Failed to anonymize user references in collection", zap.String("collection_id", collection.ID.String()), zap.String("user_id", userID.String()), zap.Error(err)) // Continue with other collections even if one fails continue } updatedCount++ } } uc.logger.Info("✅ Anonymized user references in collection metadata", zap.String("user_id", userID.String()), zap.Int("collections_updated", updatedCount)) return updatedCount, nil }