WorkflowOutboxRetentionDeletionResult.java

package org.hammer.audio.workflow.collaboration.retention;

import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

/**
 * Result of revalidating and deleting one immutable retention plan.
 *
 * @param deletedEventIds event identifiers deleted in the plan's deterministic order
 * @param skippedEventIds missing or no-longer-eligible event identifiers
 */
public record WorkflowOutboxRetentionDeletionResult(
    List<String> deletedEventIds, List<String> skippedEventIds) {

  public WorkflowOutboxRetentionDeletionResult {
    deletedEventIds = validatedIds(deletedEventIds, "deletedEventIds");
    skippedEventIds = validatedIds(skippedEventIds, "skippedEventIds");
    Set<String> overlap = new HashSet<>(deletedEventIds);
    overlap.retainAll(skippedEventIds);
    if (!overlap.isEmpty()) {
      throw new IllegalArgumentException("deleted and skipped event ids overlap: " + overlap);
    }
  }

  /** Returns an immutable defensive copy of the deleted event identifiers. */
  @Override
  public List<String> deletedEventIds() {
    return List.copyOf(deletedEventIds);
  }

  /** Returns an immutable defensive copy of the skipped event identifiers. */
  @Override
  public List<String> skippedEventIds() {
    return List.copyOf(skippedEventIds);
  }

  /** Number of rows deleted by the transaction. */
  public int deletedCount() {
    return deletedEventIds.size();
  }

  /** Number of planned rows skipped after transaction-time revalidation. */
  public int skippedCount() {
    return skippedEventIds.size();
  }

  private static List<String> validatedIds(List<String> values, String name) {
    List<String> ids = List.copyOf(Objects.requireNonNull(values, name));
    Set<String> unique = new HashSet<>();
    for (String id : ids) {
      Objects.requireNonNull(id, name + " entry");
      if (id.isBlank()) {
        throw new IllegalArgumentException(name + " entries must not be blank");
      }
      if (!unique.add(id)) {
        throw new IllegalArgumentException(name + " contains duplicate id: " + id);
      }
    }
    return ids;
  }
}