ui progressing

This commit is contained in:
master
2026-02-20 23:32:20 +02:00
parent ca5e7888d6
commit 1ec797d5e8
191 changed files with 32771 additions and 6504 deletions

View File

@@ -0,0 +1,81 @@
-- SPRINT_20260220_018 / B22-01
-- Pack 22 global context baseline: regions, environments, and per-user selectors.
CREATE SCHEMA IF NOT EXISTS platform;
CREATE TABLE IF NOT EXISTS platform.context_regions (
region_id text PRIMARY KEY,
display_name text NOT NULL,
sort_order integer NOT NULL,
enabled boolean NOT NULL DEFAULT true
);
CREATE UNIQUE INDEX IF NOT EXISTS ux_platform_context_regions_sort
ON platform.context_regions (sort_order, region_id);
CREATE TABLE IF NOT EXISTS platform.context_environments (
environment_id text PRIMARY KEY,
region_id text NOT NULL REFERENCES platform.context_regions(region_id) ON DELETE RESTRICT,
environment_type text NOT NULL,
display_name text NOT NULL,
sort_order integer NOT NULL,
enabled boolean NOT NULL DEFAULT true
);
CREATE INDEX IF NOT EXISTS ix_platform_context_environments_region_sort
ON platform.context_environments (region_id, sort_order, environment_id);
CREATE INDEX IF NOT EXISTS ix_platform_context_environments_sort
ON platform.context_environments (sort_order, region_id, environment_id);
CREATE TABLE IF NOT EXISTS platform.ui_context_preferences (
tenant_id text NOT NULL,
actor_id text NOT NULL,
regions text[] NOT NULL DEFAULT ARRAY[]::text[],
environments text[] NOT NULL DEFAULT ARRAY[]::text[],
time_window text NOT NULL DEFAULT '24h',
updated_at timestamptz NOT NULL DEFAULT now(),
updated_by text NOT NULL DEFAULT 'system',
PRIMARY KEY (tenant_id, actor_id)
);
CREATE INDEX IF NOT EXISTS ix_platform_ui_context_preferences_updated
ON platform.ui_context_preferences (updated_at DESC, tenant_id, actor_id);
ALTER TABLE platform.ui_context_preferences
DROP CONSTRAINT IF EXISTS ck_platform_ui_context_preferences_time_window;
ALTER TABLE platform.ui_context_preferences
ADD CONSTRAINT ck_platform_ui_context_preferences_time_window
CHECK (time_window IN ('1h', '24h', '7d', '30d', '90d'));
INSERT INTO platform.context_regions (region_id, display_name, sort_order, enabled)
VALUES
('us-east', 'US East', 10, true),
('eu-west', 'EU West', 20, true),
('apac', 'APAC', 30, true)
ON CONFLICT (region_id) DO UPDATE SET
display_name = EXCLUDED.display_name,
sort_order = EXCLUDED.sort_order,
enabled = EXCLUDED.enabled;
INSERT INTO platform.context_environments (
environment_id,
region_id,
environment_type,
display_name,
sort_order,
enabled
)
VALUES
('us-prod', 'us-east', 'production', 'US Production', 10, true),
('us-uat', 'us-east', 'staging', 'US UAT', 11, true),
('eu-prod', 'eu-west', 'production', 'EU Production', 20, true),
('eu-stage', 'eu-west', 'staging', 'EU Staging', 21, true),
('apac-prod', 'apac', 'production', 'APAC Production', 30, true)
ON CONFLICT (environment_id) DO UPDATE SET
region_id = EXCLUDED.region_id,
environment_type = EXCLUDED.environment_type,
display_name = EXCLUDED.display_name,
sort_order = EXCLUDED.sort_order,
enabled = EXCLUDED.enabled;

View File

