fix: resolve 4 unhealthy services from fresh volume rebuild

- router-gateway: sync 10 missing jobengine routes to local config (prevent array merge bleed-through)
- findings-ledger-web: add VulnExplorer tables to postgres-init bootstrap script
- timeline-web: replace competing migration hosted service with standard AddStartupMigrations
- graph-api: handle null PostgresGraphRepository gracefully, add graph schema to init
- scheduler-web: add failure_signatures table to init bootstrap

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
master
2026-04-09 16:23:52 +03:00
parent 537f4f17fc
commit 3a36aefd81
13 changed files with 419 additions and 89 deletions

View File

@@ -563,3 +563,86 @@ BEGIN
END $$;
COMMENT ON TABLE ledger_snapshots IS 'Point-in-time snapshots of ledger state for time-travel queries';
-- ============================================================================
-- 010_vex_fix_audit_tables.sql - VulnExplorer persistence tables
-- ============================================================================
BEGIN;
CREATE TABLE IF NOT EXISTS vex_decisions (
id UUID NOT NULL,
tenant_id TEXT NOT NULL,
vulnerability_id TEXT NOT NULL,
subject_type TEXT NOT NULL,
subject_name TEXT NOT NULL,
subject_digest JSONB NOT NULL DEFAULT '{}'::JSONB,
subject_sbom_node_id TEXT,
status TEXT NOT NULL,
justification_type TEXT NOT NULL,
justification_text TEXT,
evidence_refs JSONB,
scope_environments TEXT[],
scope_projects TEXT[],
valid_not_before TIMESTAMPTZ,
valid_not_after TIMESTAMPTZ,
attestation_ref_id TEXT,
attestation_ref_digest JSONB,
attestation_ref_storage TEXT,
signed_override JSONB,
supersedes_decision_id UUID,
created_by_id TEXT NOT NULL,
created_by_name TEXT NOT NULL,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ,
CONSTRAINT pk_vex_decisions PRIMARY KEY (tenant_id, id)
) PARTITION BY LIST (tenant_id);
CREATE TABLE IF NOT EXISTS vex_decisions_default PARTITION OF vex_decisions DEFAULT;
CREATE INDEX IF NOT EXISTS ix_vex_decisions_vuln
ON vex_decisions (tenant_id, vulnerability_id, created_at DESC);
CREATE INDEX IF NOT EXISTS ix_vex_decisions_status
ON vex_decisions (tenant_id, status);
CREATE INDEX IF NOT EXISTS ix_vex_decisions_subject
ON vex_decisions (tenant_id, subject_name);
CREATE TABLE IF NOT EXISTS fix_verifications (
id UUID NOT NULL DEFAULT gen_random_uuid(),
tenant_id TEXT NOT NULL,
cve_id TEXT NOT NULL,
component_purl TEXT NOT NULL,
artifact_digest TEXT,
verdict TEXT NOT NULL DEFAULT 'pending',
transitions JSONB NOT NULL DEFAULT '[]'::JSONB,
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT pk_fix_verifications PRIMARY KEY (tenant_id, id),
CONSTRAINT uq_fix_verifications_cve UNIQUE (tenant_id, cve_id)
) PARTITION BY LIST (tenant_id);
CREATE TABLE IF NOT EXISTS fix_verifications_default PARTITION OF fix_verifications DEFAULT;
CREATE INDEX IF NOT EXISTS ix_fix_verifications_cve
ON fix_verifications (tenant_id, cve_id);
CREATE INDEX IF NOT EXISTS ix_fix_verifications_verdict
ON fix_verifications (tenant_id, verdict);
CREATE TABLE IF NOT EXISTS audit_bundles (
id UUID NOT NULL DEFAULT gen_random_uuid(),
tenant_id TEXT NOT NULL,
bundle_id TEXT NOT NULL,
decision_ids UUID[] NOT NULL,
attestation_digest TEXT,
evidence_refs TEXT[] NOT NULL DEFAULT '{}',
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CONSTRAINT pk_audit_bundles PRIMARY KEY (tenant_id, id),
CONSTRAINT uq_audit_bundles_bundle_id UNIQUE (tenant_id, bundle_id)
) PARTITION BY LIST (tenant_id);
CREATE TABLE IF NOT EXISTS audit_bundles_default PARTITION OF audit_bundles DEFAULT;
CREATE INDEX IF NOT EXISTS ix_audit_bundles_created
ON audit_bundles (tenant_id, created_at DESC);
COMMIT;