chore: add standard international tariff seeder script

This commit is contained in:
Hamza-Ayed
2026-07-18 23:31:55 +03:00
parent 840d0e54fe
commit 22d18f32fe
+165
View File
@@ -0,0 +1,165 @@
/**
* 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.');