sprints work

This commit is contained in:
master
2026-01-11 11:19:40 +02:00
parent f6ef1ef337
commit 582a41d7a9
72 changed files with 2680 additions and 390 deletions

View File

@@ -1,6 +1,7 @@
using System.Text.Json;
using StellaOps.Concelier.Models;
using StellaOps.Concelier.Persistence.Postgres.Models;
using StellaOps.Determinism;
namespace StellaOps.Concelier.Persistence.Postgres.Conversion;
@@ -15,6 +16,20 @@ public sealed class AdvisoryConverter
WriteIndented = false
};
private readonly TimeProvider _timeProvider;
private readonly IGuidProvider _guidProvider;
/// <summary>
/// Initializes a new instance of the <see cref="AdvisoryConverter"/> class.
/// </summary>
/// <param name="timeProvider">Time provider for deterministic timestamps.</param>
/// <param name="guidProvider">GUID provider for deterministic ID generation.</param>
public AdvisoryConverter(TimeProvider? timeProvider = null, IGuidProvider? guidProvider = null)
{
_timeProvider = timeProvider ?? TimeProvider.System;
_guidProvider = guidProvider ?? SystemGuidProvider.Instance;
}
/// <summary>
/// Converts an Advisory domain model to PostgreSQL entities.
/// </summary>
@@ -22,8 +37,8 @@ public sealed class AdvisoryConverter
{
ArgumentNullException.ThrowIfNull(advisory);
var advisoryId = Guid.NewGuid();
var now = DateTimeOffset.UtcNow;
var advisoryId = _guidProvider.NewGuid();
var now = _timeProvider.GetUtcNow();
var primaryVulnId = advisory.Aliases
.FirstOrDefault(a => a.StartsWith("CVE-", StringComparison.OrdinalIgnoreCase))
@@ -62,7 +77,7 @@ public sealed class AdvisoryConverter
aliasEntities.Add(new AdvisoryAliasEntity
{
Id = Guid.NewGuid(),
Id = _guidProvider.NewGuid(),
AdvisoryId = advisoryId,
AliasType = aliasType,
AliasValue = alias,
@@ -78,7 +93,7 @@ public sealed class AdvisoryConverter
{
cvssEntities.Add(new AdvisoryCvssEntity
{
Id = Guid.NewGuid(),
Id = _guidProvider.NewGuid(),
AdvisoryId = advisoryId,
CvssVersion = metric.Version,
VectorString = metric.Vector,
@@ -103,7 +118,7 @@ public sealed class AdvisoryConverter
affectedEntities.Add(new AdvisoryAffectedEntity
{
Id = Guid.NewGuid(),
Id = _guidProvider.NewGuid(),
AdvisoryId = advisoryId,
Ecosystem = ecosystem,
PackageName = pkg.Identifier,
@@ -119,7 +134,7 @@ public sealed class AdvisoryConverter
// References
var referenceEntities = advisory.References.Select(reference => new AdvisoryReferenceEntity
{
Id = Guid.NewGuid(),
Id = _guidProvider.NewGuid(),
AdvisoryId = advisoryId,
RefType = reference.Kind ?? "web",
Url = reference.Url,
@@ -129,7 +144,7 @@ public sealed class AdvisoryConverter
// Credits
var creditEntities = advisory.Credits.Select(credit => new AdvisoryCreditEntity
{
Id = Guid.NewGuid(),
Id = _guidProvider.NewGuid(),
AdvisoryId = advisoryId,
Name = credit.DisplayName,
Contact = credit.Contacts.FirstOrDefault(),
@@ -140,7 +155,7 @@ public sealed class AdvisoryConverter
// Weaknesses
var weaknessEntities = advisory.Cwes.Select(weakness => new AdvisoryWeaknessEntity
{
Id = Guid.NewGuid(),
Id = _guidProvider.NewGuid(),
AdvisoryId = advisoryId,
CweId = weakness.Identifier,
Description = weakness.Name,
@@ -157,7 +172,7 @@ public sealed class AdvisoryConverter
{
kevFlags.Add(new KevFlagEntity
{
Id = Guid.NewGuid(),
Id = _guidProvider.NewGuid(),
AdvisoryId = advisoryId,
CveId = cveId,
VendorProject = null,

View File

@@ -9,6 +9,7 @@ using System.Globalization;
using Microsoft.Extensions.Logging;
using Npgsql;
using StellaOps.Concelier.Persistence.Postgres.Models;
using StellaOps.Determinism;
using StellaOps.Infrastructure.Postgres.Repositories;
namespace StellaOps.Concelier.Persistence.Postgres.Repositories;
@@ -19,10 +20,18 @@ namespace StellaOps.Concelier.Persistence.Postgres.Repositories;
public sealed class SyncLedgerRepository : RepositoryBase<ConcelierDataSource>, ISyncLedgerRepository
{
private const string SystemTenantId = "_system";
private readonly TimeProvider _timeProvider;
private readonly IGuidProvider _guidProvider;
public SyncLedgerRepository(ConcelierDataSource dataSource, ILogger<SyncLedgerRepository> logger)
public SyncLedgerRepository(
ConcelierDataSource dataSource,
ILogger<SyncLedgerRepository> logger,
TimeProvider? timeProvider = null,
IGuidProvider? guidProvider = null)
: base(dataSource, logger)
{
_timeProvider = timeProvider ?? TimeProvider.System;
_guidProvider = guidProvider ?? SystemGuidProvider.Instance;
}
#region Ledger Operations
@@ -93,7 +102,7 @@ public sealed class SyncLedgerRepository : RepositoryBase<ConcelierDataSource>,
RETURNING id
""";
var id = entry.Id == Guid.Empty ? Guid.NewGuid() : entry.Id;
var id = entry.Id == Guid.Empty ? _guidProvider.NewGuid() : entry.Id;
await ExecuteAsync(
SystemTenantId,
@@ -106,7 +115,7 @@ public sealed class SyncLedgerRepository : RepositoryBase<ConcelierDataSource>,
AddParameter(cmd, "bundle_hash", entry.BundleHash);
AddParameter(cmd, "items_count", entry.ItemsCount);
AddParameter(cmd, "signed_at", entry.SignedAt);
AddParameter(cmd, "imported_at", entry.ImportedAt == default ? DateTimeOffset.UtcNow : entry.ImportedAt);
AddParameter(cmd, "imported_at", entry.ImportedAt == default ? _timeProvider.GetUtcNow() : entry.ImportedAt);
},
ct).ConfigureAwait(false);
@@ -144,13 +153,13 @@ public sealed class SyncLedgerRepository : RepositoryBase<ConcelierDataSource>,
{
var entry = new SyncLedgerEntity
{
Id = Guid.NewGuid(),
Id = _guidProvider.NewGuid(),
SiteId = siteId,
Cursor = newCursor,
BundleHash = bundleHash,
ItemsCount = itemsCount,
SignedAt = signedAt,
ImportedAt = DateTimeOffset.UtcNow
ImportedAt = _timeProvider.GetUtcNow()
};
await InsertAsync(entry, ct).ConfigureAwait(false);

View File

@@ -18,13 +18,16 @@ public sealed class SitePolicyEnforcementService
{
private readonly ISyncLedgerRepository _repository;
private readonly ILogger<SitePolicyEnforcementService> _logger;
private readonly TimeProvider _timeProvider;
public SitePolicyEnforcementService(
ISyncLedgerRepository repository,
ILogger<SitePolicyEnforcementService> logger)
ILogger<SitePolicyEnforcementService> logger,
TimeProvider? timeProvider = null)
{
_repository = repository ?? throw new ArgumentNullException(nameof(repository));
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
_timeProvider = timeProvider ?? TimeProvider.System;
}
/// <summary>
@@ -301,7 +304,7 @@ public sealed class SitePolicyEnforcementService
WindowHours: windowHours);
}
var windowStart = DateTimeOffset.UtcNow.AddHours(-windowHours);
var windowStart = _timeProvider.GetUtcNow().AddHours(-windowHours);
var recentHistory = history.Where(h => h.ImportedAt >= windowStart).ToList();
return new SiteBudgetInfo(

View File

@@ -29,6 +29,7 @@
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Determinism.Abstractions\StellaOps.Determinism.Abstractions.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Infrastructure.Postgres\StellaOps.Infrastructure.Postgres.csproj" />
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Infrastructure.EfCore\StellaOps.Infrastructure.EfCore.csproj" />
<ProjectReference Include="..\StellaOps.Concelier.Core\StellaOps.Concelier.Core.csproj" />