using System.Text.RegularExpressions; namespace StellaOps.Concelier.Connector.Acsc.Configuration; /// /// Defines a single ACSC RSS feed endpoint. /// public sealed class AcscFeedOptions { private static readonly Regex SlugPattern = new("^[a-z0-9][a-z0-9\\-]*$", RegexOptions.Compiled | RegexOptions.CultureInvariant); /// /// Logical slug for the feed (alerts, advisories, threats, etc.). /// public string Slug { get; set; } = "alerts"; /// /// Relative path (under ) for the RSS feed. /// public string RelativePath { get; set; } = "/acsc/view-all-content/alerts/rss"; /// /// Indicates whether the feed is active. /// public bool Enabled { get; set; } = true; /// /// Optional display name for logging. /// public string? DisplayName { get; set; } internal void Validate(int index) { if (string.IsNullOrWhiteSpace(Slug)) { throw new InvalidOperationException($"ACSC feed entry #{index} must define a slug."); } if (!SlugPattern.IsMatch(Slug)) { throw new InvalidOperationException($"ACSC feed slug '{Slug}' is invalid. Slugs must be lower-case alphanumeric with optional hyphen separators."); } if (string.IsNullOrWhiteSpace(RelativePath)) { throw new InvalidOperationException($"ACSC feed '{Slug}' must specify a relative path."); } if (!RelativePath.StartsWith("/", StringComparison.Ordinal)) { throw new InvalidOperationException($"ACSC feed '{Slug}' relative path must begin with '/' (value: '{RelativePath}')."); } } }