@@ -0,0 +1,86 @@
-- SPRINT_20260220_018 / B22-02
-- Pack 22 releases read-model projections (list/detail/activity/approvals queue).
CREATE TABLE IF NOT EXISTS release.release_read_model (
release_id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
bundle_id uuid NOT NULL REFERENCES release.control_bundles(id) ON DELETE CASCADE,
latest_version_id uuid NULL REFERENCES release.control_bundle_versions(id) ON DELETE SET NULL,
release_name text NOT NULL,
release_slug text NOT NULL,
release_type text NOT NULL DEFAULT 'standard',
release_status text NOT NULL DEFAULT 'draft',
gate_status text NOT NULL DEFAULT 'pending',
pending_approvals integer NOT NULL DEFAULT 0,
blocking_reasons text[] NOT NULL DEFAULT ARRAY[]::text[],
risk_delta jsonb NOT NULL DEFAULT '{}'::jsonb,
target_environment text NULL,
target_region text NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS ux_release_release_read_model_tenant_bundle
ON release.release_read_model (tenant_id, bundle_id);
CREATE INDEX IF NOT EXISTS ix_release_release_read_model_tenant_status_region
ON release.release_read_model (tenant_id, release_status, target_region, updated_at DESC, release_id);
CREATE TABLE IF NOT EXISTS release.release_activity_projection (
activity_id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
release_id uuid NOT NULL REFERENCES release.control_bundles(id) ON DELETE CASCADE,
run_id uuid NULL REFERENCES release.control_bundle_materialization_runs(run_id) ON DELETE SET NULL,
approval_id text NULL,
event_type text NOT NULL,
event_status text NOT NULL,
target_environment text NULL,
target_region text NULL,
actor_id text NOT NULL,
occurred_at timestamptz NOT NULL,
correlation_key text NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_release_activity_projection_tenant_occurred
ON release.release_activity_projection (tenant_id, occurred_at DESC, activity_id DESC);
CREATE INDEX IF NOT EXISTS ix_release_activity_projection_release
ON release.release_activity_projection (release_id, occurred_at DESC, activity_id DESC);
CREATE TABLE IF NOT EXISTS release.release_approvals_projection (
approval_id text PRIMARY KEY,
tenant_id uuid NOT NULL,
release_id uuid NOT NULL REFERENCES release.control_bundles(id) ON DELETE CASCADE,
run_id uuid NULL REFERENCES release.control_bundle_materialization_runs(run_id) ON DELETE SET NULL,
approval_status text NOT NULL,
required_approvals integer NOT NULL DEFAULT 1,
current_approvals integer NOT NULL DEFAULT 0,
blockers text[] NOT NULL DEFAULT ARRAY[]::text[],
requested_by text NOT NULL,
requested_at timestamptz NOT NULL,
source_environment text NULL,
target_environment text NULL,
target_region text NULL,
correlation_key text NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_release_approvals_projection_tenant_status
ON release.release_approvals_projection (tenant_id, approval_status, requested_at DESC, approval_id);
CREATE INDEX IF NOT EXISTS ix_release_approvals_projection_release
ON release.release_approvals_projection (release_id, requested_at DESC, approval_id);
ALTER TABLE release.release_read_model
DROP CONSTRAINT IF EXISTS ck_release_release_read_model_type;
ALTER TABLE release.release_read_model
ADD CONSTRAINT ck_release_release_read_model_type
CHECK (release_type IN ('standard', 'hotfix'));
ALTER TABLE release.release_approvals_projection
DROP CONSTRAINT IF EXISTS ck_release_approvals_projection_status;
ALTER TABLE release.release_approvals_projection
ADD CONSTRAINT ck_release_approvals_projection_status
CHECK (approval_status IN ('pending', 'approved', 'rejected'));

View File

@@ -0,0 +1,267 @@
-- SPRINT_20260220_018 / B22-03
-- Pack 22 topology inventory read-model projections (regions, environments, targets, hosts, agents, paths, workflows, gate profiles).
CREATE TABLE IF NOT EXISTS release.topology_region_inventory (
tenant_id uuid NOT NULL,
region_id text NOT NULL,
display_name text NOT NULL,
sort_order integer NOT NULL,
environment_count integer NOT NULL DEFAULT 0,
target_count integer NOT NULL DEFAULT 0,
host_count integer NOT NULL DEFAULT 0,
agent_count integer NOT NULL DEFAULT 0,
last_sync_at timestamptz NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, region_id)
);
CREATE INDEX IF NOT EXISTS ix_topology_region_inventory_sort
ON release.topology_region_inventory (tenant_id, sort_order, region_id);
CREATE TABLE IF NOT EXISTS release.topology_environment_inventory (
tenant_id uuid NOT NULL,
environment_id text NOT NULL,
region_id text NOT NULL,
environment_type text NOT NULL,
display_name text NOT NULL,
sort_order integer NOT NULL,
target_count integer NOT NULL DEFAULT 0,
host_count integer NOT NULL DEFAULT 0,
agent_count integer NOT NULL DEFAULT 0,
promotion_path_count integer NOT NULL DEFAULT 0,
workflow_count integer NOT NULL DEFAULT 0,
last_sync_at timestamptz NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, environment_id),
CONSTRAINT fk_topology_environment_inventory_region
FOREIGN KEY (tenant_id, region_id)
REFERENCES release.topology_region_inventory (tenant_id, region_id)
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_topology_environment_inventory_region_sort
ON release.topology_environment_inventory (tenant_id, region_id, sort_order, environment_id);
CREATE TABLE IF NOT EXISTS release.topology_target_inventory (
tenant_id uuid NOT NULL,
target_id text NOT NULL,
target_name text NOT NULL,
region_id text NOT NULL,
environment_id text NOT NULL,
host_id text NOT NULL,
agent_id text NOT NULL,
target_type text NOT NULL,
health_status text NOT NULL,
component_version_id text NOT NULL,
image_digest text NOT NULL,
release_id uuid NULL,
release_version_id uuid NULL,
last_sync_at timestamptz NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, target_id),
CONSTRAINT fk_topology_target_inventory_environment
FOREIGN KEY (tenant_id, environment_id)
REFERENCES release.topology_environment_inventory (tenant_id, environment_id)
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_topology_target_inventory_env_order
ON release.topology_target_inventory (tenant_id, region_id, environment_id, target_name, target_id);
CREATE TABLE IF NOT EXISTS release.topology_host_inventory (
tenant_id uuid NOT NULL,
host_id text NOT NULL,
host_name text NOT NULL,
region_id text NOT NULL,
environment_id text NOT NULL,
runtime_type text NOT NULL,
host_status text NOT NULL,
agent_id text NOT NULL,
target_count integer NOT NULL DEFAULT 0,
last_seen_at timestamptz NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, host_id),
CONSTRAINT fk_topology_host_inventory_environment
FOREIGN KEY (tenant_id, environment_id)
REFERENCES release.topology_environment_inventory (tenant_id, environment_id)
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_topology_host_inventory_env_order
ON release.topology_host_inventory (tenant_id, region_id, environment_id, host_name, host_id);
CREATE TABLE IF NOT EXISTS release.topology_agent_inventory (
tenant_id uuid NOT NULL,
agent_id text NOT NULL,
agent_name text NOT NULL,
region_id text NOT NULL,
environment_id text NOT NULL,
agent_status text NOT NULL,
capabilities text[] NOT NULL DEFAULT ARRAY[]::text[],
assigned_target_count integer NOT NULL DEFAULT 0,
last_heartbeat_at timestamptz NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, agent_id),
CONSTRAINT fk_topology_agent_inventory_environment
FOREIGN KEY (tenant_id, environment_id)
REFERENCES release.topology_environment_inventory (tenant_id, environment_id)
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_topology_agent_inventory_env_order
ON release.topology_agent_inventory (tenant_id, region_id, environment_id, agent_name, agent_id);
CREATE TABLE IF NOT EXISTS release.topology_promotion_path_inventory (
tenant_id uuid NOT NULL,
path_id text NOT NULL,
region_id text NOT NULL,
source_environment_id text NOT NULL,
target_environment_id text NOT NULL,
path_mode text NOT NULL,
path_status text NOT NULL,
required_approvals integer NOT NULL DEFAULT 1,
workflow_id text NOT NULL,
gate_profile_id text NOT NULL,
last_promoted_at timestamptz NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, path_id),
CONSTRAINT fk_topology_promotion_path_source_environment
FOREIGN KEY (tenant_id, source_environment_id)
REFERENCES release.topology_environment_inventory (tenant_id, environment_id)
ON DELETE CASCADE,
CONSTRAINT fk_topology_promotion_path_target_environment
FOREIGN KEY (tenant_id, target_environment_id)
REFERENCES release.topology_environment_inventory (tenant_id, environment_id)
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_topology_promotion_path_inventory_order
ON release.topology_promotion_path_inventory (tenant_id, region_id, source_environment_id, target_environment_id, path_id);
CREATE TABLE IF NOT EXISTS release.topology_workflow_inventory (
tenant_id uuid NOT NULL,
workflow_id text NOT NULL,
workflow_name text NOT NULL,
region_id text NOT NULL,
environment_id text NOT NULL,
trigger_type text NOT NULL,
workflow_status text NOT NULL,
step_count integer NOT NULL DEFAULT 0,
gate_profile_id text NOT NULL,
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, workflow_id),
CONSTRAINT fk_topology_workflow_inventory_environment
FOREIGN KEY (tenant_id, environment_id)
REFERENCES release.topology_environment_inventory (tenant_id, environment_id)
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_topology_workflow_inventory_order
ON release.topology_workflow_inventory (tenant_id, region_id, environment_id, workflow_name, workflow_id);
CREATE TABLE IF NOT EXISTS release.topology_gate_profile_inventory (
tenant_id uuid NOT NULL,
gate_profile_id text NOT NULL,
profile_name text NOT NULL,
region_id text NOT NULL,
environment_id text NOT NULL,
policy_profile text NOT NULL,
required_approvals integer NOT NULL DEFAULT 1,
separation_of_duties boolean NOT NULL DEFAULT false,
blocking_rules text[] NOT NULL DEFAULT ARRAY[]::text[],
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, gate_profile_id),
CONSTRAINT fk_topology_gate_profile_inventory_environment
FOREIGN KEY (tenant_id, environment_id)
REFERENCES release.topology_environment_inventory (tenant_id, environment_id)
ON DELETE CASCADE
);
CREATE INDEX IF NOT EXISTS ix_topology_gate_profile_inventory_order
ON release.topology_gate_profile_inventory (tenant_id, region_id, environment_id, profile_name, gate_profile_id);
CREATE TABLE IF NOT EXISTS release.topology_sync_watermarks (
tenant_id uuid NOT NULL,
projection_name text NOT NULL,
last_synced_at timestamptz NOT NULL,
source_cursor text NULL,
status text NOT NULL DEFAULT 'idle',
error_message text NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, projection_name)
);
CREATE INDEX IF NOT EXISTS ix_topology_sync_watermarks_synced
ON release.topology_sync_watermarks (projection_name, last_synced_at DESC, tenant_id);
ALTER TABLE release.topology_environment_inventory
DROP CONSTRAINT IF EXISTS ck_topology_environment_inventory_type;
ALTER TABLE release.topology_environment_inventory
ADD CONSTRAINT ck_topology_environment_inventory_type
CHECK (environment_type IN ('development', 'staging', 'production'));
ALTER TABLE release.topology_target_inventory
DROP CONSTRAINT IF EXISTS ck_topology_target_inventory_type;
ALTER TABLE release.topology_target_inventory
ADD CONSTRAINT ck_topology_target_inventory_type
CHECK (target_type IN ('docker_host', 'compose_host', 'ecs_service', 'nomad_job', 'ssh_host'));
ALTER TABLE release.topology_target_inventory
DROP CONSTRAINT IF EXISTS ck_topology_target_inventory_health;
ALTER TABLE release.topology_target_inventory
ADD CONSTRAINT ck_topology_target_inventory_health
CHECK (health_status IN ('healthy', 'degraded', 'unhealthy', 'offline', 'unknown'));
ALTER TABLE release.topology_host_inventory
DROP CONSTRAINT IF EXISTS ck_topology_host_inventory_status;
ALTER TABLE release.topology_host_inventory
ADD CONSTRAINT ck_topology_host_inventory_status
CHECK (host_status IN ('healthy', 'degraded', 'offline', 'unknown'));
ALTER TABLE release.topology_agent_inventory
DROP CONSTRAINT IF EXISTS ck_topology_agent_inventory_status;
ALTER TABLE release.topology_agent_inventory
ADD CONSTRAINT ck_topology_agent_inventory_status
CHECK (agent_status IN ('active', 'degraded', 'offline', 'pending'));
ALTER TABLE release.topology_promotion_path_inventory
DROP CONSTRAINT IF EXISTS ck_topology_promotion_path_inventory_mode;
ALTER TABLE release.topology_promotion_path_inventory
ADD CONSTRAINT ck_topology_promotion_path_inventory_mode
CHECK (path_mode IN ('manual', 'auto_on_success', 'emergency'));
ALTER TABLE release.topology_promotion_path_inventory
DROP CONSTRAINT IF EXISTS ck_topology_promotion_path_inventory_status;
ALTER TABLE release.topology_promotion_path_inventory
ADD CONSTRAINT ck_topology_promotion_path_inventory_status
CHECK (path_status IN ('idle', 'pending', 'running', 'failed', 'succeeded'));
ALTER TABLE release.topology_workflow_inventory
DROP CONSTRAINT IF EXISTS ck_topology_workflow_inventory_trigger;
ALTER TABLE release.topology_workflow_inventory
ADD CONSTRAINT ck_topology_workflow_inventory_trigger
CHECK (trigger_type IN ('manual', 'promotion', 'schedule', 'release_created'));
ALTER TABLE release.topology_workflow_inventory
DROP CONSTRAINT IF EXISTS ck_topology_workflow_inventory_status;
ALTER TABLE release.topology_workflow_inventory
ADD CONSTRAINT ck_topology_workflow_inventory_status
CHECK (workflow_status IN ('active', 'inactive', 'running', 'failed', 'idle'));
ALTER TABLE release.topology_sync_watermarks
DROP CONSTRAINT IF EXISTS ck_topology_sync_watermarks_status;
ALTER TABLE release.topology_sync_watermarks
ADD CONSTRAINT ck_topology_sync_watermarks_status
CHECK (status IN ('idle', 'running', 'failed', 'succeeded'));

