feat: integrate OSRM route service with customer live tracking#760
feat: integrate OSRM route service with customer live tracking#760CoderMS07 wants to merge 2 commits into
Conversation
|
🎉 Thank you for your contribution! Your pull request has been received and will be reviewed shortly. If you enjoy the project, please consider giving the repository a ⭐. You can also follow my GitHub profile to stay updated on future open-source projects. Thanks for being part of the community! 🚀 |
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (4)
💤 Files with no reviewable changes (2)
🚧 Files skipped from review as they are similar to previous changes (2)
📝 WalkthroughWalkthroughAdds live route tracking end to end: OSRM geometry helpers feed a new authenticated order route endpoint, and the customer app now polls that endpoint on a timer to render an updating route polyline with loading-state feedback. ChangesLive Route Tracking via OSRM
Sequence Diagram(s)sequenceDiagram
participant LiveTrackingScreen
participant OrderService
participant orderRoutes
participant telemetry
participant getRouteGeometry
LiveTrackingScreen->>OrderService: fetchOrderRoute(orderDisplayId)
OrderService->>orderRoutes: GET /api/orders/:id/route
orderRoutes->>telemetry: latest driver coordinates
telemetry-->>orderRoutes: origin coords
orderRoutes->>getRouteGeometry: origin and destination coordinates
getRouteGeometry-->>orderRoutes: GeoJSON Feature or null
orderRoutes-->>OrderService: geometry + fallback
OrderService-->>LiveTrackingScreen: route data
LiveTrackingScreen->>LiveTrackingScreen: parse coords and update polyline
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Suggested labels
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Pull request overview
Integrates OSRM-based road-following route geometry into the customer live tracking experience by adding a backend route-geometry endpoint (with Redis caching + straight-line fallback) and wiring the Flutter client to periodically fetch and render the returned GeoJSON LineString as a polyline.
Changes:
- Backend: add OSRM GeoJSON route fetching + short-lived Redis caching and a straight-line fallback geometry.
- Backend: add authenticated
GET /api/orders/:id/routeendpoint that uses latest MongoDB telemetry as the route origin and enforces customer/driver authorization. - Flutter: add route fetch API + periodic refresh and render the returned geometry as a map polyline with an initial loading indicator.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| backend/api/src/services/osrm.js | Adds OSRM geometry fetcher returning GeoJSON Feature(LineString), with Redis caching + straight-line fallback helper. |
| backend/api/src/routes/orderRoutes.js | Adds authenticated/authorized /route endpoint to return live route geometry based on latest telemetry. |
| apps/customer/lib/services/order_service.dart | Adds fetchOrderRoute() to call the new backend endpoint. |
| apps/customer/lib/screens/live_tracking_screen.dart | Periodically fetches route geometry and renders it as a polyline; shows loading state on initial load. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| _isFetchingRoute = true; | ||
| final isFirstLoad = _lastRouteFetchAt == null; | ||
| if (isFirstLoad && mounted) { | ||
| setState(() => _isRouteLoading = true); | ||
| } | ||
|
|
||
| try { | ||
| final routeData = await _orderService.fetchOrderRoute(widget.orderId); | ||
| _lastRouteFetchAt = DateTime.now(); | ||
|
|
| function buildGeometryUrl({ originLat, originLng, destLat, destLng }) { | ||
| const baseUrl = process.env.OSRM_BASE_URL || DEFAULT_OSRM_BASE_URL; | ||
| const url = new URL('/route/v1/driving/', baseUrl); | ||
| url.pathname += `${originLng},${originLat};${destLng},${destLat}`; | ||
| url.searchParams.set('overview', 'full'); | ||
| url.searchParams.set('geometries', 'geojson'); | ||
| url.searchParams.set('alternatives', 'false'); | ||
| url.searchParams.set('steps', 'false'); | ||
| return url; |
| router.get('/:id/route', authenticate, requireRole(['customer', 'driver']), validateParams(paramIdSchema), async (req, res) => { | ||
| const orderId = req.params.id; // this is order_display_id from client | ||
|
|
||
| try { | ||
| // 1. Resolve order and check authentication / authorization | ||
| const { data: order, error: orderErr } = await supabase | ||
| .from('orders') | ||
| .select('id, customer_id, driver_id, status, pickup_lat, pickup_lng, drop_lat, drop_lng') | ||
| .eq('order_display_id', orderId) | ||
| .maybeSingle(); |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/customer/lib/screens/live_tracking_screen.dart`:
- Around line 353-357: The setState block in the live tracking screen updates
_routePoints on every poll without checking if the points have actually changed,
causing unnecessary map redraws. Add a condition before the setState call to
check if the new points are different from the current _routePoints value, and
only call setState if they differ. This prevents redundant updates when
coordinates remain identical between polls.
In `@backend/api/src/routes/orderRoutes.js`:
- Around line 1251-1253: After converting order.drop_lat and order.drop_lng to
numbers using Number() function, add validation checks to ensure the resulting
destLat and destLng values are valid numbers and not NaN. If either value is
NaN, return a clear 400 Bad Request error with a descriptive message about
invalid input data instead of allowing the invalid values to proceed to
OSRM/fallback functions. Apply the same validation logic to the pickup
coordinate conversions at lines 1265-1267 for pickup_lat and pickup_lng.
In `@backend/api/src/services/osrm.js`:
- Around line 98-101: In the buildGeometryCacheKey function, the rounding helper
function r currently uses toFixed(3) which limits precision to approximately 100
meters. Increase the number of decimal places passed to toFixed() to a higher
value (such as 5 or 6) to preserve finer-grained location accuracy and prevent
nearby GPS points from reusing the same cached polyline.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: d6dc597e-8d83-4b38-9dac-d15d394c7f0e
📒 Files selected for processing (4)
apps/customer/lib/screens/live_tracking_screen.dartapps/customer/lib/services/order_service.dartbackend/api/src/routes/orderRoutes.jsbackend/api/src/services/osrm.js
| const destLat = Number(order.drop_lat); | ||
| const destLng = Number(order.drop_lng); | ||
|
|
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Validate destination numbers after conversion before calling OSRM/fallback.
If drop_lat/drop_lng are non-numeric strings, Number(...) yields NaN; this path currently returns a generic 502 instead of a clear data error.
💡 Proposed fix
const destLat = Number(order.drop_lat);
const destLng = Number(order.drop_lng);
+ if (!Number.isFinite(destLat) || !Number.isFinite(destLng)) {
+ return res.status(500).json({ error: 'Order has invalid destination coordinates.' });
+ }
// 3. Call OSRM for a road-following route, falling back to a straight
// line if OSRM is unavailable so the tracking screen never goes blank.Also applies to: 1265-1267
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@backend/api/src/routes/orderRoutes.js` around lines 1251 - 1253, After
converting order.drop_lat and order.drop_lng to numbers using Number() function,
add validation checks to ensure the resulting destLat and destLng values are
valid numbers and not NaN. If either value is NaN, return a clear 400 Bad
Request error with a descriptive message about invalid input data instead of
allowing the invalid values to proceed to OSRM/fallback functions. Apply the
same validation logic to the pickup coordinate conversions at lines 1265-1267
for pickup_lat and pickup_lng.
|
Hi @KanishJebaMathewM, Could you please add the appropriate difficulty label to this PR? Thank you! |
97542d4 to
16adc9b
Compare
Summary
This PR integrates the OSRM route service with the customer live tracking experience and replaces straight-line or missing routes with dynamically generated road-following polylines.
Changes Made
Backend
backend/api/src/services/osrm.jsgetRouteGeometry()for fetching route geometry from OSRM.buildStraightLineGeometry()fallback when OSRM is unavailable.backend/api/src/routes/orderRoutes.jsFlutter
apps/customer/lib/services/order_service.dartfetchOrderRoute()API integration.apps/customer/lib/screens/live_tracking_screen.dartError Handling
Performance Improvements
Verification
npm run dev).Checklist
GET /api/orders/:displayId/routeCloses #582
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes