Files
Investidor-V2/database/migrations/2026_09_24_005000_investmoz_clusters.php
T
nala 250ac35fd1
tests / ci (push) Canceled after 0s
first commit
2026-09-28 10:01:09 +02:00

313 lines
13 KiB
PHP

<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
return new class extends Migration
{
// Laravel's migration ledger provides idempotency; object drift fails explicitly.
public function up(): void
{
if (DB::connection()->getDriverName() !== 'pgsql') {
throw new RuntimeException('InvestMoz requires PostgreSQL with PostGIS. Use the isolated pgsql test environment.');
}
DB::statement(<<<'SQL'
CREATE TABLE public.economic_clusters (
id uuid DEFAULT gen_random_uuid() NOT NULL,
source_system text NOT NULL DEFAULT 'investmoz',
external_id text,
version_no integer NOT NULL DEFAULT 1,
data_classification text NOT NULL DEFAULT 'internal',
correlation_id uuid,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz,
code text NOT NULL,
name text NOT NULL,
sector text NOT NULL,
status text NOT NULL,
metadata jsonb NOT NULL DEFAULT '{}'::jsonb,
CONSTRAINT imz_economic_clusters_pk PRIMARY KEY (id),
CONSTRAINT imz_economic_clusters_check_01 CHECK (version_no > 0),
CONSTRAINT imz_economic_clusters_check_02 CHECK (data_classification IN ('public','internal','confidential','restricted')),
CONSTRAINT imz_economic_clusters_check_03 CHECK (status IN ('planned','active','inactive'))
);
SQL);
DB::statement(<<<'SQL'
CREATE TABLE public.value_chains (
id uuid DEFAULT gen_random_uuid() NOT NULL,
source_system text NOT NULL DEFAULT 'investmoz',
external_id text,
version_no integer NOT NULL DEFAULT 1,
data_classification text NOT NULL DEFAULT 'internal',
correlation_id uuid,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz,
cluster_id uuid NOT NULL CONSTRAINT imz_value_chains_cluster_id_fk REFERENCES public.economic_clusters(id) ON DELETE CASCADE ON UPDATE CASCADE,
code text NOT NULL,
name text NOT NULL,
stage text NOT NULL,
CONSTRAINT imz_value_chains_pk PRIMARY KEY (id),
CONSTRAINT imz_value_chains_check_01 CHECK (version_no > 0),
CONSTRAINT imz_value_chains_check_02 CHECK (data_classification IN ('public','internal','confidential','restricted')),
CONSTRAINT imz_value_chains_check_03 CHECK (stage IN ('input','production','processing','logistics','market'))
);
SQL);
DB::statement(<<<'SQL'
CREATE TABLE public.value_chain_links (
id uuid DEFAULT gen_random_uuid() NOT NULL,
source_system text NOT NULL DEFAULT 'investmoz',
external_id text,
version_no integer NOT NULL DEFAULT 1,
data_classification text NOT NULL DEFAULT 'internal',
correlation_id uuid,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz,
from_value_chain_id uuid NOT NULL CONSTRAINT imz_value_chain_links_from_value_chain_id_fk REFERENCES public.value_chains(id) ON DELETE CASCADE ON UPDATE CASCADE,
to_value_chain_id uuid NOT NULL CONSTRAINT imz_value_chain_links_to_value_chain_id_fk REFERENCES public.value_chains(id) ON DELETE CASCADE ON UPDATE CASCADE,
link_type text NOT NULL,
CONSTRAINT imz_value_chain_links_pk PRIMARY KEY (id),
CONSTRAINT imz_value_chain_links_check_01 CHECK (version_no > 0),
CONSTRAINT imz_value_chain_links_check_02 CHECK (data_classification IN ('public','internal','confidential','restricted')),
CONSTRAINT imz_value_chain_links_check_03 CHECK (link_type IN ('supplies','processes','distributes','supports')),
CONSTRAINT imz_value_chain_links_check_04 CHECK (from_value_chain_id <> to_value_chain_id)
);
SQL);
DB::statement(<<<'SQL'
CREATE TABLE public.cluster_projects (
id uuid DEFAULT gen_random_uuid() NOT NULL,
source_system text NOT NULL DEFAULT 'investmoz',
external_id text,
version_no integer NOT NULL DEFAULT 1,
data_classification text NOT NULL DEFAULT 'internal',
correlation_id uuid,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz,
cluster_id uuid NOT NULL CONSTRAINT imz_cluster_projects_cluster_id_fk REFERENCES public.economic_clusters(id) ON DELETE CASCADE ON UPDATE CASCADE,
project_id uuid NOT NULL CONSTRAINT imz_cluster_projects_project_id_fk REFERENCES public.projects(id) ON DELETE CASCADE ON UPDATE CASCADE,
role text NOT NULL,
CONSTRAINT imz_cluster_projects_pk PRIMARY KEY (id),
CONSTRAINT imz_cluster_projects_check_01 CHECK (version_no > 0),
CONSTRAINT imz_cluster_projects_check_02 CHECK (data_classification IN ('public','internal','confidential','restricted')),
CONSTRAINT imz_cluster_projects_check_03 CHECK (role IN ('anchor','complementary','supporting'))
);
SQL);
DB::statement(<<<'SQL'
CREATE TABLE public.anchor_project_links (
id uuid DEFAULT gen_random_uuid() NOT NULL,
source_system text NOT NULL DEFAULT 'investmoz',
external_id text,
version_no integer NOT NULL DEFAULT 1,
data_classification text NOT NULL DEFAULT 'internal',
correlation_id uuid,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz,
anchor_project_id uuid NOT NULL CONSTRAINT imz_anchor_project_links_anchor_project_id_fk REFERENCES public.projects(id) ON DELETE CASCADE ON UPDATE CASCADE,
cluster_id uuid NOT NULL CONSTRAINT imz_anchor_project_links_cluster_id_fk REFERENCES public.economic_clusters(id) ON DELETE CASCADE ON UPDATE CASCADE,
rationale text NOT NULL,
CONSTRAINT imz_anchor_project_links_pk PRIMARY KEY (id),
CONSTRAINT imz_anchor_project_links_check_01 CHECK (version_no > 0),
CONSTRAINT imz_anchor_project_links_check_02 CHECK (data_classification IN ('public','internal','confidential','restricted'))
);
SQL);
DB::statement(<<<'SQL'
CREATE TABLE public.complementary_project_links (
id uuid DEFAULT gen_random_uuid() NOT NULL,
source_system text NOT NULL DEFAULT 'investmoz',
external_id text,
version_no integer NOT NULL DEFAULT 1,
data_classification text NOT NULL DEFAULT 'internal',
correlation_id uuid,
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
deleted_at timestamptz,
anchor_project_id uuid NOT NULL CONSTRAINT imz_complementary_project_links_anchor_project_id_fk REFERENCES public.projects(id) ON DELETE CASCADE ON UPDATE CASCADE,
complementary_project_id uuid NOT NULL CONSTRAINT imz_complementary_project_links_complementary_project_id_fk REFERENCES public.projects(id) ON DELETE CASCADE ON UPDATE CASCADE,
relation_type text NOT NULL,
CONSTRAINT imz_complementary_project_links_pk PRIMARY KEY (id),
CONSTRAINT imz_complementary_project_links_check_01 CHECK (version_no > 0),
CONSTRAINT imz_complementary_project_links_check_02 CHECK (data_classification IN ('public','internal','confidential','restricted')),
CONSTRAINT imz_complementary_project_links_check_03 CHECK (relation_type IN ('dependency','enabler','supplier','market')),
CONSTRAINT imz_complementary_project_links_check_04 CHECK (anchor_project_id<>complementary_project_id)
);
SQL);
}
public function down(): void
{
if (DB::connection()->getDriverName() !== 'pgsql') {
throw new RuntimeException('InvestMoz rollback requires PostgreSQL.');
}
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.complementary_project_links DROP CONSTRAINT IF EXISTS imz_complementary_project_links_anchor_project_id_fk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.complementary_project_links DROP CONSTRAINT IF EXISTS imz_complementary_project_links_complementary_project_id_fk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.complementary_project_links DROP CONSTRAINT IF EXISTS imz_complementary_project_links_pk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.complementary_project_links DROP CONSTRAINT IF EXISTS imz_complementary_project_links_check_01 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.complementary_project_links DROP CONSTRAINT IF EXISTS imz_complementary_project_links_check_02 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.complementary_project_links DROP CONSTRAINT IF EXISTS imz_complementary_project_links_check_03 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.complementary_project_links DROP CONSTRAINT IF EXISTS imz_complementary_project_links_check_04 RESTRICT;
SQL);
DB::statement(<<<'SQL'
DROP TABLE IF EXISTS public.complementary_project_links RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.anchor_project_links DROP CONSTRAINT IF EXISTS imz_anchor_project_links_anchor_project_id_fk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.anchor_project_links DROP CONSTRAINT IF EXISTS imz_anchor_project_links_cluster_id_fk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.anchor_project_links DROP CONSTRAINT IF EXISTS imz_anchor_project_links_pk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.anchor_project_links DROP CONSTRAINT IF EXISTS imz_anchor_project_links_check_01 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.anchor_project_links DROP CONSTRAINT IF EXISTS imz_anchor_project_links_check_02 RESTRICT;
SQL);
DB::statement(<<<'SQL'
DROP TABLE IF EXISTS public.anchor_project_links RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.cluster_projects DROP CONSTRAINT IF EXISTS imz_cluster_projects_cluster_id_fk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.cluster_projects DROP CONSTRAINT IF EXISTS imz_cluster_projects_project_id_fk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.cluster_projects DROP CONSTRAINT IF EXISTS imz_cluster_projects_pk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.cluster_projects DROP CONSTRAINT IF EXISTS imz_cluster_projects_check_01 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.cluster_projects DROP CONSTRAINT IF EXISTS imz_cluster_projects_check_02 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.cluster_projects DROP CONSTRAINT IF EXISTS imz_cluster_projects_check_03 RESTRICT;
SQL);
DB::statement(<<<'SQL'
DROP TABLE IF EXISTS public.cluster_projects RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chain_links DROP CONSTRAINT IF EXISTS imz_value_chain_links_from_value_chain_id_fk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chain_links DROP CONSTRAINT IF EXISTS imz_value_chain_links_to_value_chain_id_fk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chain_links DROP CONSTRAINT IF EXISTS imz_value_chain_links_pk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chain_links DROP CONSTRAINT IF EXISTS imz_value_chain_links_check_01 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chain_links DROP CONSTRAINT IF EXISTS imz_value_chain_links_check_02 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chain_links DROP CONSTRAINT IF EXISTS imz_value_chain_links_check_03 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chain_links DROP CONSTRAINT IF EXISTS imz_value_chain_links_check_04 RESTRICT;
SQL);
DB::statement(<<<'SQL'
DROP TABLE IF EXISTS public.value_chain_links RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chains DROP CONSTRAINT IF EXISTS imz_value_chains_cluster_id_fk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chains DROP CONSTRAINT IF EXISTS imz_value_chains_pk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chains DROP CONSTRAINT IF EXISTS imz_value_chains_check_01 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chains DROP CONSTRAINT IF EXISTS imz_value_chains_check_02 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.value_chains DROP CONSTRAINT IF EXISTS imz_value_chains_check_03 RESTRICT;
SQL);
DB::statement(<<<'SQL'
DROP TABLE IF EXISTS public.value_chains RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.economic_clusters DROP CONSTRAINT IF EXISTS imz_economic_clusters_pk RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.economic_clusters DROP CONSTRAINT IF EXISTS imz_economic_clusters_check_01 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.economic_clusters DROP CONSTRAINT IF EXISTS imz_economic_clusters_check_02 RESTRICT;
SQL);
DB::statement(<<<'SQL'
ALTER TABLE IF EXISTS public.economic_clusters DROP CONSTRAINT IF EXISTS imz_economic_clusters_check_03 RESTRICT;
SQL);
DB::statement(<<<'SQL'
DROP TABLE IF EXISTS public.economic_clusters RESTRICT;
SQL);
}
};