feat(logistics): add Smart Auto-Courier cascading router, OSM Nominatim + 64-District spatial gazetteer fallback, NDR phone tag, and JSON guard

This commit is contained in:
Aura Autonomous Engine
2026-10-11 17:48:11 +00:00
parent caa1a0c81e
commit 55795a3e02
7 changed files with 297 additions and 51 deletions
+92 -6
View File
@@ -120,6 +120,9 @@ export class GoogleMapsAdapter {
roadDistanceKm = Math.round((route.distanceMeters / 1000) * 10) / 10;
routeSummary = route.description || "";
}
else {
roadDistanceKm = this.haversineDistance(this.defaultHub.lat, this.defaultHub.lng, destLat, destLng);
}
}
catch (routesErr) {
roadDistanceKm = this.haversineDistance(this.defaultHub.lat, this.defaultHub.lng, destLat, destLng);
@@ -284,19 +287,102 @@ export class GoogleMapsAdapter {
quotes,
};
}
fallbackAddressParse(req) {
const raw = (req.address + " " + (req.district || "")).toLowerCase();
async fallbackAddressParse(req) {
const fullQuery = [req.address, req.thana, req.district, "Bangladesh"].filter(Boolean).join(", ");
// Tier 2: Live OpenStreetMap Nominatim Geocoding (Zero-Billing Fallback)
try {
const nomRes = await axios.get("https://nominatim.openstreetmap.org/search", {
params: {
q: fullQuery,
countrycodes: "bd",
format: "json",
addressdetails: 1,
limit: 1,
},
headers: { "User-Agent": "AuraCourierMCP/2.5 (https://courier.auraajenticai.cloud)" },
timeout: 5500,
});
if (Array.isArray(nomRes.data) && nomRes.data.length > 0) {
const hit = nomRes.data[0];
const addr = hit.address || {};
const lat = parseFloat(hit.lat);
const lng = parseFloat(hit.lon);
const thana = addr.suburb || addr.neighbourhood || addr.town || addr.municipality || addr.city_district || req.thana || "";
const district = (addr.county || addr.city || addr.state_district || req.district || "Dhaka").replace(/\s*District$/i, "");
const division = addr.state || "Dhaka Division";
return {
success: true,
formatted_address: hit.display_name || fullQuery,
thana,
district,
division,
coordinates: { lat, lng },
location_type: "GEOMETRIC_CENTER",
is_deliverable: true,
confidence_score: 88,
place_id: `osm_${hit.place_id || Date.now()}`,
};
}
}
catch (_) {
// Proceed to Tier 3 Spatial Gazetteer
}
// Tier 3: Bangladesh 64-District & Dhaka Thana Spatial Gazetteer
const raw = [req.address, req.thana, req.district].filter(Boolean).join(" ").toLowerCase();
const gazetteer = [
{ rx: /mirpur|মিরপুর|pallabi|পল্লবী|kazipara|shewrapara|কাজীপাড়া|শেওড়াপাড়া/, thana: "Mirpur", district: "Dhaka", division: "Dhaka Division", lat: 23.8042, lng: 90.3667 },
{ rx: /uttara|উত্তরা|airport|বিমানবন্দর|sector|সেক্টর|dakshin khan|uttar khan/, thana: "Uttara", district: "Dhaka", division: "Dhaka Division", lat: 23.8759, lng: 90.3795 },
{ rx: /dhanmondi|ধানমন্ডি|kalabagan|কলাবাগান|jigatola|জিগাতলা|shankar/, thana: "Dhanmondi", district: "Dhaka", division: "Dhaka Division", lat: 23.7461, lng: 90.3742 },
{ rx: /gulshan|গুলশান|banani|বনানী|baridhara|বারিধারা|niketan|নিকেতন/, thana: "Gulshan", district: "Dhaka", division: "Dhaka Division", lat: 23.7925, lng: 90.4078 },
{ rx: /mohammadpur|মোহাম্মদপুর|adabor|আদাবর|lalmatia|লালমাটিয়া|bosila|বসিলা/, thana: "Mohammadpur", district: "Dhaka", division: "Dhaka Division", lat: 23.7662, lng: 90.3589 },
{ rx: /badda|বাড্ডা|rampura|রামপুরা|banasree|বনশ্রী|aftabnagar|আফতাবনগর|hatirjheel/, thana: "Badda", district: "Dhaka", division: "Dhaka Division", lat: 23.7805, lng: 90.4267 },
{ rx: /bashundhara|বসুন্ধরা|vatara|ভাটারা|kuril|কুড়িল|nikunja|নিকুঞ্জ|khilkhet|খিলক্ষেত/, thana: "Vatara", district: "Dhaka", division: "Dhaka Division", lat: 23.8191, lng: 90.4526 },
{ rx: /motijheel|মতিঝিল|paltan|পল্টন|kakrail|কাকরাইল|shantinagar|শান্তিনগর|malibagh|মালিবাগ|mogbazar|মগবাজার/, thana: "Motijheel", district: "Dhaka", division: "Dhaka Division", lat: 23.7330, lng: 90.4172 },
{ rx: /shahbag|শাহবাগ|hatirpool|হাতিরপুল|motaleb|মোতালেব|eleph|এলিফ্যান্ট|new market|নিউ মার্কেট|farmgate|ফার্মগেট|tejgaon|তেজগাঁও|karwan|কারওয়ান/, thana: "Shahbagh", district: "Dhaka", division: "Dhaka Division", lat: 23.7415, lng: 90.3918 },
{ rx: /jatrabari|যাত্রাবাড়ী|demra|ডেমরা|kadamtali|কদমতলী|shanir akhra|শনির আখড়া|wari|ওয়ারী|old dhaka|পুরান ঢাকা|lalbagh|লালবাগ|kotwali/, thana: "Jatrabari", district: "Dhaka", division: "Dhaka Division", lat: 23.7104, lng: 90.4348 },
{ rx: /keraniganj|কেরানীগঞ্জ|ati bazar|আটি বাজার|atibazar|hasnabad/, thana: "Keraniganj", district: "Dhaka", division: "Dhaka Division", lat: 23.6942, lng: 90.3475 },
{ rx: /savar|সাভার|ashulia|আশুলিয়া|hemayetpur|হেমায়েতপুর|dhamrai|ধামরাই/, thana: "Savar", district: "Dhaka", division: "Dhaka Division", lat: 23.8583, lng: 90.2667 },
{ rx: /gazipur|গাজীপুর|tongi|টঙ্গী|board bazar|বোর্ড বাজার|joydebpur|জয়দেবপুর|konabari/, thana: "Tongi", district: "Gazipur", division: "Dhaka Division", lat: 23.9889, lng: 90.3950 },
{ rx: /narayanganj|নারায়ণগঞ্জ|siddhirganj|সিদ্ধিরগঞ্জ|fatullah|ফতুল্লা|chashara|চাষাড়া|sonargaon|rupganj/, thana: "Narayanganj Sadar", district: "Narayanganj", division: "Dhaka Division", lat: 23.6238, lng: 90.5000 },
{ rx: /chattogram|chittagong|চট্টগ্রাম|agrabad|আগ্রাবাদ|nasirabad|নাসিরাবাদ|halishahar|হালিশহর|panchlaish|gec|জিইসি|kotwali/, thana: "Panchlaish", district: "Chattogram", division: "Chattogram Division", lat: 22.3569, lng: 91.7832 },
{ rx: /cox.?s?s*bazar|কক্সবাজার|chakaria|teknaf|ukhiya/, thana: "Cox's Bazar Sadar", district: "Cox's Bazar", division: "Chattogram Division", lat: 21.4272, lng: 92.0058 },
{ rx: /cumilla|comilla|কুমিল্লা|kandirpar|কান্দিরপাড়|laksam|daudkandi/, thana: "Cumilla Sadar", district: "Cumilla", division: "Chattogram Division", lat: 23.4607, lng: 91.1809 },
{ rx: /feni|ফেনী|noakhali|নোয়াখালী|maijdee|চৌমুহনী|lakshmipur|লক্ষ্মীপুর|chandpur|চাঁদপুর|brahmanbaria|ব্রাহ্মণবাড়িয়া/, thana: "Sadar", district: "Noakhali", division: "Chattogram Division", lat: 22.8724, lng: 91.0973 },
{ rx: /sylhet|সিলেট|zindabazar|জিন্দাবাজার|amberkhana|আম্বরখানা|upashahar|উপশহর|moulvibazar|মৌলভীবাজার|sreemangal|habiganj|হবিগঞ্জ|sunamganj|সুনামগঞ্জ/, thana: "Sylhet Sadar", district: "Sylhet", division: "Sylhet Division", lat: 24.8949, lng: 91.8687 },
{ rx: /rajshahi|রাজশাহী|boalia|বোয়ালিয়া|shaheb bazar|সাহেব বাজার|motihar|নাটোর|natore|naogaon|নওগাঁ|chapainawabganj|চাঁপাইনবাবগঞ্জ|pabna|পাবনা|sirajganj|সিরাজগঞ্জ/, thana: "Boalia", district: "Rajshahi", division: "Rajshahi Division", lat: 24.3745, lng: 88.6042 },
{ rx: /bogura|bogra|বগুড়া|sherpur|শেরপুর|joypurhat|জয়পুরহাট/, thana: "Bogura Sadar", district: "Bogura", division: "Rajshahi Division", lat: 24.8481, lng: 89.3730 },
{ rx: /khulna|খুলনা|sonadanga|সোনাডাঙ্গা|khalishpur|খালিশপুর|daulatpur|jashore|jessore|যশোর|kushtia|কুষ্টিয়া|satkhira|সাতক্ষীরা|bagerhat|বাগেরহাট|jhenaidah|ঝিনাইদহ/, thana: "Sonadanga", district: "Khulna", division: "Khulna Division", lat: 22.8456, lng: 89.5403 },
{ rx: /barishal|barisal|বরিশাল|patukhali|পটুয়াখালী|bhola|ভোলা|pirojpur|পিরোজপুর|jhalokati|barguna/, thana: "Barishal Sadar", district: "Barishal", division: "Barishal Division", lat: 22.7010, lng: 90.3535 },
{ rx: /rangpur|রংপুর|dinajpur|দিনাজপুর|thakurgaon|ঠাকুরগাঁও|panchagarh|পঞ্চগড়|nilphamari|নীলফামারী|saidpur|সৈয়দপুর|kurigram|কুড়িগ্রাম|gaibandha|গাইবান্ধা|lalmonirhat/, thana: "Rangpur Sadar", district: "Rangpur", division: "Rangpur Division", lat: 25.7439, lng: 89.2752 },
{ rx: /mymensingh|ময়মনসিংহ|jamalpur|জামালপুর|netrokona|নেত্রকোনা|tangail|টাঙ্গাইল|kishoreganj|কিশোরগঞ্জ|faridpur|ফরিদপুর|madaripur|মাদারীপুর|gopalganj|গোপালগঞ্জ|shariatpur|শরীয়তপুর|rajbari|রাজবাড়ী|manikganj|মানিকগঞ্জ|munshiganj|মুন্সিগঞ্জ|narsingdi|নরসিংদী/, thana: "Mymensingh Sadar", district: "Mymensingh", division: "Mymensingh Division", lat: 24.7471, lng: 90.4203 },
];
for (const g of gazetteer) {
if (g.rx.test(raw)) {
return {
success: true,
formatted_address: `${req.address}, ${req.thana || g.thana}, ${req.district || g.district}, Bangladesh`,
thana: req.thana || g.thana,
district: req.district || g.district,
division: g.division,
coordinates: { lat: g.lat, lng: g.lng },
location_type: "GEOMETRIC_CENTER",
is_deliverable: true,
confidence_score: 84,
place_id: `bd_gazetteer_${g.district.toLowerCase().replace(/\s+/g, "_")}`,
};
}
}
const isDhaka = /dhaka|ঢাকা/i.test(raw);
return {
success: true,
formatted_address: req.address,
thana: req.thana || "",
thana: req.thana || (isDhaka ? "Dhaka Metro" : "Sadar"),
district: req.district || (isDhaka ? "Dhaka" : "Outside Dhaka"),
division: isDhaka ? "Dhaka" : "",
coordinates: isDhaka ? { lat: 23.8103, lng: 90.4125 } : { lat: 22.3569, lng: 91.7832 },
division: isDhaka ? "Dhaka Division" : "Bangladesh",
coordinates: isDhaka ? { lat: 23.8103, lng: 90.4125 } : { lat: 24.0000, lng: 90.0000 },
location_type: "APPROXIMATE",
is_deliverable: true,
confidence_score: 65,
confidence_score: 72,
};
}
haversineDistance(lat1, lon1, lat2, lon2) {