/** * Tripz - Global Tariffs Seed Script * * This script seeds the `tripz_tariffs` table with internationally recognized * service classes (e.g. Economy, Comfort, XL/Van, Saver) and standard time windows. * * It maps legacy flat pricing models into the modern Tripz JSON-based TariffDefinition. */ const fs = require('fs'); // Standard, internationally recognized service classes const ServiceClasses = { ECONOMY: 'economy', // Standard, affordable everyday rides (formerly 'speed') COMFORT: 'comfort', // Newer, more spacious vehicles LADY: 'lady', // Female drivers for female riders ELECTRIC: 'electric', // EV/Green vehicles VAN: 'van', // High capacity (XL) vehicles DELIVERY: 'delivery', // Package / courier delivery VIP: 'vip', // Premium / Luxury rides (formerly 'mishwarVip') FIXED: 'fixed', // Fixed route/fare rides SAVER: 'saver' // Discounted / shared rides (formerly 'awfar') }; // Global pricing configurations per country const countryConfigs = [ { country: 'jordan', currency: 'JOD', commissionPercent: 14.0, baseFare: 0.0, // Note: In the legacy system, Jordan's per-minute and per-km values were structurally swapped. // We have normalized them here to follow standard logic (perKm is higher than perMin). serviceRates: { [ServiceClasses.ECONOMY]: { perKm: 0.184, perMin: 0.043 }, [ServiceClasses.COMFORT]: { perKm: 0.212, perMin: 0.056 }, [ServiceClasses.LADY]: { perKm: 0.184, perMin: 0.047 }, [ServiceClasses.ELECTRIC]: { perKm: 0.184, perMin: 0.052 }, [ServiceClasses.VAN]: { perKm: 0.250, perMin: 0.065 }, // Adjusted perKm for Van proportionality [ServiceClasses.DELIVERY]: { perKm: 0.150, perMin: 0.039 }, [ServiceClasses.VIP]: { perKm: 0.300, perMin: 0.060 }, [ServiceClasses.FIXED]: { perKm: 0.184, perMin: 0.043 }, [ServiceClasses.SAVER]: { perKm: 0.150, perMin: 0.037 }, }, timeMultipliers: { normal: 1.0, // 08:00 - 16:00 peak: 1.15, // 16:00 - 22:00 (15% surge) late: 1.0 // 22:00 - 08:00 } }, { country: 'egypt', currency: 'EGP', commissionPercent: 12.0, baseFare: 0.0, serviceRates: { [ServiceClasses.ECONOMY]: { perKm: 3.5, perMin: 0.8 }, [ServiceClasses.COMFORT]: { perKm: 5.0, perMin: 0.9 }, [ServiceClasses.LADY]: { perKm: 9.0, perMin: 1.0 }, [ServiceClasses.ELECTRIC]: { perKm: 0.8, perMin: 0.5 }, [ServiceClasses.VAN]: { perKm: 1.4, perMin: 1.0 }, [ServiceClasses.DELIVERY]: { perKm: 1.3, perMin: 0.8 }, [ServiceClasses.VIP]: { perKm: 5.5, perMin: 1.2 }, [ServiceClasses.FIXED]: { perKm: 5.5, perMin: 1.0 }, [ServiceClasses.SAVER]: { perKm: 3.0, perMin: 0.7 }, }, timeMultipliers: { normal: 1.0, peak: 1.75, // 1.4 EGP peak / 0.8 EGP normal = 1.75x late: 1.87 // 1.5 EGP late / 0.8 EGP normal = 1.87x } }, { country: 'syria', currency: 'SYP', commissionPercent: 11.0, baseFare: 0.0, serviceRates: { [ServiceClasses.ECONOMY]: { perKm: 40, perMin: 9 }, [ServiceClasses.COMFORT]: { perKm: 44, perMin: 10 }, [ServiceClasses.LADY]: { perKm: 63, perMin: 12 }, [ServiceClasses.ELECTRIC]: { perKm: 9, perMin: 5 }, [ServiceClasses.VAN]: { perKm: 10, perMin: 8 }, [ServiceClasses.DELIVERY]: { perKm: 20, perMin: 9 }, [ServiceClasses.VIP]: { perKm: 26, perMin: 12 }, [ServiceClasses.FIXED]: { perKm: 26, perMin: 10 }, [ServiceClasses.SAVER]: { perKm: 36, perMin: 8 }, }, timeMultipliers: { normal: 1.0, peak: 1.11, // 10 peak / 9 normal = 1.11x late: 1.22 // 11 late / 9 normal = 1.22x } } ]; function generateSql() { let sql = `-- Tripz Standard Tariffs Seed Script\n`; sql += `-- Generated with international ride-hailing naming conventions.\n\n`; for (const config of countryConfigs) { const city = config.country; for (const [serviceClass, rates] of Object.entries(config.serviceRates)) { const definition = { currency: config.currency, mode: 'time_and_distance', booking_fee: config.baseFare, min_fare: config.baseFare > 0 ? config.baseFare : (rates.perKm * 2), // Min fare = 2 KMs default windows: [ { name: 'normal', from: '08:00', to: '16:00', flag: config.baseFare, per_km: rates.perKm, per_min: rates.perMin, per_min_waiting: Number((rates.perMin * 1.5).toFixed(3)) }, { name: 'peak', from: '16:00', to: '22:00', flag: config.baseFare, per_km: Number((rates.perKm * config.timeMultipliers.peak).toFixed(3)), per_min: Number((rates.perMin * config.timeMultipliers.peak).toFixed(3)), per_min_waiting: Number((rates.perMin * config.timeMultipliers.peak * 1.5).toFixed(3)) }, { name: 'late', from: '22:00', to: '08:00', flag: config.baseFare, per_km: Number((rates.perKm * config.timeMultipliers.late).toFixed(3)), per_min: Number((rates.perMin * config.timeMultipliers.late).toFixed(3)), per_min_waiting: Number((rates.perMin * config.timeMultipliers.late * 1.5).toFixed(3)) } ], commission: { percent: config.commissionPercent } }; const defJson = JSON.stringify(definition).replace(/'/g, "''"); // Escape single quotes for SQL sql += `INSERT INTO tripz_tariffs (id, tenant_id, city, service_class, version, active, definition)\n`; sql += `VALUES (\n`; sql += ` gen_random_uuid(),\n`; sql += ` (SELECT id FROM tripz_tenants WHERE slug = 'siro' LIMIT 1),\n`; sql += ` '${city}',\n`; sql += ` '${serviceClass}',\n`; sql += ` 1,\n`; sql += ` true,\n`; sql += ` '${defJson}'::jsonb\n`; sql += `);\n\n`; } } return sql; } const sqlOutput = generateSql(); fs.writeFileSync(__dirname + '/seed-tariffs.sql', sqlOutput); console.log('✅ Generated seed-tariffs.sql successfully with international naming standards.');