Skip to content

fix(delivery): Zeitfenster in der Ankunftsschätzung, lesbare Kartenattribution im Dunkelmodus - #102

Merged
huhn511 merged 3 commits into
mainfrom
fix/delivery-zeitfenster-und-attribution
Sep 7, 2026
Merged

huhn511 merged 3 commits into
mainfrom
fix/delivery-zeitfenster-und-attribution

Conversation

@huhn511

@huhn511 huhn511 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Problem

Smoke-Test vom 2026-09-07 in der Fahrer-App: die Ankunftsschätzung ignorierte Zeitfenster (Sammelstelle mit Fenster 09:00–09:30 bekam „Ankunft ca. 06:34"), und im Dunkelmodus war die Kartenattribution „Leaflet | © OpenStreetMap" mit ~1,8:1 unlesbar (leaflet.css gewann per Reihenfolge gegen global.css).

Änderung

  • Core und TypeScript-Zwilling: parseTimeWindow(), timeWindowBounds(), estimateArrivalDetails() mit Ankunft = max(ETA, Fensterbeginn), waitSeconds je Stopp, Wartezeit wandert in die Folge-ETAs, missesTimeWindow als Hinweis auf der Stoppkarte. Optimierung sortiert offene Stopps nach Fensterbeginn (Heuristik im Core dokumentiert, done/failed bleiben stehen). Einzelne Uhrzeit nur mit Präfix („ab", „bis", „spätestens", …) gedeutet (Review-Finding).
  • Attribution mit höherer Spezifität auf --color-surface, Kontrast in beiden Modi ≥ 4.5:1.

Verifikation

  • deliveryTours.test.js 83, delivery-routing 61 (inkl. core-consistency), bakery-delivery 67 Tests grün; curl- und Playwright-Reproduktion vor/nach dem Fix; unabhängiges Review (mergeable).

Hinweis

  • tour.duration enthält die Wartezeit vor Fensterbeginn nicht (nur Fahr- plus Standzeit); die Wartezeit ist an den ETAs sichtbar.

🤖 Generated with Claude Code

https://claude.ai/code/session_01PDQ42tUXqC7U3y716SssNx

Sebastian Heußer and others added 3 commits September 7, 2026 18:18
…im Dunkelmodus lesbar

Die Ankunftsschätzung ignorierte das Zeitfenster eines Stopps: an der
Sammelstelle Kindergarten Mörsbach (09:00-09:30) stand „Ankunft ca. 06:34",
ein Stopp mit 08:00-09:00 dahinter als Stopp 2 mit 06:42. `timeWindow`
wurde nur als String durchgereicht.

- Core: `parseTimeWindow()` liest „09:00-09:30", „9:00 – 9:30", „ab 09:00",
  „bis 09:30" (Freitext bleibt erlaubt und wirkungslos); `timeWindowBounds()`
  legt die Grenzen auf den Tourtag. `estimateArrivalDetails()` rechnet je
  Stopp `ankunft = max(eta, Fensterbeginn)`, weist `waitSeconds` aus und
  schiebt die Wartezeit in die Folge-ETAs; `missesTimeWindow`, wenn die
  Ankunft nach dem Fensterende liegt. `estimateArrivals()` bleibt als
  ISO-Wrapper erhalten.
- `orderStopsNearestNeighbour(origin, stops, { startedAt, vehicleType, date })`
  sortiert mit Zeitfenstern (Heuristik im Core-Kommentar: früheste
  Bedienzeit, verpasste Fenster und Kandidaten, die einem anderen Stopp das
  Fenster nehmen, ans Ende; ohne Fenster unverändert Nearest Neighbour).
- Mock-Server: `decorateTour` liefert `waitSeconds` und `missesTimeWindow`
  je Stopp; `POST /tours/:id/optimize` sortiert bei lesbaren Fenstern im
  Core ab dem Ausgangspunkt der Ankunftsprognose und lässt OSRM nur noch
  messen (der Trip-Endpunkt kennt keine Zeitfenster). done/failed bleiben
  über `applyOpenStopOrder` auf ihrem Platz.
- Frontend-Zwilling `@bakery/delivery/routing`: `parseTimeWindow`,
  `timeWindowBounds`, `optimizeRouteOrder(…, options)`,
  `withEstimatedArrivals(…, date)`; `core-consistency.spec.ts` rechnet
  Lesen, Reihenfolge, Ankunfts- und Wartezeiten gegen den Server.
- Stoppkarte: „Wartezeit bis Fensterbeginn" und der Hinweis „Zeitfenster …
  voraussichtlich nicht mehr einhaltbar – Ankunft erst gegen HH:MM Uhr".

Kartenattribution „Leaflet | © OpenStreetMap": `leaflet.css` setzt den
Balken mit gleicher Spezifität auf rgba(255,255,255,0.8) und gewann per
Ladereihenfolge - im Dunkelmodus 1,8:1. Die Regel in `global.css` trägt
jetzt `.leaflet-control-container` mit (drei Klassen, kein `!important`).
Per Playwright/getComputedStyle gemessen: hell 5,9:1, dunkel 8,6:1.

Tests: deliveryTours.test.js 61 → 81, delivery-routing 47 → 59,
bakery-delivery 62 → 67 (neue StopCard.spec.tsx).

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PDQ42tUXqC7U3y716SssNx
… Punkt-Schreibweise lesen

parseTimeWindow() las jede einzelne Uhrzeit als Fensterbeginn: „spätestens 09:30"
ließ die ETA-Kette bis 09:30 warten und schob alle Folge-Stopps - das Gegenteil
der Absicht. Jetzt gilt eine einzelne Uhrzeit nur mit erkennbarem Präfix
(ab / nicht vor / frühestens → Beginn, bis / spätestens / vor → Ende), sonst
bleibt sie Freitext ohne Wirkung („09:00 Uhr", „ca. 12:30"). Die deutsche
Punkt-Schreibweise „08.00-09.00" wird gelesen, ein Datum wie „19.09.2026" nicht.

Server-Core und TypeScript-Zwilling gleich geändert; deliveryTours.test.js,
delivery-routing.spec.ts und core-consistency.spec.ts prüfen die neuen Fälle.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PDQ42tUXqC7U3y716SssNx
@huhn511
huhn511 merged commit d825aff into main Sep 7, 2026
6 checks passed
@github-actions github-actions Bot added documentation Improvements or additions to documentation api ui backend testing labels Sep 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api backend documentation Improvements or additions to documentation testing ui

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant