using System.Collections.Immutable; namespace StellaOps.Doctor.Models; /// /// A single step in a remediation workflow. /// public sealed record RemediationStep { /// /// Order of this step in the remediation sequence (1-based). /// public required int Order { get; init; } /// /// Human-readable description of what this step does. /// public required string Description { get; init; } /// /// The command or action to execute. /// May contain placeholders like {HOSTNAME} or {PASSWORD}. /// public required string Command { get; init; } /// /// Type of command (shell, SQL, API, etc.). /// public CommandType CommandType { get; init; } = CommandType.Shell; /// /// Placeholders in the command that need user-supplied values. /// Key is the placeholder name (e.g., "HOSTNAME"), value is the description. /// public IReadOnlyDictionary? Placeholders { get; init; } /// /// Indicates if this step performs destructive operations (delete, truncate, drop, reset, etc.). /// Destructive steps should not be auto-executed by AdvisoryAI. /// Added as part of SPRINT_20260118_015_Doctor_check_quality_improvements (DQUAL-005). /// public bool IsDestructive { get; init; } /// /// A safe dry-run variant of the command that previews what would happen without making changes. /// For example, "rm -rf /path" might have a dry-run variant of "find /path -type f | head -20". /// Added as part of SPRINT_20260118_015_Doctor_check_quality_improvements (DQUAL-005). /// public string? DryRunVariant { get; init; } } /// /// Remediation instructions for fixing a failed check. /// public sealed record Remediation { /// /// Ordered steps to remediate the issue. /// public required IReadOnlyList Steps { get; init; } /// /// Safety note about the remediation (e.g., "This will restart the service"). /// public string? SafetyNote { get; init; } /// /// Whether a backup is recommended before applying remediation. /// public bool RequiresBackup { get; init; } /// /// URL to a detailed runbook for this remediation. /// Added as part of SPRINT_20260117_029_DOCS_runbook_coverage (RUN-008). /// public string? RunbookUrl { get; init; } /// /// Creates an empty remediation with no steps. /// public static Remediation Empty => new() { Steps = ImmutableArray.Empty }; }