301 lines
12 KiB
PL/PgSQL
301 lines
12 KiB
PL/PgSQL
-- ============================================================
|
|
-- HMM demo carrier performance source data for PostgreSQL.
|
|
--
|
|
-- Target: AWS RDS for PostgreSQL, database postgres
|
|
-- Schema: hmm_demo
|
|
-- Redmine: #729
|
|
--
|
|
-- This script is idempotent. It owns only C001..C008 and their
|
|
-- 2025-02 through 2026-07 monthly demo rows. It never stores an
|
|
-- RDS endpoint, password, or certificate path.
|
|
--
|
|
-- Example:
|
|
-- PGPASSWORD="$PG_PASSWORD" psql \
|
|
-- "host=$PG_HOST port=5432 dbname=postgres user=$PG_USER \
|
|
-- sslmode=verify-full sslrootcert=$PG_SSL_ROOT_CERT" \
|
|
-- -X -f sql/source/postgres_hmm_carrier_performance.sql
|
|
-- ============================================================
|
|
|
|
\set ON_ERROR_STOP on
|
|
\echo === HMM carrier performance demo: begin ===
|
|
|
|
BEGIN;
|
|
|
|
CREATE SCHEMA IF NOT EXISTS hmm_demo AUTHORIZATION postgres;
|
|
COMMENT ON SCHEMA hmm_demo IS
|
|
'HMM federation demonstration data. All carrier names and KPI values are fictional.';
|
|
|
|
REVOKE CREATE ON SCHEMA hmm_demo FROM PUBLIC;
|
|
|
|
CREATE TABLE IF NOT EXISTS hmm_demo.carriers (
|
|
carrier_code VARCHAR(10) PRIMARY KEY,
|
|
carrier_name VARCHAR(120) NOT NULL UNIQUE,
|
|
country_code CHAR(2) NOT NULL CHECK (country_code ~ '^[A-Z]{2}$'),
|
|
alliance_name VARCHAR(80),
|
|
service_region VARCHAR(40) NOT NULL,
|
|
performance_tier VARCHAR(10) NOT NULL
|
|
CHECK (performance_tier IN ('CORE', 'GROWTH', 'WATCH')),
|
|
active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT CURRENT_TIMESTAMP
|
|
);
|
|
|
|
COMMENT ON TABLE hmm_demo.carriers IS
|
|
'Fictional carrier master data for the HMM ADB and PostgreSQL federation demo.';
|
|
COMMENT ON COLUMN hmm_demo.carriers.carrier_code IS 'Fictional carrier identifier.';
|
|
COMMENT ON COLUMN hmm_demo.carriers.performance_tier IS
|
|
'Demo portfolio tier: CORE, GROWTH, or WATCH.';
|
|
|
|
CREATE TABLE IF NOT EXISTS hmm_demo.carrier_monthly_performance (
|
|
carrier_code VARCHAR(10) NOT NULL
|
|
REFERENCES hmm_demo.carriers (carrier_code),
|
|
performance_month DATE NOT NULL
|
|
CHECK (performance_month = date_trunc('month', performance_month)::DATE),
|
|
contracted_teu INTEGER NOT NULL CHECK (contracted_teu >= 0),
|
|
shipped_teu INTEGER NOT NULL CHECK (shipped_teu >= 0),
|
|
revenue_usd NUMERIC(16,2) NOT NULL CHECK (revenue_usd >= 0),
|
|
gross_margin_usd NUMERIC(16,2) NOT NULL,
|
|
schedule_reliability_pct NUMERIC(5,2) NOT NULL
|
|
CHECK (schedule_reliability_pct BETWEEN 0 AND 100),
|
|
vessel_utilization_pct NUMERIC(5,2) NOT NULL
|
|
CHECK (vessel_utilization_pct BETWEEN 0 AND 100),
|
|
claim_rate_pct NUMERIC(5,2) NOT NULL
|
|
CHECK (claim_rate_pct BETWEEN 0 AND 100),
|
|
yoy_growth_pct NUMERIC(7,2) NOT NULL,
|
|
risk_level VARCHAR(10) NOT NULL
|
|
CHECK (risk_level IN ('GREEN', 'AMBER', 'RED')),
|
|
updated_at TIMESTAMPTZ NOT NULL,
|
|
PRIMARY KEY (carrier_code, performance_month)
|
|
);
|
|
|
|
COMMENT ON TABLE hmm_demo.carrier_monthly_performance IS
|
|
'Deterministic fictional monthly carrier KPIs for 2025-02 through 2026-07.';
|
|
COMMENT ON COLUMN hmm_demo.carrier_monthly_performance.performance_month IS
|
|
'First calendar day of the KPI month.';
|
|
COMMENT ON COLUMN hmm_demo.carrier_monthly_performance.risk_level IS
|
|
'Derived demo risk level based on margin, reliability, and claim rate.';
|
|
|
|
CREATE INDEX IF NOT EXISTS ix_carrier_perf_month
|
|
ON hmm_demo.carrier_monthly_performance (performance_month, carrier_code);
|
|
CREATE INDEX IF NOT EXISTS ix_carrier_perf_risk
|
|
ON hmm_demo.carrier_monthly_performance (risk_level, performance_month);
|
|
|
|
INSERT INTO hmm_demo.carriers (
|
|
carrier_code,
|
|
carrier_name,
|
|
country_code,
|
|
alliance_name,
|
|
service_region,
|
|
performance_tier,
|
|
active
|
|
) VALUES
|
|
('C001', 'Bluewave Maritime', 'SG', 'North Pacific Network', 'ASIA-PACIFIC', 'CORE', TRUE),
|
|
('C002', 'Pacific Star Lines', 'JP', 'East Ocean Connect', 'ASIA-PACIFIC', 'CORE', TRUE),
|
|
('C003', 'Korea Ocean Link', 'KR', 'East Ocean Connect', 'ASIA-PACIFIC', 'GROWTH', TRUE),
|
|
('C004', 'Nordic Seaways', 'DK', 'Northern Trade Group', 'EUROPE', 'CORE', TRUE),
|
|
('C005', 'Orient Bridge Shipping', 'TW', 'North Pacific Network', 'ASIA-PACIFIC', 'WATCH', TRUE),
|
|
('C006', 'Atlantic Merchant Line', 'DE', 'Atlantic Cargo Forum', 'EUROPE-AMERICAS', 'WATCH', TRUE),
|
|
('C007', 'Global Horizon Cargo', 'US', 'Atlantic Cargo Forum', 'AMERICAS', 'GROWTH', TRUE),
|
|
('C008', 'Southern Cross Marine', 'FR', 'Southern Ocean Group', 'OCEANIA', 'WATCH', TRUE)
|
|
ON CONFLICT (carrier_code) DO UPDATE SET
|
|
carrier_name = EXCLUDED.carrier_name,
|
|
country_code = EXCLUDED.country_code,
|
|
alliance_name = EXCLUDED.alliance_name,
|
|
service_region = EXCLUDED.service_region,
|
|
performance_tier = EXCLUDED.performance_tier,
|
|
active = EXCLUDED.active;
|
|
|
|
WITH month_series AS (
|
|
SELECT
|
|
month_index,
|
|
(DATE '2025-02-01' + make_interval(months => month_index))::DATE AS performance_month,
|
|
CASE month_index % 6
|
|
WHEN 0 THEN -1
|
|
WHEN 1 THEN 0
|
|
WHEN 2 THEN 1
|
|
WHEN 3 THEN 2
|
|
WHEN 4 THEN 1
|
|
ELSE -1
|
|
END::NUMERIC AS seasonal_factor
|
|
FROM generate_series(0, 17) AS series(month_index)
|
|
),
|
|
profiles (
|
|
carrier_code,
|
|
base_teu,
|
|
monthly_teu_step,
|
|
seasonal_teu,
|
|
utilization_base,
|
|
utilization_step,
|
|
revenue_per_teu,
|
|
revenue_step,
|
|
margin_pct_base,
|
|
margin_pct_step,
|
|
reliability_base,
|
|
reliability_step,
|
|
claim_rate_base,
|
|
claim_rate_step,
|
|
yoy_growth_base,
|
|
yoy_growth_step
|
|
) AS (
|
|
VALUES
|
|
('C001', 1800::NUMERIC, 25::NUMERIC, 80::NUMERIC, 91.5::NUMERIC, 0.10::NUMERIC, 1850::NUMERIC, 4::NUMERIC, 15.0::NUMERIC, 0.10::NUMERIC, 95.0::NUMERIC, 0.05::NUMERIC, 0.35::NUMERIC, -0.005::NUMERIC, 8.0::NUMERIC, 0.25::NUMERIC),
|
|
('C002', 1500::NUMERIC, 5::NUMERIC, 60::NUMERIC, 88.5::NUMERIC, 0.02::NUMERIC, 1780::NUMERIC, 3::NUMERIC, 12.0::NUMERIC, 0.00::NUMERIC, 92.5::NUMERIC, 0.00::NUMERIC, 0.45::NUMERIC, 0.005::NUMERIC, 3.0::NUMERIC, 0.05::NUMERIC),
|
|
('C003', 1050::NUMERIC, 15::NUMERIC, 50::NUMERIC, 83.0::NUMERIC, 0.20::NUMERIC, 1920::NUMERIC, 2::NUMERIC, 8.0::NUMERIC, 0.15::NUMERIC, 88.5::NUMERIC, 0.25::NUMERIC, 1.20::NUMERIC, -0.040::NUMERIC, -4.0::NUMERIC, 0.60::NUMERIC),
|
|
('C004', 1350::NUMERIC, 0::NUMERIC, 180::NUMERIC, 86.0::NUMERIC, 0.00::NUMERIC, 1810::NUMERIC, 3::NUMERIC, 10.0::NUMERIC, 0.00::NUMERIC, 93.0::NUMERIC, 0.00::NUMERIC, 0.55::NUMERIC, 0.010::NUMERIC, 1.0::NUMERIC, 0.10::NUMERIC),
|
|
('C005', 1300::NUMERIC, -20::NUMERIC, 70::NUMERIC, 88.0::NUMERIC, -0.10::NUMERIC, 1850::NUMERIC, -2::NUMERIC, 8.0::NUMERIC, -0.20::NUMERIC, 91.0::NUMERIC, -0.15::NUMERIC, 0.80::NUMERIC, 0.030::NUMERIC, -2.0::NUMERIC, -0.50::NUMERIC),
|
|
('C006', 1250::NUMERIC, -10::NUMERIC, 90::NUMERIC, 84.0::NUMERIC, -0.12::NUMERIC, 1800::NUMERIC, -3::NUMERIC, 6.0::NUMERIC, -0.15::NUMERIC, 87.0::NUMERIC, -0.25::NUMERIC, 1.50::NUMERIC, 0.050::NUMERIC, -5.0::NUMERIC, -0.70::NUMERIC),
|
|
('C007', 800::NUMERIC, 30::NUMERIC, 100::NUMERIC, 82.0::NUMERIC, 0.25::NUMERIC, 2050::NUMERIC, 5::NUMERIC, 9.0::NUMERIC, 0.18::NUMERIC, 90.5::NUMERIC, 0.15::NUMERIC, 0.70::NUMERIC, -0.020::NUMERIC, 12.0::NUMERIC, 0.50::NUMERIC),
|
|
('C008', 1150::NUMERIC, -25::NUMERIC, 60::NUMERIC, 80.0::NUMERIC, -0.15::NUMERIC, 1750::NUMERIC, -4::NUMERIC, 3.0::NUMERIC, -0.20::NUMERIC, 85.0::NUMERIC, -0.30::NUMERIC, 2.00::NUMERIC, 0.080::NUMERIC, -8.0::NUMERIC, -0.80::NUMERIC)
|
|
),
|
|
base_metrics AS (
|
|
SELECT
|
|
p.carrier_code,
|
|
m.performance_month,
|
|
ROUND(
|
|
p.base_teu
|
|
+ p.monthly_teu_step * m.month_index
|
|
+ p.seasonal_teu * m.seasonal_factor
|
|
)::INTEGER AS contracted_teu,
|
|
LEAST(
|
|
98.0::NUMERIC,
|
|
GREATEST(
|
|
60.0::NUMERIC,
|
|
p.utilization_base
|
|
+ p.utilization_step * m.month_index
|
|
+ m.seasonal_factor * 0.50
|
|
)
|
|
) AS utilization_pct,
|
|
p.revenue_per_teu + p.revenue_step * m.month_index AS unit_revenue,
|
|
p.margin_pct_base + p.margin_pct_step * m.month_index AS margin_pct,
|
|
LEAST(
|
|
99.5::NUMERIC,
|
|
GREATEST(
|
|
60.0::NUMERIC,
|
|
p.reliability_base
|
|
+ p.reliability_step * m.month_index
|
|
+ m.seasonal_factor * 0.20
|
|
)
|
|
) AS reliability_pct,
|
|
LEAST(
|
|
100.0::NUMERIC,
|
|
GREATEST(
|
|
0.0::NUMERIC,
|
|
p.claim_rate_base + p.claim_rate_step * m.month_index
|
|
)
|
|
) AS claim_pct,
|
|
p.yoy_growth_base + p.yoy_growth_step * m.month_index AS yoy_pct
|
|
FROM profiles p
|
|
CROSS JOIN month_series m
|
|
),
|
|
volume_metrics AS (
|
|
SELECT
|
|
b.*,
|
|
ROUND(b.contracted_teu * b.utilization_pct / 100.0)::INTEGER AS shipped_teu
|
|
FROM base_metrics b
|
|
),
|
|
financial_metrics AS (
|
|
SELECT
|
|
v.*,
|
|
ROUND(v.shipped_teu * v.unit_revenue, 2) AS revenue_usd
|
|
FROM volume_metrics v
|
|
),
|
|
final_metrics AS (
|
|
SELECT
|
|
f.*,
|
|
ROUND(f.revenue_usd * f.margin_pct / 100.0, 2) AS gross_margin_usd
|
|
FROM financial_metrics f
|
|
)
|
|
INSERT INTO hmm_demo.carrier_monthly_performance (
|
|
carrier_code,
|
|
performance_month,
|
|
contracted_teu,
|
|
shipped_teu,
|
|
revenue_usd,
|
|
gross_margin_usd,
|
|
schedule_reliability_pct,
|
|
vessel_utilization_pct,
|
|
claim_rate_pct,
|
|
yoy_growth_pct,
|
|
risk_level,
|
|
updated_at
|
|
)
|
|
SELECT
|
|
f.carrier_code,
|
|
f.performance_month,
|
|
f.contracted_teu,
|
|
f.shipped_teu,
|
|
f.revenue_usd,
|
|
f.gross_margin_usd,
|
|
ROUND(f.reliability_pct, 2),
|
|
ROUND(f.utilization_pct, 2),
|
|
ROUND(f.claim_pct, 2),
|
|
ROUND(f.yoy_pct, 2),
|
|
CASE
|
|
WHEN f.gross_margin_usd < 0
|
|
OR f.reliability_pct < 87
|
|
OR f.claim_pct >= 2 THEN 'RED'
|
|
WHEN f.margin_pct < 7
|
|
OR f.reliability_pct < 92
|
|
OR f.claim_pct >= 1 THEN 'AMBER'
|
|
ELSE 'GREEN'
|
|
END,
|
|
TIMESTAMPTZ '2026-07-24 00:00:00+00'
|
|
FROM final_metrics f
|
|
ON CONFLICT (carrier_code, performance_month) DO UPDATE SET
|
|
contracted_teu = EXCLUDED.contracted_teu,
|
|
shipped_teu = EXCLUDED.shipped_teu,
|
|
revenue_usd = EXCLUDED.revenue_usd,
|
|
gross_margin_usd = EXCLUDED.gross_margin_usd,
|
|
schedule_reliability_pct = EXCLUDED.schedule_reliability_pct,
|
|
vessel_utilization_pct = EXCLUDED.vessel_utilization_pct,
|
|
claim_rate_pct = EXCLUDED.claim_rate_pct,
|
|
yoy_growth_pct = EXCLUDED.yoy_growth_pct,
|
|
risk_level = EXCLUDED.risk_level,
|
|
updated_at = EXCLUDED.updated_at;
|
|
|
|
CREATE OR REPLACE VIEW hmm_demo.carrier_performance_latest_v AS
|
|
SELECT
|
|
c.carrier_code,
|
|
c.carrier_name,
|
|
c.country_code,
|
|
c.alliance_name,
|
|
c.service_region,
|
|
c.performance_tier,
|
|
p.performance_month,
|
|
p.contracted_teu,
|
|
p.shipped_teu,
|
|
p.revenue_usd,
|
|
p.gross_margin_usd,
|
|
p.schedule_reliability_pct,
|
|
p.vessel_utilization_pct,
|
|
p.claim_rate_pct,
|
|
p.yoy_growth_pct,
|
|
p.risk_level
|
|
FROM hmm_demo.carriers c
|
|
JOIN hmm_demo.carrier_monthly_performance p
|
|
ON p.carrier_code = c.carrier_code
|
|
WHERE p.performance_month = (
|
|
SELECT MAX(latest.performance_month)
|
|
FROM hmm_demo.carrier_monthly_performance latest
|
|
);
|
|
|
|
COMMENT ON VIEW hmm_demo.carrier_performance_latest_v IS
|
|
'Latest fictional monthly KPI for each active demo carrier.';
|
|
|
|
DO $role$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'hmm_federation_reader') THEN
|
|
CREATE ROLE hmm_federation_reader NOLOGIN;
|
|
END IF;
|
|
END
|
|
$role$;
|
|
|
|
GRANT USAGE ON SCHEMA hmm_demo TO hmm_federation_reader;
|
|
GRANT SELECT ON ALL TABLES IN SCHEMA hmm_demo TO hmm_federation_reader;
|
|
ALTER DEFAULT PRIVILEGES IN SCHEMA hmm_demo
|
|
GRANT SELECT ON TABLES TO hmm_federation_reader;
|
|
|
|
COMMIT;
|
|
|
|
\echo === HMM carrier performance demo: complete ===
|
|
\echo Next: run sql/source/postgres_hmm_carrier_performance_verify.sql
|