using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace StellaOps.Scanner.Triage.Entities;
///
/// Effective VEX status for a finding after merging multiple VEX sources.
/// Preserves provenance pointers for auditability.
///
[Table("triage_effective_vex")]
public sealed class TriageEffectiveVex
{
///
/// Unique identifier.
///
[Key]
[Column("id")]
public Guid Id { get; init; } = Guid.NewGuid();
///
/// The finding this VEX status applies to.
///
[Column("finding_id")]
public Guid FindingId { get; init; }
///
/// The effective VEX status after merging.
///
[Column("status")]
public TriageVexStatus Status { get; init; }
///
/// Source domain that provided this VEX (e.g., "excititor").
///
[Required]
[Column("source_domain")]
public required string SourceDomain { get; init; }
///
/// Stable reference string to the source document.
///
[Required]
[Column("source_ref")]
public required string SourceRef { get; init; }
///
/// Array of pruned VEX sources with reasons (for merge transparency).
///
[Column("pruned_sources", TypeName = "jsonb")]
public string? PrunedSourcesJson { get; init; }
///
/// Hash of the DSSE envelope if signed.
///
[Column("dsse_envelope_hash")]
public string? DsseEnvelopeHash { get; init; }
///
/// Reference to Rekor/ledger entry for signature verification.
///
[Column("signature_ref")]
public string? SignatureRef { get; init; }
///
/// Issuer of the VEX document.
///
[Column("issuer")]
public string? Issuer { get; init; }
///
/// When this VEX status became valid.
///
[Column("valid_from")]
public DateTimeOffset ValidFrom { get; init; } = DateTimeOffset.UtcNow;
///
/// When this VEX status expires (null = indefinite).
///
[Column("valid_to")]
public DateTimeOffset? ValidTo { get; init; }
///
/// When this record was collected.
///
[Column("collected_at")]
public DateTimeOffset CollectedAt { get; init; } = DateTimeOffset.UtcNow;
// Navigation property
[ForeignKey(nameof(FindingId))]
public TriageFinding? Finding { get; init; }
}