Use extId station lookup and clamp walk durations

Add ApiClient.findStationByExtId and toStation helper; use it in
useOriginStationWalk. Clamp OSRM route/step durations to a minimum
walking speed (1.25 m/s) and update tests to mock the new API call.
This commit is contained in:
2026-05-18 12:15:13 +02:00
parent ce1fa4972c
commit 44fb492759
4 changed files with 54 additions and 25 deletions
@@ -69,6 +69,12 @@ jest.mock('../hooks/useOriginStationWalk', () => ({
jest.mock('../services/api', () => ({
api: {
findStationByExtId: jest.fn().mockResolvedValue({
name: 'Mödling Bahnhof',
extId: '1231701',
lat: 48.085,
lng: 16.296,
}),
searchJourneys: jest.fn().mockResolvedValue([
{
id: 'journey-1',
@@ -24,9 +24,9 @@ export function useOriginStationWalk(origin: Station | null) {
if (origin?.lat == null || origin.lng == null) return;
try {
const nearest = await api.findNearestStationByCoords(origin.lat, origin.lng);
const selectedStation = await api.findStationByExtId(origin.extId);
if (!isMounted) return;
setStation(nearest);
setStation(selectedStation);
} catch (err) {
if (!isMounted) return;
setLookupError(err instanceof Error ? err.message : 'Origin station lookup failed');
+5 -2
View File
@@ -2,6 +2,8 @@ import type { WalkRoute, WalkStep } from "@timetoleave/core";
import { OSRM_URL } from "./constants";
import { ApiClient } from "./api-service";
const WALKING_METERS_PER_SECOND = 1.25;
// ---------------------------------------------------------------------------
// OSRM response types (internal, not exported)
// ---------------------------------------------------------------------------
@@ -76,16 +78,17 @@ export class WalkRoutingClient {
if (res.code !== "Ok" || !res.routes.length) return null;
const route = res.routes[0];
const walkingDuration = Math.ceil(route.distance / WALKING_METERS_PER_SECOND);
const steps: WalkStep[] = (route.legs[0]?.steps ?? []).map((s) => ({
name: s.name,
distance: s.distance,
duration: s.duration,
duration: Math.max(s.duration, Math.ceil(s.distance / WALKING_METERS_PER_SECOND)),
instruction: stepInstruction(s),
}));
return {
distance: route.distance,
duration: route.duration,
duration: Math.max(route.duration, walkingDuration),
steps,
};
}