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:
@@ -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);
|
||||
@@ -14,6 +14,11 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Npgsql" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Embed SQL migrations as resources -->
|
||||
<EmbeddedResource Include="Migrations\**\*.sql" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user