refactor: DB schema fixes + container renames + compose include + audit sprint

- FindingsLedger: change schema from public to findings (V3-01)
- Add 9 migration module plugins: RiskEngine, Replay, ExportCenter, Integrations, Signer, IssuerDirectory, Workflow, PacksRegistry, OpsMemory (V4-01 to V4-09)
- Remove 16 redundant inline CREATE SCHEMA patterns (V4-10)
- Rename export→export-web, excititor→excititor-web for consistency
- Compose stella-ops.yml: thin wrapper using include: directive
- Fix dead /api/v1/jobengine/* gateway routes → release-orchestrator/packsregistry
- Scheduler plugin architecture: ISchedulerJobPlugin + ScanJobPlugin + DoctorJobPlugin
- Create unified audit sink sprint plan
- VulnExplorer integration tests + gap analysis

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-04-08 16:10:36 +03:00
parent 6592cdcc9b
commit 65106afe4c
100 changed files with 5788 additions and 2852 deletions

View File

@@ -0,0 +1,18 @@
-- 001_initial_schema.sql
-- RiskEngine: schema and risk_score_results table.
CREATE SCHEMA IF NOT EXISTS riskengine;
CREATE TABLE IF NOT EXISTS riskengine.risk_score_results (
job_id UUID PRIMARY KEY,
provider TEXT NOT NULL,
subject TEXT NOT NULL,
score DOUBLE PRECISION NOT NULL,
success BOOLEAN NOT NULL,
error TEXT NULL,
signals JSONB NOT NULL,
completed_at TIMESTAMPTZ NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_risk_score_results_completed_at
ON riskengine.risk_score_results (completed_at DESC);

View File

@@ -14,6 +14,11 @@
<ItemGroup>
<PackageReference Include="Npgsql" />
</ItemGroup>
<ItemGroup>
<!-- Embed SQL migrations as resources -->
<EmbeddedResource Include="Migrations\**\*.sql" />
</ItemGroup>

View File

@@ -14,8 +14,6 @@ public sealed class PostgresRiskScoreResultStore : IRiskScoreResultStore, IAsync
private static readonly JsonSerializerOptions JsonOptions = new(JsonSerializerDefaults.Web);
private readonly NpgsqlDataSource _dataSource;
private readonly object _initGate = new();
private bool _tableInitialized;
public PostgresRiskScoreResultStore(string connectionString)
{
@@ -32,7 +30,6 @@ public sealed class PostgresRiskScoreResultStore : IRiskScoreResultStore, IAsync
public async Task SaveAsync(RiskScoreResult result, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
await EnsureTableAsync(cancellationToken).ConfigureAwait(false);
const string sql = """
INSERT INTO riskengine.risk_score_results (
@@ -79,8 +76,6 @@ public sealed class PostgresRiskScoreResultStore : IRiskScoreResultStore, IAsync
public bool TryGet(Guid jobId, out RiskScoreResult result)
{
EnsureTable();
const string sql = """
SELECT provider, subject, score, success, error, signals, completed_at
FROM riskengine.risk_score_results
@@ -127,75 +122,4 @@ public sealed class PostgresRiskScoreResultStore : IRiskScoreResultStore, IAsync
return _dataSource.DisposeAsync();
}
private async Task EnsureTableAsync(CancellationToken cancellationToken)
{
lock (_initGate)
{
if (_tableInitialized)
{
return;
}
}
const string ddl = """
CREATE SCHEMA IF NOT EXISTS riskengine;
CREATE TABLE IF NOT EXISTS riskengine.risk_score_results (
job_id UUID PRIMARY KEY,
provider TEXT NOT NULL,
subject TEXT NOT NULL,
score DOUBLE PRECISION NOT NULL,
success BOOLEAN NOT NULL,
error TEXT NULL,
signals JSONB NOT NULL,
completed_at TIMESTAMPTZ NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_risk_score_results_completed_at
ON riskengine.risk_score_results (completed_at DESC);
""";
await using var connection = await _dataSource.OpenConnectionAsync(cancellationToken).ConfigureAwait(false);
await using var command = new NpgsqlCommand(ddl, connection);
await command.ExecuteNonQueryAsync(cancellationToken).ConfigureAwait(false);
lock (_initGate)
{
_tableInitialized = true;
}
}
private void EnsureTable()
{
lock (_initGate)
{
if (_tableInitialized)
{
return;
}
}
const string ddl = """
CREATE SCHEMA IF NOT EXISTS riskengine;
CREATE TABLE IF NOT EXISTS riskengine.risk_score_results (
job_id UUID PRIMARY KEY,
provider TEXT NOT NULL,
subject TEXT NOT NULL,
score DOUBLE PRECISION NOT NULL,
success BOOLEAN NOT NULL,
error TEXT NULL,
signals JSONB NOT NULL,
completed_at TIMESTAMPTZ NOT NULL
);
CREATE INDEX IF NOT EXISTS idx_risk_score_results_completed_at
ON riskengine.risk_score_results (completed_at DESC);
""";
using var connection = _dataSource.OpenConnection();
using var command = new NpgsqlCommand(ddl, connection);
command.ExecuteNonQuery();
lock (_initGate)
{
_tableInitialized = true;
}
}
}