// SPDX-FileCopyrightText: 2026 FocusFlow contributors
// SPDX-License-Identifier: AGPL-3.0-only

part of '../../repositories.dart';

/// Mutation result that avoids throwing for expected repository conflicts.
class RepositoryMutationResult {
  /// Creates a `RepositoryMutationResult._` instance with the values required by its invariants.
  /// Callers should pass already-normalized scheduler data because validation and defaulting belong at the model or service boundary, not in arbitrary UI code.
  const RepositoryMutationResult._({
    this.revision,
    this.failure,
  });

  /// Creates a `RepositoryMutationResult.success` instance with the values required by its invariants.
  /// Callers should pass already-normalized scheduler data because validation and defaulting belong at the model or service boundary, not in arbitrary UI code.
  factory RepositoryMutationResult.success({required int revision}) {
    return RepositoryMutationResult._(revision: revision);
  }

  /// Creates a `RepositoryMutationResult.failure` instance with the values required by its invariants.
  /// Callers should pass already-normalized scheduler data because validation and defaulting belong at the model or service boundary, not in arbitrary UI code.
  factory RepositoryMutationResult.failure(RepositoryFailure failure) {
    return RepositoryMutationResult._(failure: failure);
  }

  /// Stores the `revision` value for this object.
  /// This field is part of the explicit state that downstream scheduling, persistence, or UI code reads when composing behavior.
  final int? revision;

  /// Stores the `failure` value for this object.
  /// This field is part of the explicit state that downstream scheduling, persistence, or UI code reads when composing behavior.
  final RepositoryFailure? failure;

  /// Returns the derived `isSuccess` value for this object.
  /// Keeping this as an accessor gives callers a stable read surface while the owning type controls how the value is calculated.
  bool get isSuccess => failure == null;
}
