const fs = require('fs'); const path = require('path'); const crypto = require('crypto'); const jsonPath = path.join(__dirname, '..', 'iran_provinces_cities.json'); const list = JSON.parse(fs.readFileSync(jsonPath, 'utf8')); let sql = '-- Migration: Populate all provinces and cities of Iran\n'; sql += '-- Preserves existing tree structure: Country (ایران) -> Provinces (استان ...) -> Cities\n\n'; // 1. Ensure Country exists sql += 'INSERT INTO "City" ("id", "name", "parentId")\n'; sql += "VALUES ('city-iran', 'ایران', NULL)\n"; sql += 'ON CONFLICT ("id") DO NOTHING;\n\n'; function makeId(prefix, str) { return prefix + '-' + crypto.createHash('md5').update(str).digest('hex').substring(0, 16); } // 2. Insert Provinces for (const item of list) { let pName = item.province.trim(); if (!pName.startsWith('استان')) { pName = 'استان ' + pName; } const provId = makeId('prov', pName); const escapedName = pName.replace(/'/g, "''"); sql += 'INSERT INTO "City" ("id", "name", "parentId")\n'; sql += `SELECT '${provId}', '${escapedName}', 'city-iran'\n`; sql += `WHERE NOT EXISTS (SELECT 1 FROM "City" WHERE "name" = '${escapedName}');\n`; } sql += '\n-- 3. Insert Cities under their respective Province\n'; for (const item of list) { let pName = item.province.trim(); if (!pName.startsWith('استان')) { pName = 'استان ' + pName; } const escapedProvName = pName.replace(/'/g, "''"); for (const c of item.cities) { const cName = c.trim(); if (!cName) continue; const cityId = makeId('city', pName + '-' + cName); const escapedCityName = cName.replace(/'/g, "''"); sql += 'INSERT INTO "City" ("id", "name", "parentId")\n'; sql += `SELECT '${cityId}', '${escapedCityName}', (\n`; sql += ` SELECT "id" FROM "City" WHERE "name" = '${escapedProvName}' LIMIT 1\n`; sql += ')\n'; sql += 'WHERE NOT EXISTS (\n'; sql += ' SELECT 1 FROM "City" c2\n'; sql += ' JOIN "City" p2 ON c2."parentId" = p2."id"\n'; sql += ` WHERE c2."name" = '${escapedCityName}' AND p2."name" = '${escapedProvName}'\n`; sql += ');\n'; } } const targetDir = path.join(__dirname, '..', 'apps', 'api', 'prisma', 'migrations', '20261025120000_seed_iran_cities'); if (!fs.existsSync(targetDir)) { fs.mkdirSync(targetDir, { recursive: true }); } const targetFile = path.join(targetDir, 'migration.sql'); fs.writeFileSync(targetFile, sql, 'utf8'); console.log('Migration generated at:', targetFile); console.log('Total bytes:', fs.statSync(targetFile).size);