86 lines
5.0 KiB
Markdown
86 lines
5.0 KiB
Markdown
# 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 `FinishDeliveryEvent` → `TourBloc._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 1–3 bzw. 4–6) 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 1–3: keine Fahrer-Signatur, kein Abschluss.
|
||
- Fehler in 4–6: 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 1–6 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.
|