View File

@@ -0,0 +1,171 @@
-- SPRINT_20260220_018 / B22-04
-- Pack 22 security consolidation read projections (findings/disposition/SBOM explorer).
CREATE TABLE IF NOT EXISTS release.security_finding_projection (
tenant_id uuid NOT NULL,
finding_id text NOT NULL,
cve_id text NOT NULL,
severity text NOT NULL,
package_name text NOT NULL,
component_name text NOT NULL,
release_id uuid NULL,
release_name text NOT NULL,
environment_id text NOT NULL,
region_id text NOT NULL,
reachable boolean NOT NULL DEFAULT false,
reachability_score integer NOT NULL DEFAULT 0,
effective_disposition text NOT NULL,
vex_status text NOT NULL,
exception_status text NOT NULL,
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, finding_id)
);
CREATE INDEX IF NOT EXISTS ix_security_finding_projection_filters
ON release.security_finding_projection (
tenant_id,
region_id,
environment_id,
severity,
effective_disposition,
updated_at DESC,
finding_id
);
CREATE INDEX IF NOT EXISTS ix_security_finding_projection_cve
ON release.security_finding_projection (tenant_id, cve_id, finding_id);
CREATE TABLE IF NOT EXISTS release.security_disposition_projection (
tenant_id uuid NOT NULL,
finding_id text NOT NULL,
cve_id text NOT NULL,
release_id uuid NULL,
release_name text NOT NULL,
package_name text NOT NULL,
component_name text NOT NULL,
environment_id text NOT NULL,
region_id text NOT NULL,
vex_status text NOT NULL,
vex_justification text NOT NULL,
vex_statement_id text NULL,
vex_updated_at timestamptz NULL,
exception_status text NOT NULL,
exception_reason text NOT NULL,
exception_approval_state text NOT NULL,
exception_id text NULL,
exception_expires_at timestamptz NULL,
exception_updated_at timestamptz NULL,
effective_disposition text NOT NULL,
policy_action text NOT NULL,
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, finding_id)
);
CREATE INDEX IF NOT EXISTS ix_security_disposition_projection_filters
ON release.security_disposition_projection (
tenant_id,
region_id,
environment_id,
effective_disposition,
updated_at DESC,
finding_id
);
CREATE INDEX IF NOT EXISTS ix_security_disposition_projection_release
ON release.security_disposition_projection (tenant_id, release_id, finding_id);
CREATE TABLE IF NOT EXISTS release.security_sbom_component_projection (
tenant_id uuid NOT NULL,
component_id text NOT NULL,
release_id uuid NULL,
release_name text NOT NULL,
environment_id text NOT NULL,
region_id text NOT NULL,
package_name text NOT NULL,
component_name text NOT NULL,
component_version text NOT NULL,
supplier text NOT NULL,
license text NOT NULL,
vulnerability_count integer NOT NULL DEFAULT 0,
critical_reachable_count integer NOT NULL DEFAULT 0,
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, component_id)
);
CREATE INDEX IF NOT EXISTS ix_security_sbom_component_projection_filters
ON release.security_sbom_component_projection (
tenant_id,
region_id,
environment_id,
release_name,
component_name,
component_id
);
CREATE TABLE IF NOT EXISTS release.security_sbom_graph_projection (
tenant_id uuid NOT NULL,
edge_id text NOT NULL,
from_node_id text NOT NULL,
to_node_id text NOT NULL,
relation_type text NOT NULL,
region_id text NOT NULL,
environment_id text NOT NULL,
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, edge_id)
);
CREATE INDEX IF NOT EXISTS ix_security_sbom_graph_projection_filters
ON release.security_sbom_graph_projection (
tenant_id,
region_id,
environment_id,
from_node_id,
to_node_id,
edge_id
);
ALTER TABLE release.security_finding_projection
DROP CONSTRAINT IF EXISTS ck_security_finding_projection_severity;
ALTER TABLE release.security_finding_projection
ADD CONSTRAINT ck_security_finding_projection_severity
CHECK (severity IN ('critical', 'high', 'medium', 'low', 'info'));
ALTER TABLE release.security_finding_projection
DROP CONSTRAINT IF EXISTS ck_security_finding_projection_disposition;
ALTER TABLE release.security_finding_projection
ADD CONSTRAINT ck_security_finding_projection_disposition
CHECK (effective_disposition IN ('accepted_risk', 'mitigated', 'action_required', 'review_required'));
ALTER TABLE release.security_disposition_projection
DROP CONSTRAINT IF EXISTS ck_security_disposition_projection_vex_status;
ALTER TABLE release.security_disposition_projection
ADD CONSTRAINT ck_security_disposition_projection_vex_status
CHECK (vex_status IN ('affected', 'not_affected', 'under_investigation'));
ALTER TABLE release.security_disposition_projection
DROP CONSTRAINT IF EXISTS ck_security_disposition_projection_exception_status;
ALTER TABLE release.security_disposition_projection
ADD CONSTRAINT ck_security_disposition_projection_exception_status
CHECK (exception_status IN ('none', 'pending', 'approved', 'rejected'));
ALTER TABLE release.security_disposition_projection
DROP CONSTRAINT IF EXISTS ck_security_disposition_projection_approval_state;
ALTER TABLE release.security_disposition_projection
ADD CONSTRAINT ck_security_disposition_projection_approval_state
CHECK (exception_approval_state IN ('not_requested', 'awaiting_review', 'approved', 'rejected'));
ALTER TABLE release.security_disposition_projection
DROP CONSTRAINT IF EXISTS ck_security_disposition_projection_policy_action;
ALTER TABLE release.security_disposition_projection
ADD CONSTRAINT ck_security_disposition_projection_policy_action
CHECK (policy_action IN ('allow_with_exception', 'allow', 'block', 'review'));

