Search/AdvisoryAI and DAL conversion to EF finishes up. Preparation for microservices consolidation.

This commit is contained in:
master
2026-02-25 18:19:22 +02:00
parent 4db038123b
commit 63c70a6d37
447 changed files with 52257 additions and 2636 deletions

View File

@@ -34,11 +34,15 @@ public sealed class PostgresCallGraphProjectionRepository : RepositoryBase<Signa
WriteIndented = false
};
private readonly TimeProvider _timeProvider;
public PostgresCallGraphProjectionRepository(
SignalsDataSource dataSource,
ILogger<PostgresCallGraphProjectionRepository> logger)
ILogger<PostgresCallGraphProjectionRepository> logger,
TimeProvider? timeProvider = null)
: base(dataSource, logger)
{
_timeProvider = timeProvider ?? TimeProvider.System;
}
/// <inheritdoc />
@@ -53,7 +57,7 @@ public sealed class PostgresCallGraphProjectionRepository : RepositoryBase<Signa
// Keep raw SQL for RETURNING (xmax = 0) which EF cannot express
const string sql = """
INSERT INTO signals.scans (scan_id, artifact_digest, sbom_digest, repo_uri, commit_sha, status, created_at)
VALUES (@scan_id, @artifact_digest, @sbom_digest, @repo_uri, @commit_sha, 'processing', NOW())
VALUES (@scan_id, @artifact_digest, @sbom_digest, @repo_uri, @commit_sha, 'processing', @now)
ON CONFLICT (scan_id)
DO UPDATE SET
artifact_digest = EXCLUDED.artifact_digest,
@@ -64,6 +68,7 @@ public sealed class PostgresCallGraphProjectionRepository : RepositoryBase<Signa
RETURNING (xmax = 0) AS was_inserted
""";
var now = _timeProvider.GetUtcNow();
await using var connection = await DataSource.OpenSystemConnectionAsync(cancellationToken).ConfigureAwait(false);
await using var command = CreateCommand(sql, connection);
@@ -72,6 +77,7 @@ public sealed class PostgresCallGraphProjectionRepository : RepositoryBase<Signa
AddParameter(command, "@sbom_digest", sbomDigest ?? (object)DBNull.Value);
AddParameter(command, "@repo_uri", repoUri ?? (object)DBNull.Value);
AddParameter(command, "@commit_sha", commitSha ?? (object)DBNull.Value);
AddParameter(command, "@now", now);
var result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);
return result is true;
@@ -83,12 +89,14 @@ public sealed class PostgresCallGraphProjectionRepository : RepositoryBase<Signa
await using var connection = await DataSource.OpenSystemConnectionAsync(cancellationToken).ConfigureAwait(false);
await using var dbContext = SignalsDbContextFactory.Create(connection, CommandTimeoutSeconds, GetSchemaName());
var now = _timeProvider.GetUtcNow();
await dbContext.Database.ExecuteSqlRawAsync(
"""
UPDATE signals.scans
SET status = 'completed', completed_at = NOW()
WHERE scan_id = {0}
SET status = 'completed', completed_at = {0}
WHERE scan_id = {1}
""",
now,
scanId,
cancellationToken).ConfigureAwait(false);
}
@@ -99,14 +107,16 @@ public sealed class PostgresCallGraphProjectionRepository : RepositoryBase<Signa
await using var connection = await DataSource.OpenSystemConnectionAsync(cancellationToken).ConfigureAwait(false);
await using var dbContext = SignalsDbContextFactory.Create(connection, CommandTimeoutSeconds, GetSchemaName());
var now = _timeProvider.GetUtcNow();
await dbContext.Database.ExecuteSqlRawAsync(
"""
UPDATE signals.scans
SET status = 'failed', error_message = {1}, completed_at = NOW()
WHERE scan_id = {0}
SET status = 'failed', error_message = {0}, completed_at = {1}
WHERE scan_id = {2}
""",
scanId,
errorMessage,
now,
scanId,
cancellationToken).ConfigureAwait(false);
}

View File

