ui progressing
This commit is contained in:
@@ -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;
|
||||
@@ -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'));
|
||||
@@ -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'));
|
||||
@@ -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'));
|
||||
@@ -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'));
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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'));
|
||||
@@ -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'));
|
||||
@@ -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);
|
||||
@@ -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. |
|
||||
|
||||
Reference in New Issue
Block a user