View File

@@ -0,0 +1,128 @@
-- SPRINT_20260220_018 / B22-05
-- Pack 22 integrations feed and VEX source health projections.
CREATE TABLE IF NOT EXISTS release.integration_feed_source_health (
tenant_id uuid NOT NULL,
source_id text NOT NULL,
source_name text NOT NULL,
source_type text NOT NULL,
provider text NOT NULL,
region_id text NOT NULL,
environment_id text NOT NULL,
status text NOT NULL,
freshness text NOT NULL,
freshness_minutes integer NULL,
sla_minutes integer NOT NULL,
last_sync_at timestamptz NULL,
last_success_at timestamptz NULL,
last_error text NULL,
consumer_domains text[] NOT NULL DEFAULT ARRAY[]::text[],
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, source_id, region_id, environment_id)
);
CREATE INDEX IF NOT EXISTS ix_integration_feed_source_health_filters
ON release.integration_feed_source_health (
tenant_id,
region_id,
environment_id,
status,
freshness,
source_type,
source_name
);
CREATE TABLE IF NOT EXISTS release.integration_vex_source_health (
tenant_id uuid NOT NULL,
source_id text NOT NULL,
source_name text NOT NULL,
source_type text NOT NULL,
provider text NOT NULL,
region_id text NOT NULL,
environment_id text NOT NULL,
status text NOT NULL,
freshness text NOT NULL,
freshness_minutes integer NULL,
sla_minutes integer NOT NULL,
statement_format text NOT NULL,
document_count_24h integer NOT NULL DEFAULT 0,
last_sync_at timestamptz NULL,
last_success_at timestamptz NULL,
last_error text NULL,
consumer_domains text[] NOT NULL DEFAULT ARRAY[]::text[],
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, source_id, region_id, environment_id)
);
CREATE INDEX IF NOT EXISTS ix_integration_vex_source_health_filters
ON release.integration_vex_source_health (
tenant_id,
region_id,
environment_id,
status,
freshness,
source_type,
source_name
);
CREATE TABLE IF NOT EXISTS release.integration_source_sync_watermarks (
tenant_id uuid NOT NULL,
source_family text NOT NULL,
region_id text NOT NULL,
environment_id text NOT NULL,
last_synced_at timestamptz NULL,
updated_at timestamptz NOT NULL,
correlation_key text NOT NULL,
PRIMARY KEY (tenant_id, source_family, region_id, environment_id)
);
ALTER TABLE release.integration_feed_source_health
DROP CONSTRAINT IF EXISTS ck_integration_feed_source_health_source_type;
ALTER TABLE release.integration_feed_source_health
ADD CONSTRAINT ck_integration_feed_source_health_source_type
CHECK (source_type IN ('advisory_feed'));
ALTER TABLE release.integration_feed_source_health
DROP CONSTRAINT IF EXISTS ck_integration_feed_source_health_status;
ALTER TABLE release.integration_feed_source_health
ADD CONSTRAINT ck_integration_feed_source_health_status
CHECK (status IN ('healthy', 'degraded', 'offline'));
ALTER TABLE release.integration_feed_source_health
DROP CONSTRAINT IF EXISTS ck_integration_feed_source_health_freshness;
ALTER TABLE release.integration_feed_source_health
ADD CONSTRAINT ck_integration_feed_source_health_freshness
CHECK (freshness IN ('fresh', 'stale', 'unknown'));
ALTER TABLE release.integration_vex_source_health
DROP CONSTRAINT IF EXISTS ck_integration_vex_source_health_source_type;
ALTER TABLE release.integration_vex_source_health
ADD CONSTRAINT ck_integration_vex_source_health_source_type
CHECK (source_type IN ('vex_source'));
ALTER TABLE release.integration_vex_source_health
DROP CONSTRAINT IF EXISTS ck_integration_vex_source_health_status;
ALTER TABLE release.integration_vex_source_health
ADD CONSTRAINT ck_integration_vex_source_health_status
CHECK (status IN ('healthy', 'degraded', 'offline'));
ALTER TABLE release.integration_vex_source_health
DROP CONSTRAINT IF EXISTS ck_integration_vex_source_health_freshness;
ALTER TABLE release.integration_vex_source_health
ADD CONSTRAINT ck_integration_vex_source_health_freshness
CHECK (freshness IN ('fresh', 'stale', 'unknown'));
ALTER TABLE release.integration_vex_source_health
DROP CONSTRAINT IF EXISTS ck_integration_vex_source_health_statement_format;
ALTER TABLE release.integration_vex_source_health
ADD CONSTRAINT ck_integration_vex_source_health_statement_format
CHECK (statement_format IN ('openvex', 'csaf_vex'));

