Fix driver route export import#213
Conversation
markboenigk
left a comment
There was a problem hiding this comment.
Code Review
This PR adds loadDriverRouteFromText to accept both Results-page export JSON and the existing session save format, removes the inline upload UI from /driver_assist, and routes import errors back via sessionStorage. Clean frontend-only change — here are a few things worth addressing before merge.
Bug: capacityUsed: 0 silently rejects valid Results exports
app/ui/src/lib/driver-route/importSession.ts line 47:
capacityUsed: z.number().positive().optional(),z.number().positive() excludes zero. If the Results page ever exports a stop with capacityUsed: 0 (e.g. a mandatory waypoint or pickup with nothing to drop off), resultsRouteSchema.safeParse() fails, the code falls through to session parsing which also fails, and the driver sees "This file is not a recognized route or session JSON file" — no indication of the actual problem.
Fix: change .positive() → .nonnegative(). Also revisit whether the ?? 1 default on line 183 should become ?? 0 (0-capacity stop vs. unspecified-capacity stop are different things).
Architecture: double validation makes the driver_assist error path dead code
upload-route/page.tsx now calls parseRouteUploadText(text) (result discarded) before storing to sessionStorage. Then driver_assist/page.tsx calls loadDriverRouteFromText again on the same bytes. Since both call the same function with the same input, anything that passes upload-route will pass driver_assist — the catch / sessionStorage.setItem(ROUTE_UPLOAD_ERROR_KEY, ...) / router.replace block in driver_assist is unreachable through the normal UI flow.
Worth picking one owner: pre-validate at upload and simplify/remove the driver_assist catch, or drop the upload-time pre-validation and let driver_assist remain the sole error handler. Right now both live on and the dead path will silently rot.
Architecture: sessionStorage for cross-page error passback is fragile
Writing an error key in driver_assist and reading it back in upload-route's mount effect breaks silently if sessionStorage is unavailable (strict private-browsing settings, storage quota hit) or cleared mid-navigation. The Next.js convention for this pattern is a query param:
router.replace(`/upload-route?error=${encodeURIComponent(message)}`);Survives storage resets, shows up in the address bar, and eliminates the ROUTE_UPLOAD_ERROR_KEY constant being imported from an upload-route internal module into driver_assist.
Cleanup: queueMicrotask wrapping setState in useEffect is unnecessary
React 18 automatically batches all synchronous state updates within an effect. The queueMicrotask calls on lines 74 and 100 of driver_assist/page.tsx add an extra microtask turn with no batching benefit — they just delay the loading → route transition by one tick and make the timing harder to follow. Calling the three setters directly is equivalent and clearer.
Cleanup: parseRouteUploadText is a pure pass-through
routeUploadValidation.ts exports one constant and one function that is literally return loadDriverRouteFromText(text). The module name implies validation responsibility that lives entirely in importSession.ts. Callers could import loadDriverRouteFromText directly; ROUTE_UPLOAD_ERROR_KEY could move to a shared constants file to remove the driver_assist → upload-route import dependency.
Summary
Motivation
RouteJSON shape, but Driver Assist only accepted session-save or raw session data JSON.Changes
Frontend:
sequence-> route orderaddresseeName-> customer namephoneNumber-> phone numbercapacityUsed-> package countnote-> noteslat/lng-> navigation coordinates/upload-routeand/driver_assistto use the same Driver Assist route parser.Backend:
Validation
Frontend
npm.cmd --prefix app/ui run lintnpm.cmd --prefix app/ui run format:checknpm.cmd --prefix app/ui run typechecknpm.cmd --prefix app/ui run testnpm.cmd --prefix app/ui run buildnpm.cmd --prefix app/mobile run lintnpm.cmd --prefix app/mobile run typecheckBackend
cmake --preset dev.github/scripts/check-backend-static.sh build/devcmake --build --preset dev --parallelctest --preset dev --output-on-failure --no-tests=error -LE 'e2e|docker'Risk
Rollout and Recovery
High-Signal PR Checklist
Related Issues
#199
lat/lng.