// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/user/delete.go package user import ( "context" "fmt" "github.com/gocql/gocql" "go.uber.org/zap" "codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/pkg/validation" ) func (impl userStorerImpl) DeleteByID(ctx context.Context, id gocql.UUID) error { // First, get the user to know all the data we need to delete user, err := impl.GetByID(ctx, id) if err != nil { return fmt.Errorf("failed to get user for deletion: %w", err) } if user == nil { return nil // User doesn't exist, nothing to delete } batch := impl.session.NewBatch(gocql.LoggedBatch).WithContext(ctx) // Delete from all user tables batch.Query(`DELETE FROM users_by_id WHERE id = ?`, id) batch.Query(`DELETE FROM users_by_email WHERE email = ?`, user.Email) // Delete from verification code table if user has verification code // Note: We delete by scanning since verification_code is the partition key // This is acceptable for GDPR deletion (rare operation, thorough cleanup) if user.SecurityData != nil && user.SecurityData.Code != "" { batch.Query(`DELETE FROM users_by_verification_code WHERE verification_code = ?`, user.SecurityData.Code) } // Delete all user sessions // Note: sessions_by_user_id is partitioned by user_id, so this is efficient batch.Query(`DELETE FROM sessions_by_user_id WHERE user_id = ?`, id) // Execute the batch if err := impl.session.ExecuteBatch(batch); err != nil { impl.logger.Error("Failed to delete user", zap.String("user_id", id.String()), zap.Error(err)) return fmt.Errorf("failed to delete user: %w", err) } impl.logger.Info("User deleted successfully", zap.String("user_id", id.String()), zap.String("email", validation.MaskEmail(user.Email))) return nil } func (impl userStorerImpl) DeleteByEmail(ctx context.Context, email string) error { // First get the user by email to get the ID user, err := impl.GetByEmail(ctx, email) if err != nil { return fmt.Errorf("failed to get user by email for deletion: %w", err) } if user == nil { return nil // User doesn't exist } // Delete by ID return impl.DeleteByID(ctx, user.ID) }