BIG FAT
This commit is contained in:
85
docs/finish_delivery.md
Normal file
85
docs/finish_delivery.md
Normal file
@ -0,0 +1,85 @@
|
||||
# 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.
|
||||
Reference in New Issue
Block a user