Przejdź do treści

Przepływy — pełna dokumentacja flow paczki

Wszystkie przepływy systemowe od stworzenia paczki przez API zewnętrznego systemu, przez ładowanie na kiosku, aż po odbiór — z każdym wariantem, statusem, eventem i powiadomieniem.

Wersja referencyjna

Dokumentacja zgodna z kioskiem v1.1.21 i backendem etap 5.1. Każda zmiana w state machine wymaga update'u tego dokumentu.

Zmiana metody komunikacji ze sprzętem (etap 9+)

Diagramy poniżej pokazują warstwę „Hardware" jako mastera Modbus (hardware.open(N) — Modbus pulse). To był stan do etapu 5. Dziś kiosk nie steruje sprzętem bezpośrednio — woła agenta SmartConf po lokalnym API 127.0.0.1:8800 (POST /v1/doors/{N}/open lub POST /v1/jobs/open + poll). Logika flow (open → włóż/wyjmij → close → status) pozostaje identyczna — zmienił się tylko transport. Pełny opis → Komunikacja kiosk ↔ agent. Wszędzie gdzie diagram mówi „Modbus", czytaj „agent SmartConf /v1".

Mapa dokumentów

Dokument Co opisuje
Tworzenie paczki API zewnętrzne → POST /shipments → CREATED
Ładowanie (deposit) Kurier na kiosku, wszystkie 10 wariantów ładowania
Odbiór (pickup) Odbiorca na kiosku, wszystkie 9 wariantów odbioru
Powiadomienia i webhooki Co dostaje recipient, ops i external system
Edge cases Wygaśnięcie, anulowanie, fault reporty, brak hardware

State machine paczki (globalny)

stateDiagram-v2
    [*] --> CREATED: POST /shipments
    CREATED --> ASSIGNED: courier login + kod nadania<br/>(deposit/begin-existing)
    CREATED --> CANCELLED: admin anuluj
    ASSIGNED --> DEPOSITED: drzwi zamknięte<br/>POST /shipments/:id/deposited
    ASSIGNED --> CREATED: fault podczas open<br/>(deposit/abandon-locker)
    ASSIGNED --> CANCELLED: admin anuluj
    DEPOSITED --> PICKED_UP: recipient login + open + close<br/>POST /pickup/:id/complete
    DEPOSITED --> CREATED: deposit/cancel-after-deposit<br/>(operator: paczki nie ma w skrytce)
    DEPOSITED --> EXPIRED: cron (>7 dni bez odbioru)
    DEPOSITED --> CANCELLED: admin anuluj
    PICKED_UP --> [*]
    CANCELLED --> [*]
    EXPIRED --> [*]

State machine skrytki (per Locker)

stateDiagram-v2
    [*] --> FREE: rejestracja maszyny
    FREE --> RESERVED: deposit/begin-existing<br/>(pickup wolnego slotu rozmiaru)
    RESERVED --> OCCUPIED: markDeposited<br/>(drzwi zamknięte z paczką)
    RESERVED --> BROKEN: deposit/abandon-locker<br/>(fault podczas open)
    RESERVED --> FREE: shipment cancelled<br/>(przed włożeniem paczki)
    OCCUPIED --> FREE: markPickedUp<br/>(recipient odebrał) LUB<br/>deposit/cancel-after-deposit
    OCCUPIED --> BROKEN: pickup "Zgłoś obsłudze"<br/>(sensor disagrees)
    BROKEN --> FREE: admin reset z panelu

Phase machine kiosku (LockerOpenScreen)

Wewnętrzna logika UI kiosku podczas otwierania jednej skrytki — używana zarówno w deposit jak pickup. Każda transition może wpaść w fault.

stateDiagram-v2
    [*] --> opening: enter screen
    opening --> open: 'opened' event z mastera<br/>LUB pre-flight: drzwi już otwarte
    opening --> userConfirmOpened: 20s watchdog<br/>brak 'opened'
    opening --> faultReported: master E07 / driver timeout<br/>(_phasePriorToFault=opening)
    opening --> failed: driver throw exception
    userConfirmOpened --> open: user TAK
    userConfirmOpened --> failed: user NIE<br/>(_phasePriorToFault=userConfirmOpened)
    open --> closed: 'closed' event<br/>(LUB fallback poll co 2s)
    open --> userConfirmClosed: 20s bez close
    open --> faultReported: master fault<br/>(_phasePriorToFault=open)
    userConfirmClosed --> closed: user TAK + re-poll OK
    userConfirmClosed --> open: user DOCIŚNIJ
    userConfirmClosed --> faultReported: user Zgłoś obsłudze<br/>(_phasePriorToFault=userConfirmClosed)
    closed --> done: onClosed() OK<br/>(markDeposited/markPickedUp)
    done --> [*]: pop with 'success'<br/>(po reopen panel: Zakończ / timeout 10s)
    faultReported --> opening: retry (jeśli _phasePriorToFault==opening)
    faultReported --> [*]: pop with 'fault' (Anuluj)
    failed --> opening: retry
    failed --> [*]: pop with 'fault' (Anuluj)

v1.1.20 / v1.1.21 — krytyczne reguły

  • _onCloseDetected ignoruje close event jeśli phase != open (v1.1.20) — chroni przed sensor flicker po fault dialog
  • "Spróbuj ponownie" widoczne TYLKO gdy _phasePriorToFault == opening (v1.1.21) — re-firing unlock pulse na już-otwartych drzwiach jest no-op

Trzy warstwy stanu

Każda operacja modyfikuje stan na trzech warstwach — wszystkie muszą być spójne:

Warstwa Co trzyma Kto zmienia
Fizyczna (hardware) Pozycja zamka + sensor drzwi Modbus master + operator fizycznie
Backend DB Shipment.status, Locker.status, timestamps Endpointy backend
Kiosk UI _Phase LockerOpenScreen + ekrany Deposit/Pickup{Success,Failure}Screen Lokalna state machine

Spójność statusów (operator wymaganie)

Status w panelu MUSI zawsze odpowiadać temu co user widział na kiosku. Jeśli kiosk pokazał "Paczka nienadana" 🔴 — backend musi mieć CREATED, nie DEPOSITED. Wszystkie znane przypadki niespójności naprawione w v1.1.20 (_onCloseDetected guard).

Konwencje w diagramach

  • 🟢 zielony screen = sukces ("Paczka nadana" / "Paczka odebrana")
  • 🔴 czerwony screen = porażka ("Paczka nie została nadana")
  • 🟡 żółty/orange screen = fault dialog (problem techniczny / Zgłoszenie wysłane / Drzwi nie zostały zamknięte)
  • USER fault report = Zgłoś obsłudze button pressed
  • MACHINE fault report = auto-detected hardware fault (E07, E16, driver timeout)