HI-FI: Wire Recipient And Delivery Window Data To Results#161
HI-FI: Wire Recipient And Delivery Window Data To Results#161KesarSidhu wants to merge 3 commits into
Conversation
|
Solid plumbing work overall — the round-trip through sessionMapper and the conditional omission of empty fields from the API payload are both done well. Two things worth a follow-up: 1. New
2. Capacity logic change deserves scrutiny // before
capacityUsed: step.load?.[0] ?? 0,
// after
const qtyFromForm = address && address.deliveryQuantity > 0 ? address.deliveryQuantity : undefined;
const capacityUsed = qtyFromForm ?? step.load?.[0] ?? 0;VROOM's Minor nits:
What's good: defaults added in both |
Map recipient name, phone, and delivery window bounds from edit session through vroomToRoutes into results Stop fields. Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
355e088 to
b604f65
Compare
kirillakovalenko
left a comment
There was a problem hiding this comment.
Code Review: PR #161 — HI-FI: Wire Recipient And Delivery Window Data To Results
Author: Kesar Singh Sidhu | Files changed: 4 | +41 / -2
Overview
A clean, focused PR that pipes recipientName, phoneNumber, and the delivery window from the edit form through vroomToRoutes into the Stop type, then renders them on expanded stop cards. The motivation is solid — drivers had no way to see contact info or delivery windows after optimization.
Code Quality
vroomToRoutes.ts — mapping logic
The diff shows that addresseeName and phoneNumber already existed on Stop before this PR (and were already mapped), but the PR correctly adds .trim() to both, which is a good cleanup. The delivery window spread is correct:
...(winStart && winEnd ? { deliveryWindowStart: winStart, deliveryWindowEnd: winEnd } : {})
However, there's a minor inconsistency: inferTimeWindowKind (line 69) still reads the raw address?.deliveryTimeStart / address?.deliveryTimeEnd without trimming, while the new winStart/winEnd variables are trimmed. If a value is " 9:00 AM" (leading space), inferTimeWindowKind would treat it as truthy but the trimmed version would match — so the behavior is consistent in practice, but the raw read in inferTimeWindowKind is slightly inconsistent with the new convention.
EditableStopItem.tsx — rendering
- The phone row renders
{stop.phoneNumber ?? "—"}unconditionally, matching the pattern used foraddresseeName. Consistent and correct. - The delivery window row correctly gates on both fields being set before rendering, matching the type contract where both are either present or absent.
- Label concern: The existing label says
"Name of addressed to:"(grammatically awkward) — the new"Phone:"and"Delivery window:"labels are fine, but worth flagging the existing label as technical debt.
types.ts — Stop interface
The JSDoc comment added is useful. One note: deliveryWindowStart and deliveryWindowEnd having no paired invariant enforcement at the type level (i.e., you can have one without the other) could be a footgun for future callers. A discriminated union or a nested deliveryWindow?: { start: string; end: string } object would make the "always both or neither" contract explicit and compile-time safe.
// Current (implicit pairing): deliveryWindowStart?: string; deliveryWindowEnd?: string;
// More explicit alternative:
deliveryWindow?: { start: string; end: string };
Test Coverage
The new test in vroomToRoutes.test.ts is good — it covers the happy path including the trim for recipientName. Missing cases worth adding:
- Only one window bound set (e.g.,
deliveryTimeStartset,deliveryTimeEndabsent) — verify neitherdeliveryWindowStartnordeliveryWindowEndappears on the stop. - Empty/whitespace-only window strings — verify they're treated as absent (the
trim()logic handles this, but a test would lock it in). - Phone number with surrounding whitespace — the
trim()onphoneNumberis untested.
Risks & Concerns
| Severity | Finding |
|---|---|
| Low | build and all mobile/backend CI checks are unchecked in the PR checklist — these should pass before merge. |
| Low | The "always both or never" window invariant is implicit, not type-enforced. Acceptable for now but worth a follow-up. |
| Low | inferTimeWindowKind uses un-trimmed values while the new mapping uses trimmed ones — cosmetically inconsistent. |
| Nit | "Name of addressed to:" label (pre-existing) is awkward; could be cleaned up as a drive-by. |
Summary
The PR is well-scoped, the mapping logic is correct, and the test covers the main happy path. The main actionable items are:
- Before merge: Confirm the unchecked CI steps pass (especially
build). - Recommended follow-up: Add edge-case tests for partial window and whitespace-only fields.
- Optional refactor: Collapse
deliveryWindowStart/EndintodeliveryWindow?: { start: string; end: string }for a stronger type contract.
Verdict: Approve with minor suggestions. The core logic is correct and the change is low-risk.
Co-authored-by: Cursor <cursoragent@cursor.com>
markboenigk
left a comment
There was a problem hiding this comment.
Both concerns from my earlier comment are resolved: fields are rendered in EditableStopItem and VROOM's step.load is kept for capacityUsed. kirillakovalenko's suggestions are also addressed in the latest commit — deliveryWindow uses the nested object shape and inferTimeWindowKind receives trimmed values. CI is all green. Approved.
Summary
Results expanded stop cards show recipient name, phone, and delivery window from the edit session, mapped through
vroomToRoutesintoStopand rendered on each card.Motivation
Stop cards only showed address, package count, and optimizer arrival time. Recipient contact and the user’s delivery window lived on the edit form but were not passed through to results, so drivers could not see them after optimization.
Changes
app/ui/src/app/results/types.ts— add optionalphoneNumber,deliveryWindowStart, anddeliveryWindowEndonStop.app/ui/src/app/edit/utils/vroomToRoutes.ts— maprecipientName,phoneNumber, and delivery window bounds fromAddressCardonto each stop (trim empty strings; window only when both start and end are set). KeepcapacityUsedfrom VROOMstep.load, not form quantity.app/ui/src/app/results/components/EditableStopItem.tsx— render phone and delivery window rows on expanded stop cards.app/ui/src/tests/vroomToRoutes.test.ts— test recipient, phone, and window mapping.Out of scope for this PR (already on
main, unchanged here):optimizeMapper.ts,sessionMapper.ts,delivery.ts,useAddresses.ts,useCSVUpload.ts.Validation
Frontend
npm --prefix app/ui run lintnpm --prefix app/ui run format:checknpm --prefix app/ui run typechecknpm --prefix app/ui run testnpm --prefix app/ui run buildnpm --prefix app/mobile run lintnpm --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'docker compose -f deploy/compose/docker-compose.arm64.yml --env-file deploy/env/http-server.arm64.env configRisk
Low — UI-only mapping and display.
capacityUsedstill comes from the optimizer’sstep.load. Phone usesphoneNumberonStop(same field name as edit → API), not a separateaddresseePhone.Rollout and Recovery
Ship with the results page. Revert this PR if stop card field layout or mapping needs adjustment.