fix(roadtrip): re-pin a via to the leg it was dragged onto

Dragging a via somewhere else on the map changed where the point IS and never where it
sits in the chain. The anchor that decides which two stops it is threaded between was
worked out once, when the point was dropped, and the drag sent only coordinates —
`roadtripViaUpdateRequestSchema` carried a lat and a lng and nothing else.

So a via pulled past the stop it used to precede kept claiming the earlier leg. The
router then drove out to it and turned back before carrying on, which on screen is not a
subtly wrong route: it is a spur that reads as the drag having done nothing at all, with
the original road still sitting there unchanged.

The anchor is not a property of the point but of where the point sits along the drive, so
it is recomputed on a drag the same way it is on a drop. The projection that did that was
inline in addRoadtripVia; it moves to a shared `anchorFor` and both callers use it.

A drag differs from a drop in two ways, both deliberate. It measures against its OWN day:
letting the nearest day win, which is right for a click on open map, would hand the via to
a neighbouring day whose road happens to pass closer and make it disappear from the day it
was dragged in. And it has no 2 km guard: pulling a via well off the current road is
exactly what the gesture is for, and the anchor only says which leg gets bent.

`after_order_index` is optional on the way in, so a drag inside one leg and an older
client still send just the coordinates, and the stored pin is then left alone rather
than cleared.
This commit is contained in:
Maurice
2026-09-09 18:25:23 +02:00
committed by Maurice
parent 77162aa8d5
commit 59b7c35e87
8 changed files with 158 additions and 15 deletions
+11 -1
View File
@@ -43,10 +43,20 @@ export const roadtripViaCreateRequestSchema = z.object({
});
export type RoadtripViaCreateRequest = z.infer<typeof roadtripViaCreateRequestSchema>;
/** Moving a via is the whole edit — dragging it somewhere else on the map. */
/**
* Moving a via is the whole edit — dragging it somewhere else on the map.
*
* `after_order_index` travels with the drag because the anchor is not a property of the
* point, it is a property of where the point sits along the drive. Without it a via
* dragged past the stop it used to precede keeps claiming the earlier leg, and the route
* runs out to it and back again before carrying on — which reads as the drag having done
* nothing at all. Optional so an older client, and a drag that did not move the via
* across a stop, still send just the coordinates.
*/
export const roadtripViaUpdateRequestSchema = z.object({
lat: latSchema,
lng: lngSchema,
after_order_index: z.number().int().min(0).optional(),
});
export type RoadtripViaUpdateRequest = z.infer<typeof roadtripViaUpdateRequestSchema>;