beginTransaction(); try { $transit_con->prepare( "INSERT INTO transit_routes (org_id,name_ar,name_en,direction,polyline,distance_km,duration_min,status,created_by) VALUES (?,?,?,?,?,?,?,'draft',?)" )->execute([ $transit_org_id, $nameAr, filterRequest('name_en'), $direction, filterRequest('polyline'), filterRequest('distance_km','float'), filterRequest('duration_min','int'), $transit_admin_id, ]); $routeId = (int)$transit_con->lastInsertId(); $insertStop = $transit_con->prepare( "INSERT INTO transit_stops (route_id,org_id,sequence,name_ar,name_en,latitude,longitude,geofence_radius,eta_offset_min,is_major) VALUES (?,?,?,?,?,?,?,?,?,?)" ); foreach ($stops as $i => $s) { if (empty($s['lat']) || empty($s['lng']) || empty($s['name_ar'])) continue; $insertStop->execute([ $routeId, $transit_org_id, $i + 1, $s['name_ar'], $s['name_en'] ?? null, (float)$s['lat'], (float)$s['lng'], (int)($s['radius'] ?? 150), isset($s['eta_offset_min']) ? (int)$s['eta_offset_min'] : null, (int)($s['is_major'] ?? 0), ]); } $transit_con->commit(); } catch (Throwable $e) { $transit_con->rollBack(); appLog('[TRANSIT][ROUTE] ' . $e->getMessage(), 'ERROR'); jsonError('Failed to save route', 500); } jsonSuccess(['route_id' => $routeId, 'stops_added' => count($stops)], 'Route saved as draft');