-- Allow cities directly under a country (province optional). -- Seed Iraq, Turkey, UAE + major cities (Iran already seeded in 004_iran_cities). CREATE OR REPLACE FUNCTION cities_validate_parent_level() RETURNS TRIGGER AS $$ DECLARE parent_level city_level; BEGIN IF NEW.level = 'country' THEN RETURN NEW; END IF; SELECT level INTO parent_level FROM cities WHERE id = NEW.parent_id; IF NOT FOUND THEN RAISE EXCEPTION 'parent city not found'; END IF; IF NEW.level = 'province' AND parent_level <> 'country' THEN RAISE EXCEPTION 'province parent must be a country'; END IF; -- Province is optional: city may hang under a province or directly under a country. IF NEW.level = 'city' AND parent_level NOT IN ('province', 'country') THEN RAISE EXCEPTION 'city parent must be a province or country'; END IF; IF NEW.level = 'district' AND parent_level <> 'city' THEN RAISE EXCEPTION 'district parent must be a city'; END IF; RETURN NEW; END; $$ LANGUAGE plpgsql; -- --------------------------------------------------------------------------- -- Countries (skip if slug already exists) -- --------------------------------------------------------------------------- INSERT INTO cities (parent_id, level, name_fa, name_en, landline_code, slug, sort_order) SELECT NULL, 'country', v.name_fa, v.name_en, v.landline_code, v.slug, v.sort_order FROM ( VALUES ('ایران', 'Iran', '98', 'iran', 1), ('عراق', 'Iraq', '964', 'iraq', 2), ('ترکیه', 'Turkey', '90', 'turkey', 3), ('امارات', 'UAE', '971', 'uae', 4) ) AS v(name_fa, name_en, landline_code, slug, sort_order) WHERE NOT EXISTS ( SELECT 1 FROM cities c WHERE c.slug = v.slug ); -- --------------------------------------------------------------------------- -- Major cities under country (direct children; province not required) -- Iran cities already exist under provinces — API lists them via country parent. -- --------------------------------------------------------------------------- INSERT INTO cities (parent_id, level, name_fa, name_en, landline_code, slug, sort_order) SELECT c.id, 'city', v.name_fa, v.name_en, v.landline_code, v.slug, v.sort_order FROM cities c JOIN ( VALUES -- Iraq ('iraq', 'بغداد', 'Baghdad', '1', 'baghdad', 1), ('iraq', 'بصره', 'Basra', '40', 'basra', 2), ('iraq', 'اربیل', 'Erbil', '66', 'erbil', 3), ('iraq', 'موصل', 'Mosul', '60', 'mosul', 4), ('iraq', 'نجف', 'Najaf', '33', 'najaf', 5), ('iraq', 'سلیمانیه', 'Sulaymaniyah', '53', 'sulaymaniyah', 6), ('iraq', 'کرکوک', 'Kirkuk', '50', 'kirkuk', 7), -- Turkey ('turkey', 'استانبول', 'Istanbul', '212', 'istanbul', 1), ('turkey', 'آنکارا', 'Ankara', '312', 'ankara', 2), ('turkey', 'ازمیر', 'Izmir', '232', 'izmir', 3), ('turkey', 'آنتالیا', 'Antalya', '242', 'antalya', 4), ('turkey', 'بورسا', 'Bursa', '224', 'bursa', 5), ('turkey', 'غازی عینتاب', 'Gaziantep', '342', 'gaziantep', 6), -- UAE ('uae', 'دبی', 'Dubai', '4', 'dubai', 1), ('uae', 'ابوظبی', 'Abu Dhabi', '2', 'abu-dhabi', 2), ('uae', 'شارجه', 'Sharjah', '6', 'sharjah', 3), ('uae', 'عجمان', 'Ajman', '6', 'ajman', 4), ('uae', 'رأس الخیمه', 'Ras Al Khaimah', '7', 'ras-al-khaimah', 5) ) AS v(country_slug, name_fa, name_en, landline_code, slug, sort_order) ON c.slug = v.country_slug AND c.level = 'country' WHERE NOT EXISTS ( SELECT 1 FROM cities x WHERE x.slug = v.slug );