@@ -16,10 +16,12 @@ namespace StellaOps.Signals.Persistence.Postgres.Repositories;
public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDataSource>, IDeploymentRefsRepository
{
private bool _tableInitialized;
private readonly TimeProvider _timeProvider;
public PostgresDeploymentRefsRepository(SignalsDataSource dataSource, ILogger<PostgresDeploymentRefsRepository> logger)
public PostgresDeploymentRefsRepository(SignalsDataSource dataSource, ILogger<PostgresDeploymentRefsRepository> logger, TimeProvider? timeProvider = null)
: base(dataSource, logger)
{
_timeProvider = timeProvider ?? TimeProvider.System;
}
public async Task<int> CountDeploymentsAsync(string purl, CancellationToken cancellationToken = default)
@@ -34,11 +36,13 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
SELECT COUNT(DISTINCT image_id)
FROM signals.deploy_refs
WHERE purl = @purl
AND last_seen_at > NOW() - INTERVAL '30 days'";
AND last_seen_at > @cutoff";
var cutoff = _timeProvider.GetUtcNow().AddDays(-30);
await using var connection = await DataSource.OpenSystemConnectionAsync(cancellationToken).ConfigureAwait(false);
await using var command = CreateCommand(sql, connection);
AddParameter(command, "@purl", purl.Trim());
AddParameter(command, "@cutoff", cutoff);
var result = await command.ExecuteScalarAsync(cancellationToken).ConfigureAwait(false);
return result is long count ? (int)count : 0;
@@ -56,13 +60,15 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
SELECT DISTINCT image_id
FROM signals.deploy_refs
WHERE purl = @purl
AND last_seen_at > NOW() - INTERVAL '30 days'
AND last_seen_at > @cutoff
ORDER BY image_id
LIMIT @limit";
var cutoff = _timeProvider.GetUtcNow().AddDays(-30);
await using var connection = await DataSource.OpenSystemConnectionAsync(cancellationToken).ConfigureAwait(false);
await using var command = CreateCommand(sql, connection);
AddParameter(command, "@purl", purl.Trim());
AddParameter(command, "@cutoff", cutoff);
AddParameter(command, "@limit", limit);
await using var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false);
@@ -85,7 +91,8 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
await using var connection = await DataSource.OpenSystemConnectionAsync(cancellationToken).ConfigureAwait(false);
await using var dbContext = SignalsDbContextFactory.Create(connection, CommandTimeoutSeconds, GetSchemaName());
// Keep raw SQL for UPSERT with ON CONFLICT and COALESCE/NOW() expressions
// Keep raw SQL for UPSERT with ON CONFLICT and COALESCE expressions
var now = _timeProvider.GetUtcNow();
await dbContext.Database.ExecuteSqlRawAsync(
"""
INSERT INTO signals.deploy_refs (
@@ -95,7 +102,7 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
) VALUES (
{0}, {1}, {2}, {3},
{4}, {5}, {6}, {7},
NOW(), NOW()
{8}, {8}
)
ON CONFLICT (purl, image_id, environment)
DO UPDATE SET
@@ -104,7 +111,7 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
namespace = COALESCE(EXCLUDED.namespace, signals.deploy_refs.namespace),
cluster = COALESCE(EXCLUDED.cluster, signals.deploy_refs.cluster),
region = COALESCE(EXCLUDED.region, signals.deploy_refs.region),
last_seen_at = NOW()
last_seen_at = {8}
""",
deployment.Purl.Trim(),
(object?)deployment.PurlVersion ?? DBNull.Value,
@@ -114,6 +121,7 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
(object?)deployment.Namespace ?? DBNull.Value,
(object?)deployment.Cluster ?? DBNull.Value,
(object?)deployment.Region ?? DBNull.Value,
now,
cancellationToken).ConfigureAwait(false);
}
@@ -136,7 +144,7 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
) VALUES (
@purl, @purl_version, @image_id, @image_digest,
@environment, @namespace, @cluster, @region,
NOW(), NOW()
@now, @now
)
ON CONFLICT (purl, image_id, environment)
DO UPDATE SET
@@ -145,8 +153,9 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
namespace = COALESCE(EXCLUDED.namespace, signals.deploy_refs.namespace),
cluster = COALESCE(EXCLUDED.cluster, signals.deploy_refs.cluster),
region = COALESCE(EXCLUDED.region, signals.deploy_refs.region),
last_seen_at = NOW()";
last_seen_at = @now";
var now = _timeProvider.GetUtcNow();
foreach (var deployment in deployments)
{
if (deployment is null)
@@ -162,6 +171,7 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
AddParameter(command, "@namespace", (object?)deployment.Namespace ?? DBNull.Value);
AddParameter(command, "@cluster", (object?)deployment.Cluster ?? DBNull.Value);
AddParameter(command, "@region", (object?)deployment.Region ?? DBNull.Value);
AddParameter(command, "@now", now);
await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
}
@@ -193,12 +203,14 @@ public sealed class PostgresDeploymentRefsRepository : RepositoryBase<SignalsDat
MIN(first_seen_at) as first_deployment
FROM signals.deploy_refs
WHERE purl = @purl
AND last_seen_at > NOW() - INTERVAL '30 days'
AND last_seen_at > @cutoff
GROUP BY purl";
var cutoff = _timeProvider.GetUtcNow().AddDays(-30);
await using var connection = await DataSource.OpenSystemConnectionAsync(cancellationToken).ConfigureAwait(false);
await using var command = CreateCommand(sql, connection);
AddParameter(command, "@purl", purl.Trim());
AddParameter(command, "@cutoff", cutoff);
await using var reader = await command.ExecuteReaderAsync(cancellationToken).ConfigureAwait(false);