Files
Holzleitner-Lieferservice-App/docs/finish_delivery.md
Dennis Nemec 2470299a10 BIG FAT
2026-04-28 13:03:09 +02:00

5.0 KiB
Raw Blame History

Lieferungs-Abschluss: Ablauf & bekannte Themen

Dieses Dokument beschreibt den Request-Ablauf, der ausgelöst wird, wenn der Fahrer nach der Unterschrift "Lieferung abschließen" auslöst, sowie bekannte Schwachstellen, die mittelfristig adressiert werden sollten.

Stand: 2026-04-26.

Aufrufkette

UI: SignatureView.onSigned_onSign(customer, driver) (lib/feature/delivery/detail/presentation/delivery_detail_page.dart)

BLoC: dispatched FinishDeliveryEventTourBloc._finishDelivery (lib/feature/delivery/bloc/tour_bloc.dart)

Repository (lib/feature/delivery/repository/tour_repository.dart):

  1. uploadDriverSignature(deliveryId, driverSignature)
  2. uploadCustomerSignature(deliveryId, customerSignature)
  3. finishDelivery(deliveryId)

Daraus ergeben sich 7 sequenzielle HTTP-Requests (jeweils await):

Reihenfolge HTTP Endpoint Zweck
1 GET /v1/uploadFile uploadId für Fahrer-Signatur holen
2 POST /v1/uploadFile/{uploadId} Multipart-Upload delivery_{id}_signature_driver.jpg
3 PATCH /v1/uploadFile/{uploadId} Upload commit, liefert ObjectID
4 GET /v1/uploadFile uploadId für Kunden-Signatur holen
5 POST /v1/uploadFile/{uploadId} Multipart-Upload delivery_{id}_signature_customer.jpg
6 PATCH /v1/uploadFile/{uploadId} Upload commit
7 POST _web_finishDelivery Atomarer Abschluss: setzt _SV_DELIVERY_STATE = "geliefert" und _SV_DELIVERY_DELIVERED_AT = <Zeitstempel>, räumt entfernte Artikel auf. Body { "delivery_id": <id>, "delivered_at": "<yyyy-MM-ddTHH:mm:ss>" }

Die GET/POST/PATCH-Sequenz pro Signatur (Schritte 13 bzw. 46) ist vom ERP-/Dokumentenverwaltungssystem so vorgegeben und wird hier nicht angepasst.

Der frühere zusätzliche Aufruf von _web_updateDelivery mit state = finished (historisch Schritt 7) ist entfallen: _web_finishDelivery setzt State und Lieferzeitpunkt jetzt atomar in einem einzigen UPDATE auf Belegkopf.

Offene Punkte

1. Doppelter Abschluss-Call — erledigt (2026-04-26)

Status: behoben. _web_updateDelivery wird im Abschluss-Flow nicht mehr aufgerufen. _web_finishDelivery schreibt _SV_DELIVERY_STATE und _SV_DELIVERY_DELIVERED_AT atomar in einem einzigen UPDATE auf Belegkopf und führt anschließend _removeArticles aus.

3. Hartcodierte Sequenz ohne Retry, generisches Error-Reporting

Die 7 Requests laufen strikt nacheinander mit await. Bei einem Fehler an einer beliebigen Stelle landet der Flow in TourBloc._handleError und emittiert eine generische Meldung "Fehler beim Abschließen der Lieferung", ohne den genauen Schritt zu nennen.

Risiken:

  • Partial-Failure-Zustände sind möglich:
    • Fehler in 13: keine Fahrer-Signatur, kein Abschluss.
    • Fehler in 46: Fahrer-Signatur ist hochgeladen, Kunden-Signatur nicht, Lieferung weiterhin offen.
    • Fehler in 7 (_web_finishDelivery): beide Signaturen liegen am ERP, State und Lieferzeitpunkt aber nicht gesetzt — Lieferung bleibt laufend. Da der Endpoint atomar ist, gibt es keinen Zwischen-Zustand "State gesetzt, Zeitstempel fehlt" oder umgekehrt.
  • Schlechtes Netz / Funkloch beim Fahrer ist Realität → Wahrscheinlichkeit ist nicht klein.
  • Fahrer kann den Schritt blind wiederholen, ohne zu wissen, ob Signaturen schon liegen → potenziell doppelte Bilddateien im DMS.
  • Diagnose im Support ist mühsam, weil die Fehlermeldung nichts zur Stelle sagt.

To-do (mittelfristig):

  • Pro Repository-Schritt eine eigene, sprechende Fehlermeldung ("Fahrersignatur konnte nicht gespeichert werden", "Kundensignatur …", "Lieferung konnte nicht als abgeschlossen markiert werden").
  • Idempotenz prüfen: lassen sich die Schritte 16 ohne Doppel-Effekt wiederholen? Falls ja, Retry-Strategie mit exponential backoff für Netzfehler. Falls nein, mit Backend abstimmen.
  • Server-Sicht "Wurde Schritt X für Lieferung Y schon erledigt?" einbauen, damit ein Wiederaufnehmen nach App-Crash/Neustart möglich ist.
  • Optional: Outbox-Pattern — Signaturen + Finish-Marker werden lokal persistiert und im Hintergrund hochgeladen, statt blockierend im UI.