// codeberg.org/mapleopentech/monorepo/cloud/maplefile-backend/internal/repo/user/anonymize_old_ips.go package user import ( "context" "time" "github.com/gocql/gocql" "go.uber.org/zap" ) // AnonymizeOldIPs anonymizes IP addresses in user tables older than the cutoff date func (impl *userStorerImpl) AnonymizeOldIPs(ctx context.Context, cutoffDate time.Time) (int, error) { totalAnonymized := 0 // Anonymize users_by_id table count, err := impl.anonymizeUsersById(ctx, cutoffDate) if err != nil { impl.logger.Error("Failed to anonymize users_by_id", zap.Error(err), zap.Time("cutoff_date", cutoffDate)) return totalAnonymized, err } totalAnonymized += count impl.logger.Info("IP anonymization completed for user tables", zap.Int("total_anonymized", totalAnonymized), zap.Time("cutoff_date", cutoffDate)) return totalAnonymized, nil } // anonymizeUsersById processes the users_by_id table func (impl *userStorerImpl) anonymizeUsersById(ctx context.Context, cutoffDate time.Time) (int, error) { count := 0 // Query all users (efficient primary key scan, no ALLOW FILTERING) query := `SELECT id, created_at, ip_anonymized_at FROM maplefile.users_by_id` iter := impl.session.Query(query).WithContext(ctx).Iter() var id gocql.UUID var createdAt time.Time var ipAnonymizedAt *time.Time for iter.Scan(&id, &createdAt, &ipAnonymizedAt) { // Filter in application code: older than cutoff AND not yet anonymized if createdAt.Before(cutoffDate) && ipAnonymizedAt == nil { // Update the record to anonymize IPs updateQuery := ` UPDATE maplefile.users_by_id SET created_from_ip_address = '', modified_from_ip_address = '', ip_anonymized_at = ? WHERE id = ? ` if err := impl.session.Query(updateQuery, time.Now(), id).WithContext(ctx).Exec(); err != nil { impl.logger.Error("Failed to anonymize user record", zap.String("user_id", id.String()), zap.Error(err)) continue } count++ } } if err := iter.Close(); err != nil { impl.logger.Error("Error during users_by_id iteration", zap.Error(err)) return count, err } impl.logger.Debug("Anonymized users_by_id table", zap.Int("count", count), zap.Time("cutoff_date", cutoffDate)) return count, nil }