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,15 @@
|
||||
-- 001_initial_schema.sql
|
||||
-- Replay: schema and feed_snapshot_index table.
|
||||
|
||||
CREATE SCHEMA IF NOT EXISTS replay;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS replay.feed_snapshot_index (
|
||||
provider_id TEXT NOT NULL,
|
||||
digest TEXT NOT NULL,
|
||||
captured_at TIMESTAMPTZ NOT NULL,
|
||||
epoch_timestamp TIMESTAMPTZ NOT NULL,
|
||||
PRIMARY KEY (provider_id, captured_at, digest)
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_replay_snapshot_index_lookup
|
||||
ON replay.feed_snapshot_index (provider_id, captured_at DESC, digest ASC);
|
||||
@@ -8,8 +8,6 @@ namespace StellaOps.Replay.WebService;
|
||||
public sealed class PostgresFeedSnapshotIndexStore : IFeedSnapshotIndexStore, IAsyncDisposable
|
||||
{
|
||||
private readonly NpgsqlDataSource _dataSource;
|
||||
private readonly object _initGate = new();
|
||||
private bool _tableInitialized;
|
||||
|
||||
public PostgresFeedSnapshotIndexStore(string connectionString)
|
||||
{
|
||||
@@ -26,7 +24,6 @@ public sealed class PostgresFeedSnapshotIndexStore : IFeedSnapshotIndexStore, IA
|
||||
public async Task IndexSnapshotAsync(FeedSnapshotIndexEntry entry, CancellationToken ct = default)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(entry);
|
||||
await EnsureTableAsync(ct).ConfigureAwait(false);
|
||||
|
||||
const string sql = """
|
||||
INSERT INTO replay.feed_snapshot_index (
|
||||
@@ -58,7 +55,6 @@ public sealed class PostgresFeedSnapshotIndexStore : IFeedSnapshotIndexStore, IA
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(providerId);
|
||||
await EnsureTableAsync(ct).ConfigureAwait(false);
|
||||
|
||||
const string sql = """
|
||||
SELECT provider_id, digest, captured_at, epoch_timestamp
|
||||
@@ -97,7 +93,6 @@ public sealed class PostgresFeedSnapshotIndexStore : IFeedSnapshotIndexStore, IA
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(providerId);
|
||||
await EnsureTableAsync(ct).ConfigureAwait(false);
|
||||
|
||||
const string sql = """
|
||||
SELECT provider_id, digest, captured_at, epoch_timestamp
|
||||
@@ -139,38 +134,6 @@ public sealed class PostgresFeedSnapshotIndexStore : IFeedSnapshotIndexStore, IA
|
||||
return _dataSource.DisposeAsync();
|
||||
}
|
||||
|
||||
private async Task EnsureTableAsync(CancellationToken ct)
|
||||
{
|
||||
lock (_initGate)
|
||||
{
|
||||
if (_tableInitialized)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const string ddl = """
|
||||
CREATE SCHEMA IF NOT EXISTS replay;
|
||||
CREATE TABLE IF NOT EXISTS replay.feed_snapshot_index (
|
||||
provider_id TEXT NOT NULL,
|
||||
digest TEXT NOT NULL,
|
||||
captured_at TIMESTAMPTZ NOT NULL,
|
||||
epoch_timestamp TIMESTAMPTZ NOT NULL,
|
||||
PRIMARY KEY (provider_id, captured_at, digest)
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_replay_snapshot_index_lookup
|
||||
ON replay.feed_snapshot_index (provider_id, captured_at DESC, digest ASC);
|
||||
""";
|
||||
|
||||
await using var connection = await _dataSource.OpenConnectionAsync(ct).ConfigureAwait(false);
|
||||
await using var command = new NpgsqlCommand(ddl, connection);
|
||||
await command.ExecuteNonQueryAsync(ct).ConfigureAwait(false);
|
||||
|
||||
lock (_initGate)
|
||||
{
|
||||
_tableInitialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public sealed class SeedFsFeedSnapshotBlobStore : IFeedSnapshotBlobStore
|
||||
|
||||
@@ -30,6 +30,11 @@
|
||||
<EmbeddedResource Include="Translations\*.json" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<!-- Embed SQL migrations as resources -->
|
||||
<EmbeddedResource Include="Migrations\**\*.sql" />
|
||||
</ItemGroup>
|
||||
|
||||
<PropertyGroup Label="StellaOpsReleaseVersion">
|
||||
<Version>1.0.0-alpha1</Version>
|
||||
<InformationalVersion>1.0.0-alpha1</InformationalVersion>
|
||||
|
||||
Reference in New Issue
Block a user