View File

@@ -0,0 +1,44 @@
-- SPRINT_20260220_023 / B23-RUN-02
-- Run input snapshot persistence for deterministic run-detail provenance.
CREATE TABLE IF NOT EXISTS release.run_input_snapshots (
snapshot_id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
run_id uuid NOT NULL REFERENCES release.control_bundle_materialization_runs(run_id) ON DELETE CASCADE,
bundle_id uuid NOT NULL REFERENCES release.control_bundles(id) ON DELETE CASCADE,
bundle_version_id uuid NOT NULL REFERENCES release.control_bundle_versions(id) ON DELETE CASCADE,
policy_pack_version text NOT NULL,
feed_snapshot_id text NOT NULL,
feed_freshness_status text NOT NULL DEFAULT 'unknown',
feed_freshness_minutes integer NULL,
sbom_snapshot_id text NOT NULL,
sbom_job_id text NULL,
reachability_snapshot_id text NOT NULL,
reachability_job_id text NULL,
reachability_coverage_percent integer NOT NULL DEFAULT 0,
reachability_evidence_age_minutes integer NULL,
vex_snapshot_ref text NULL,
disposition_snapshot_ref text NULL,
captured_at timestamptz NOT NULL,
correlation_key text NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS ux_release_run_input_snapshots_tenant_run
ON release.run_input_snapshots (tenant_id, run_id, captured_at DESC, snapshot_id);
CREATE INDEX IF NOT EXISTS ix_release_run_input_snapshots_tenant_bundle_version
ON release.run_input_snapshots (tenant_id, bundle_id, bundle_version_id, captured_at DESC, snapshot_id);
ALTER TABLE release.run_input_snapshots
DROP CONSTRAINT IF EXISTS ck_release_run_input_snapshots_feed_freshness;
ALTER TABLE release.run_input_snapshots
ADD CONSTRAINT ck_release_run_input_snapshots_feed_freshness
CHECK (feed_freshness_status IN ('fresh', 'stale', 'unknown'));
ALTER TABLE release.run_input_snapshots
DROP CONSTRAINT IF EXISTS ck_release_run_input_snapshots_coverage_percent;
ALTER TABLE release.run_input_snapshots
ADD CONSTRAINT ck_release_run_input_snapshots_coverage_percent
CHECK (reachability_coverage_percent BETWEEN 0 AND 100);

View File

@@ -0,0 +1,44 @@
-- SPRINT_20260220_023 / B23-RUN-03
-- Run gate decision ledger for provenance and explainability.
CREATE TABLE IF NOT EXISTS release.run_gate_decision_ledger (
gate_decision_id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
run_id uuid NOT NULL REFERENCES release.control_bundle_materialization_runs(run_id) ON DELETE CASCADE,
snapshot_id uuid NULL REFERENCES release.run_input_snapshots(snapshot_id) ON DELETE SET NULL,
verdict text NOT NULL,
machine_reason_codes text[] NOT NULL DEFAULT ARRAY[]::text[],
human_reason_codes text[] NOT NULL DEFAULT ARRAY[]::text[],
risk_budget_delta numeric(12, 4) NOT NULL DEFAULT 0,
risk_budget_contributors jsonb NOT NULL DEFAULT '[]'::jsonb,
staleness_verdict text NOT NULL DEFAULT 'unknown',
staleness_threshold_minutes integer NOT NULL DEFAULT 0,
blocked_items text[] NOT NULL DEFAULT ARRAY[]::text[],
evaluated_by text NOT NULL,
evaluated_at timestamptz NOT NULL,
correlation_key text NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_release_run_gate_decision_ledger_tenant_run
ON release.run_gate_decision_ledger (tenant_id, run_id, evaluated_at DESC, gate_decision_id DESC);
ALTER TABLE release.run_gate_decision_ledger
DROP CONSTRAINT IF EXISTS ck_release_run_gate_decision_ledger_verdict;
ALTER TABLE release.run_gate_decision_ledger
ADD CONSTRAINT ck_release_run_gate_decision_ledger_verdict
CHECK (verdict IN ('allow', 'review', 'block'));
ALTER TABLE release.run_gate_decision_ledger
DROP CONSTRAINT IF EXISTS ck_release_run_gate_decision_ledger_staleness;
ALTER TABLE release.run_gate_decision_ledger
ADD CONSTRAINT ck_release_run_gate_decision_ledger_staleness
CHECK (staleness_verdict IN ('fresh', 'stale', 'unknown'));
ALTER TABLE release.run_gate_decision_ledger
DROP CONSTRAINT IF EXISTS ck_release_run_gate_decision_ledger_threshold;
ALTER TABLE release.run_gate_decision_ledger
ADD CONSTRAINT ck_release_run_gate_decision_ledger_threshold
CHECK (staleness_threshold_minutes >= 0);

View File

@@ -0,0 +1,41 @@
-- SPRINT_20260220_023 / B23-RUN-04
-- Ordered run approval checkpoints with signature and rationale trails.
CREATE TABLE IF NOT EXISTS release.run_approval_checkpoints (
checkpoint_id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
run_id uuid NOT NULL REFERENCES release.control_bundle_materialization_runs(run_id) ON DELETE CASCADE,
checkpoint_order integer NOT NULL,
checkpoint_name text NOT NULL,
required_role text NOT NULL,
status text NOT NULL,
approver_id text NULL,
approved_at timestamptz NULL,
signature_algorithm text NULL,
signature_value text NULL,
rationale text NULL,
evidence_proof_ref text NULL,
correlation_key text NOT NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS ux_release_run_approval_checkpoints_order
ON release.run_approval_checkpoints (tenant_id, run_id, checkpoint_order);
CREATE INDEX IF NOT EXISTS ix_release_run_approval_checkpoints_status
ON release.run_approval_checkpoints (tenant_id, run_id, status, updated_at DESC, checkpoint_order);
ALTER TABLE release.run_approval_checkpoints
DROP CONSTRAINT IF EXISTS ck_release_run_approval_checkpoints_order;
ALTER TABLE release.run_approval_checkpoints
ADD CONSTRAINT ck_release_run_approval_checkpoints_order
CHECK (checkpoint_order > 0);
ALTER TABLE release.run_approval_checkpoints
DROP CONSTRAINT IF EXISTS ck_release_run_approval_checkpoints_status;
ALTER TABLE release.run_approval_checkpoints
ADD CONSTRAINT ck_release_run_approval_checkpoints_status
CHECK (status IN ('pending', 'approved', 'rejected', 'skipped'));

View File

@@ -0,0 +1,55 @@
-- SPRINT_20260220_023 / B23-RUN-05
-- Run deployment phase timeline and rollback trigger/outcome lineage.
CREATE TABLE IF NOT EXISTS release.run_deployment_timeline (
deployment_event_id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
run_id uuid NOT NULL REFERENCES release.control_bundle_materialization_runs(run_id) ON DELETE CASCADE,
target_id text NOT NULL,
target_name text NOT NULL,
target_environment text NOT NULL,
target_region text NOT NULL,
strategy text NOT NULL,
phase text NOT NULL,
status text NOT NULL,
artifact_digest text NULL,
log_ref text NULL,
rollback_trigger_id text NULL,
rollback_outcome text NULL,
occurred_at timestamptz NOT NULL,
correlation_key text NOT NULL
);
CREATE INDEX IF NOT EXISTS ix_release_run_deployment_timeline_run
ON release.run_deployment_timeline (tenant_id, run_id, occurred_at DESC, deployment_event_id DESC);
CREATE INDEX IF NOT EXISTS ix_release_run_deployment_timeline_filters
ON release.run_deployment_timeline (tenant_id, target_environment, target_region, status, occurred_at DESC);
ALTER TABLE release.run_deployment_timeline
DROP CONSTRAINT IF EXISTS ck_release_run_deployment_timeline_strategy;
ALTER TABLE release.run_deployment_timeline
ADD CONSTRAINT ck_release_run_deployment_timeline_strategy
CHECK (strategy IN ('canary', 'rolling', 'blue_green', 'recreate'));
ALTER TABLE release.run_deployment_timeline
DROP CONSTRAINT IF EXISTS ck_release_run_deployment_timeline_phase;
ALTER TABLE release.run_deployment_timeline
ADD CONSTRAINT ck_release_run_deployment_timeline_phase
CHECK (phase IN ('queued', 'precheck', 'deploying', 'verifying', 'completed', 'rollback'));
ALTER TABLE release.run_deployment_timeline
DROP CONSTRAINT IF EXISTS ck_release_run_deployment_timeline_status;
ALTER TABLE release.run_deployment_timeline
ADD CONSTRAINT ck_release_run_deployment_timeline_status
CHECK (status IN ('pending', 'running', 'succeeded', 'failed', 'rolled_back'));
ALTER TABLE release.run_deployment_timeline
DROP CONSTRAINT IF EXISTS ck_release_run_deployment_timeline_rollback_outcome;
ALTER TABLE release.run_deployment_timeline
ADD CONSTRAINT ck_release_run_deployment_timeline_rollback_outcome
CHECK (COALESCE(rollback_outcome, 'none') IN ('none', 'triggered', 'succeeded', 'failed'));

View File

@@ -0,0 +1,48 @@
-- SPRINT_20260220_023 / B23-RUN-06
-- Decision capsule and replay linkage per release run.
CREATE TABLE IF NOT EXISTS release.run_capsule_replay_linkage (
linkage_id uuid PRIMARY KEY,
tenant_id uuid NOT NULL,
run_id uuid NOT NULL REFERENCES release.control_bundle_materialization_runs(run_id) ON DELETE CASCADE,
decision_capsule_id text NOT NULL,
capsule_hash text NOT NULL,
signature_status text NOT NULL,
transparency_receipt text NULL,
replay_verdict text NOT NULL,
replay_match boolean NOT NULL,
replay_mismatch_report_ref text NULL,
replay_checked_at timestamptz NULL,
audit_stream_ref text NULL,
export_profiles text[] NOT NULL DEFAULT ARRAY[]::text[],
correlation_key text NOT NULL,
created_at timestamptz NOT NULL,
updated_at timestamptz NOT NULL
);
CREATE UNIQUE INDEX IF NOT EXISTS ux_release_run_capsule_replay_linkage_run
ON release.run_capsule_replay_linkage (tenant_id, run_id);
CREATE INDEX IF NOT EXISTS ix_release_run_capsule_replay_linkage_verdict
ON release.run_capsule_replay_linkage (tenant_id, replay_verdict, updated_at DESC, linkage_id DESC);
ALTER TABLE release.run_capsule_replay_linkage
DROP CONSTRAINT IF EXISTS ck_release_run_capsule_replay_linkage_signature_status;
ALTER TABLE release.run_capsule_replay_linkage
ADD CONSTRAINT ck_release_run_capsule_replay_linkage_signature_status
CHECK (signature_status IN ('signed', 'unsigned', 'invalid'));
ALTER TABLE release.run_capsule_replay_linkage
DROP CONSTRAINT IF EXISTS ck_release_run_capsule_replay_linkage_replay_verdict;
ALTER TABLE release.run_capsule_replay_linkage
ADD CONSTRAINT ck_release_run_capsule_replay_linkage_replay_verdict
CHECK (replay_verdict IN ('match', 'mismatch', 'not_available'));
ALTER TABLE release.run_capsule_replay_linkage
DROP CONSTRAINT IF EXISTS ck_release_run_capsule_replay_linkage_mismatch_report;
ALTER TABLE release.run_capsule_replay_linkage
ADD CONSTRAINT ck_release_run_capsule_replay_linkage_mismatch_report
CHECK (replay_verdict <> 'mismatch' OR replay_mismatch_report_ref IS NOT NULL);

View File

@@ -4,5 +4,10 @@ Source of truth: `docs/implplan/SPRINT_20260130_002_Tools_csproj_remediation_sol
| Task ID | Status | Notes |
| --- | --- | --- |
| B22-01-DB | DONE | Sprint `docs/implplan/SPRINT_20260220_018_Platform_pack22_backend_contracts_and_migrations.md`: added release migration `047_GlobalContextAndFilters.sql` with `platform.context_regions`, `platform.context_environments`, and `platform.ui_context_preferences`. |
| B22-02-DB | DONE | Sprint `docs/implplan/SPRINT_20260220_018_Platform_pack22_backend_contracts_and_migrations.md`: added release migration `048_ReleaseReadModels.sql` with release list/activity/approvals projection tables, correlation keys, and deterministic ordering indexes. |
| B22-03-DB | DONE | Sprint `docs/implplan/SPRINT_20260220_018_Platform_pack22_backend_contracts_and_migrations.md`: added release migration `049_TopologyInventory.sql` with normalized topology inventory projection tables and sync-watermark indexes. |
| B22-04-DB | DONE | Sprint `docs/implplan/SPRINT_20260220_018_Platform_pack22_backend_contracts_and_migrations.md`: added release migration `050_SecurityDispositionProjection.sql` with consolidated findings/disposition/SBOM read-model projection tables, filters, and enum constraints. |
| B22-05-DB | DONE | Sprint `docs/implplan/SPRINT_20260220_018_Platform_pack22_backend_contracts_and_migrations.md`: added release migration `051_IntegrationSourceHealth.sql` for integrations feed and VEX source health/freshness read-model projection objects. |
| REMED-05 | TODO | Remediation checklist: docs/implplan/audits/csproj-standards/remediation/checklists/src/Platform/__Libraries/StellaOps.Platform.Database/StellaOps.Platform.Database.md. |
| REMED-06 | DONE | SOLID review notes captured for SPRINT_20260130_002. |