using System.Collections.Immutable; using System.Text.Json.Serialization; namespace StellaOps.Policy.Engine.EffectiveDecisionMap; /// /// Represents an effective policy decision for an asset/snapshot. /// Stored in Redis for Graph overlay lookups. /// public sealed record EffectiveDecisionEntry { /// /// Tenant identifier. /// [JsonPropertyName("tenant_id")] public required string TenantId { get; init; } /// /// Asset identifier (PURL or SBOM ID). /// [JsonPropertyName("asset_id")] public required string AssetId { get; init; } /// /// Snapshot identifier (SBOM version or evaluation run). /// [JsonPropertyName("snapshot_id")] public required string SnapshotId { get; init; } /// /// Policy pack ID that produced this decision. /// [JsonPropertyName("pack_id")] public required string PackId { get; init; } /// /// Policy pack version. /// [JsonPropertyName("pack_version")] public required int PackVersion { get; init; } /// /// Final decision status (allow, warn, deny, blocked). /// [JsonPropertyName("status")] public required string Status { get; init; } /// /// Severity level if applicable. /// [JsonPropertyName("severity")] public string? Severity { get; init; } /// /// Rule name that determined the decision. /// [JsonPropertyName("rule_name")] public string? RuleName { get; init; } /// /// Priority of the applied rule. /// [JsonPropertyName("priority")] public int? Priority { get; init; } /// /// Exception ID if an exception was applied. /// [JsonPropertyName("exception_id")] public string? ExceptionId { get; init; } /// /// Count of advisories affecting this asset. /// [JsonPropertyName("advisory_count")] public int AdvisoryCount { get; init; } /// /// Count of critical/high severity findings. /// [JsonPropertyName("high_severity_count")] public int HighSeverityCount { get; init; } /// /// Aggregated annotations from the decision. /// [JsonPropertyName("annotations")] public ImmutableDictionary Annotations { get; init; } = ImmutableDictionary.Empty; /// /// Version counter for cache coherency. /// [JsonPropertyName("version")] public required long Version { get; init; } /// /// When this entry was evaluated. /// [JsonPropertyName("evaluated_at")] public required DateTimeOffset EvaluatedAt { get; init; } /// /// When this entry expires. /// [JsonPropertyName("expires_at")] public required DateTimeOffset ExpiresAt { get; init; } /// /// Correlation ID for tracing. /// [JsonPropertyName("correlation_id")] public string? CorrelationId { get; init; } } /// /// Result of an effective decision map query. /// public sealed record EffectiveDecisionQueryResult { /// /// Found entries mapped by asset ID. /// public required IReadOnlyDictionary Entries { get; init; } /// /// Asset IDs that were not found. /// public required IReadOnlyList NotFound { get; init; } /// /// Current version of the decision map. /// public long MapVersion { get; init; } /// /// Whether the result came from cache. /// public bool FromCache { get; init; } } /// /// Summary statistics for a snapshot's effective decisions. /// public sealed record EffectiveDecisionSummary { /// /// Snapshot ID. /// public required string SnapshotId { get; init; } /// /// Total assets evaluated. /// public int TotalAssets { get; init; } /// /// Count by status. /// public required IReadOnlyDictionary StatusCounts { get; init; } /// /// Count by severity. /// public required IReadOnlyDictionary SeverityCounts { get; init; } /// /// Assets with exceptions applied. /// public int ExceptionCount { get; init; } /// /// Map version at time of summary. /// public long MapVersion { get; init; } /// /// When this summary was computed. /// public DateTimeOffset ComputedAt { get; init; } } /// /// Filter options for querying effective decisions. /// public sealed record EffectiveDecisionFilter { /// /// Filter by status values. /// public IReadOnlyList? Statuses { get; init; } /// /// Filter by severity values. /// public IReadOnlyList? Severities { get; init; } /// /// Include only assets with exceptions. /// public bool? HasException { get; init; } /// /// Filter by minimum advisory count. /// public int? MinAdvisoryCount { get; init; } /// /// Filter by minimum high severity count. /// public int? MinHighSeverityCount { get; init; } /// /// Maximum results to return. /// public int Limit { get; init; } = 1000; /// /// Offset for pagination. /// public int Offset { get; init; } = 0; }