using System; using System.Collections.Generic; using System.Text.Json; using System.Text.Json.Serialization; namespace StellaOps.SbomService.Models; public sealed record SbomUploadRequest { [JsonPropertyName("artifactRef")] public string ArtifactRef { get; init; } = string.Empty; [JsonPropertyName("sbom")] public JsonElement? Sbom { get; init; } [JsonPropertyName("sbomBase64")] public string? SbomBase64 { get; init; } [JsonPropertyName("format")] public string? Format { get; init; } [JsonPropertyName("source")] public SbomUploadSource? Source { get; init; } } public sealed record SbomUploadSource { [JsonPropertyName("tool")] public string? Tool { get; init; } [JsonPropertyName("version")] public string? Version { get; init; } [JsonPropertyName("ciContext")] public SbomUploadCiContext? CiContext { get; init; } } public sealed record SbomUploadCiContext { [JsonPropertyName("buildId")] public string? BuildId { get; init; } [JsonPropertyName("repository")] public string? Repository { get; init; } } public sealed record SbomUploadResponse { [JsonPropertyName("sbomId")] public string SbomId { get; init; } = string.Empty; [JsonPropertyName("artifactRef")] public string ArtifactRef { get; init; } = string.Empty; [JsonPropertyName("digest")] public string Digest { get; init; } = string.Empty; [JsonPropertyName("format")] public string Format { get; init; } = string.Empty; [JsonPropertyName("formatVersion")] public string FormatVersion { get; init; } = string.Empty; [JsonPropertyName("validationResult")] public SbomValidationSummary ValidationResult { get; init; } = new(); [JsonPropertyName("analysisJobId")] public string AnalysisJobId { get; init; } = string.Empty; } public sealed record SbomValidationSummary { [JsonPropertyName("valid")] public bool Valid { get; init; } [JsonPropertyName("qualityScore")] public double QualityScore { get; init; } [JsonPropertyName("warnings")] public IReadOnlyList Warnings { get; init; } = Array.Empty(); [JsonPropertyName("errors")] public IReadOnlyList Errors { get; init; } = Array.Empty(); [JsonPropertyName("componentCount")] public int ComponentCount { get; init; } } public sealed record SbomNormalizedComponent( string Key, string Name, string? Version, string? Purl, string? License); public sealed record SbomLedgerSubmission( string ArtifactRef, string Digest, string Format, string FormatVersion, string Source, SbomUploadSource? Provenance, IReadOnlyList Components, Guid? ParentVersionId); public sealed record SbomLedgerVersion { public required Guid VersionId { get; init; } public required Guid ChainId { get; init; } public required string ArtifactRef { get; init; } public required int SequenceNumber { get; init; } public required string Digest { get; init; } public required string Format { get; init; } public required string FormatVersion { get; init; } public required string Source { get; init; } public required DateTimeOffset CreatedAtUtc { get; init; } public SbomUploadSource? Provenance { get; init; } public Guid? ParentVersionId { get; init; } public string? ParentDigest { get; init; } public IReadOnlyList Components { get; init; } = Array.Empty(); } public sealed record SbomVersionHistoryItem( Guid VersionId, int SequenceNumber, string Digest, string Format, string FormatVersion, string Source, DateTimeOffset CreatedAtUtc, Guid? ParentVersionId, string? ParentDigest, int ComponentCount); public sealed record SbomVersionHistoryResult( string ArtifactRef, Guid ChainId, IReadOnlyList Versions, string? NextCursor); public sealed record SbomTemporalQueryResult( string ArtifactRef, SbomVersionHistoryItem? Version); public sealed record SbomDiffComponent( string Key, string Name, string? Purl, string? Version, string? License); public sealed record SbomVersionChange( string Key, string Name, string? Purl, string? FromVersion, string? ToVersion); public sealed record SbomLicenseChange( string Key, string Name, string? Purl, string? FromLicense, string? ToLicense); public sealed record SbomDiffSummary( int AddedCount, int RemovedCount, int VersionChangedCount, int LicenseChangedCount); public sealed record SbomDiffResult { public required Guid BeforeVersionId { get; init; } public required Guid AfterVersionId { get; init; } public IReadOnlyList Added { get; init; } = Array.Empty(); public IReadOnlyList Removed { get; init; } = Array.Empty(); public IReadOnlyList VersionChanged { get; init; } = Array.Empty(); public IReadOnlyList LicenseChanged { get; init; } = Array.Empty(); public SbomDiffSummary Summary { get; init; } = new(0, 0, 0, 0); } public sealed record SbomLineageNode( Guid VersionId, int SequenceNumber, string Digest, string Source, DateTimeOffset CreatedAtUtc); public sealed record SbomLineageEdge( Guid FromVersionId, Guid ToVersionId, string Relationship); public static class SbomLineageRelationships { public const string Parent = "parent"; public const string Build = "build"; } public sealed record SbomLineageResult( string ArtifactRef, Guid ChainId, IReadOnlyList Nodes, IReadOnlyList Edges); public sealed record SbomRetentionResult( int VersionsPruned, int ChainsTouched, IReadOnlyList Messages); public sealed class SbomLedgerOptions { public int MaxVersionsPerArtifact { get; init; } = 50; public int MaxAgeDays { get; init; } public int MinVersionsToKeep { get; init; } = 1; } public sealed record SbomLedgerAuditEntry( string ArtifactRef, Guid VersionId, string Action, DateTimeOffset TimestampUtc, string? Details); public sealed record SbomAnalysisJob( string JobId, string ArtifactRef, Guid VersionId, DateTimeOffset CreatedAtUtc, string Status);