CREATE TABLE skills_edu.program_details ( id uuid PRIMARY KEY REFERENCES public.courses(id) ON DELETE RESTRICT, title_en varchar(255), study_area varchar(255), qualification_level varchar(100), duration_value integer CHECK (duration_value IS NULL OR duration_value > 0), duration_unit varchar(20), delivery_mode varchar(20) CHECK (delivery_mode IS NULL OR delivery_mode IN ('in_person','hybrid','distance')), capacity integer CHECK (capacity IS NULL OR capacity >= 0), available_places integer CHECK (available_places IS NULL OR available_places >= 0), cost_amount numeric(18,2) CHECK (cost_amount IS NULL OR cost_amount >= 0), currency char(3), location_master_id uuid, accreditation_status varchar(30) NOT NULL DEFAULT 'declared' CHECK (accreditation_status IN ('declared','in_validation','confirmed','expired','not_accredited')), accrediting_authority varchar(255), accreditation_valid_until date, source_name varchar(255), created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), deleted_at timestamptz, CHECK (available_places IS NULL OR capacity IS NULL OR available_places <= capacity) ); CREATE TABLE skills_edu.education_program_skills ( program_id uuid NOT NULL REFERENCES public.courses(id) ON DELETE CASCADE, skill_id uuid NOT NULL REFERENCES public.skills(id) ON DELETE RESTRICT, target_level varchar(30), verification_status varchar(20) NOT NULL DEFAULT 'declared' CHECK (verification_status IN ('declared','validated','rejected')), PRIMARY KEY (program_id, skill_id) ); CREATE TABLE skills_edu.skill_gaps ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), skill_id uuid NOT NULL REFERENCES public.skills(id) ON DELETE RESTRICT, occupation_id uuid REFERENCES public.occupations(id) ON DELETE SET NULL, cluster_master_id uuid, corridor_master_id uuid, project_master_id uuid, location_master_id uuid, period_start date NOT NULL, period_end date, demand_quantity numeric(18,2) NOT NULL DEFAULT 0, supply_quantity numeric(18,2) NOT NULL DEFAULT 0, gap_quantity numeric(18,2) GENERATED ALWAYS AS (demand_quantity - supply_quantity) STORED, criticality varchar(20) CHECK (criticality IS NULL OR criticality IN ('low','medium','high','critical')), evidence jsonb NOT NULL DEFAULT '{}'::jsonb, validation_status varchar(20) NOT NULL DEFAULT 'draft' CHECK (validation_status IN ('draft','in_validation','validated','rejected')), responsible_user_id bigint, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), CHECK (period_end IS NULL OR period_end >= period_start) ); CREATE TABLE skills_edu.educational_opportunity_details ( id uuid PRIMARY KEY REFERENCES public.education_investment_proposals(id) ON DELETE RESTRICT, gap_id uuid REFERENCES skills_edu.skill_gaps(id) ON DELETE SET NULL, title_en varchar(255), opportunity_type varchar(40) NOT NULL CHECK (opportunity_type IN ('new_course','course_expansion','training_centre','laboratory','internship','apprenticeship','upskilling','reskilling','trainer_training','certification_support','digital_learning','infrastructure','scholarship_fund','partnership','other')), description_en text, target_audience text, required_capacity integer CHECK (required_capacity IS NULL OR required_capacity > 0), cluster_master_id uuid, corridor_master_id uuid, project_master_id uuid, zee_master_id uuid, zfi_master_id uuid, location_master_id uuid, investment_mode varchar(100), maturity varchar(30), risks jsonb NOT NULL DEFAULT '[]'::jsonb, source_records jsonb NOT NULL DEFAULT '[]'::jsonb, visibility_level varchar(20) NOT NULL DEFAULT 'private' CHECK (visibility_level IN ('private','validated_users','public_summary')), valid_until date, created_by bigint NOT NULL, updated_by bigint, created_at timestamptz NOT NULL DEFAULT now(), updated_at timestamptz NOT NULL DEFAULT now(), deleted_at timestamptz ); CREATE TABLE skills_edu.educational_opportunity_skills ( opportunity_id uuid NOT NULL REFERENCES skills_edu.educational_opportunity_details(id) ON DELETE CASCADE, skill_id uuid NOT NULL REFERENCES public.skills(id) ON DELETE RESTRICT, target_level varchar(30), PRIMARY KEY (opportunity_id, skill_id) ); CREATE TABLE skills_edu.profile_need_matches ( id uuid PRIMARY KEY DEFAULT gen_random_uuid(), profile_id uuid NOT NULL REFERENCES skills_edu.professional_profiles(id) ON DELETE CASCADE, need_id uuid NOT NULL REFERENCES skills_edu.human_resource_need_details(id) ON DELETE CASCADE, rule_version varchar(50) NOT NULL, score numeric(5,2) CHECK (score IS NULL OR score BETWEEN 0 AND 100), required_conditions_met boolean NOT NULL DEFAULT false, matched_skills jsonb NOT NULL DEFAULT '[]'::jsonb, skill_gaps jsonb NOT NULL DEFAULT '[]'::jsonb, explanation jsonb NOT NULL DEFAULT '{}'::jsonb, confidence_level varchar(20) CHECK (confidence_level IS NULL OR confidence_level IN ('low','medium','high')), review_status varchar(20) NOT NULL DEFAULT 'pending' CHECK (review_status IN ('pending','approved','rejected','contested')), reviewed_by bigint, reviewed_at timestamptz, created_at timestamptz NOT NULL DEFAULT now(), UNIQUE (profile_id, need_id, rule_version) ); CREATE INDEX idx_skill_gaps_context ON skills_edu.skill_gaps(skill_id,cluster_master_id,corridor_master_id,project_master_id,validation_status); CREATE INDEX idx_matches_need_score ON skills_edu.profile_need_matches(need_id,required_conditions_met,score DESC); ALTER TABLE skills_edu.program_details ADD FOREIGN KEY (location_master_id) REFERENCES public.geo_locations(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.skill_gaps ADD FOREIGN KEY (responsible_user_id) REFERENCES public.users(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.skill_gaps ADD FOREIGN KEY (project_master_id) REFERENCES public.projects(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.skill_gaps ADD FOREIGN KEY (cluster_master_id) REFERENCES public.economic_clusters(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.skill_gaps ADD FOREIGN KEY (corridor_master_id) REFERENCES public.development_corridors(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.skill_gaps ADD FOREIGN KEY (location_master_id) REFERENCES public.geo_locations(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.educational_opportunity_details ADD FOREIGN KEY (created_by) REFERENCES public.users(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.educational_opportunity_details ADD FOREIGN KEY (updated_by) REFERENCES public.users(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.educational_opportunity_details ADD FOREIGN KEY (project_master_id) REFERENCES public.projects(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.educational_opportunity_details ADD FOREIGN KEY (cluster_master_id) REFERENCES public.economic_clusters(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.educational_opportunity_details ADD FOREIGN KEY (corridor_master_id) REFERENCES public.development_corridors(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.educational_opportunity_details ADD FOREIGN KEY (zee_master_id) REFERENCES public.investment_zones(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.educational_opportunity_details ADD FOREIGN KEY (zfi_master_id) REFERENCES public.investment_zones(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.educational_opportunity_details ADD FOREIGN KEY (location_master_id) REFERENCES public.geo_locations(id) ON DELETE RESTRICT; ALTER TABLE skills_edu.profile_need_matches ADD FOREIGN KEY (reviewed_by) REFERENCES public.users(id) ON DELETE RESTRICT;