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;
}