sequenceDiagram
    participant browser
    participant checkout-app
    participant gateway
    participant booking-engine
    participant train-inventory
    participant S3

    browser->>checkout-app: load /checkout?cartId=...

    activate browser
    activate checkout-app

    checkout-app->>gateway: holdCartProduct(cartId)
    activate gateway

    gateway->>booking-engine: holdCartProduct(cartId)<br/>(60s timeout)
    activate booking-engine

    booking-engine->>train-inventory: createBooking(cart.trains)
    activate train-inventory

    train-inventory->>S3: POST /booking<br/>(30s timeout)
    activate S3

    S3-->>train-inventory: provisional booking
    deactivate S3

    train-inventory-->>booking-engine: provisional booking
    deactivate train-inventory

    booking-engine->>booking-engine: save booking reference on cart

    booking-engine-->>gateway: booking reference
    deactivate booking-engine

    gateway-->>checkout-app: booking reference
    deactivate gateway

    checkout-app->>gateway: getCart(cartId)
    activate gateway

    gateway->>booking-engine: getCart(cartId)<br/>(60s timeout)
    activate booking-engine

    booking-engine-->>gateway: cart
    deactivate booking-engine

    gateway->>train-inventory: getCart.journeys
    activate train-inventory

    train-inventory->>S3: GET /booking/{reference}<br/>(30s timeout)
    activate S3

    S3->>train-inventory: provisional booking
    deactivate S3

    train-inventory-->>gateway: journeys read from booking
    deactivate train-inventory

    gateway-->>checkout-app: Cart with journeys
    deactivate gateway

    checkout-app-->>browser: /checkout?cartId=...
    deactivate checkout-app

    Note over browser,checkout-app: The browser inputs checkout info

    browser->>checkout-app: checkout mutation
    activate checkout-app

    checkout-app->>gateway: checkout mutation
    activate gateway

    gateway->>booking-engine: checkout mutation<br/>(60s timeout)
    activate booking-engine

    booking-engine->>train-inventory: updatePassengersAndAddCustomer()
    activate train-inventory

    train-inventory->>S3: POST /customer<br/>(30s timeout)
    activate S3
    S3-->>train-inventory: customer response
    deactivate S3

    train-inventory->>S3: PATCH /passengers<br/>(30s timeout)
    activate S3
    S3-->>train-inventory: passengers response
    deactivate S3

    train-inventory->>S3: GET /booking<br/>(30s timeout)
    activate S3
    S3-->>train-inventory: booking status
    deactivate S3

    train-inventory-->>booking-engine: updatePassengersAndAddCustomer response
    deactivate train-inventory

    booking-engine->>train-inventory: addPayments()
    activate train-inventory

    train-inventory->>S3: POST /payments<br/>(30s timeout)
    activate S3
    S3-->>train-inventory: payment response
    deactivate S3

    train-inventory->>S3: GET /booking<br/>(30s timeout)
    activate S3
    S3-->>train-inventory: booking status
    deactivate S3

    train-inventory-->>booking-engine: addPayments response
    deactivate train-inventory

    booking-engine->>train-inventory: confirmBooking()
    activate train-inventory

    train-inventory->>S3: POST /booking<br/>(30s timeout)
    activate S3
    S3-->>train-inventory: booking confirmation
    deactivate S3

    train-inventory->>S3: GET /booking<br/>(30s timeout)
    activate S3
    S3-->>train-inventory: final booking status
    deactivate S3

    train-inventory-->>booking-engine: confirmBooking response
    deactivate train-inventory

    booking-engine-->>gateway: checkout mutation response
    deactivate booking-engine

    gateway-->>checkout-app: checkout mutation response
    deactivate gateway

    checkout-app-->>browser: checkout complete
    deactivate checkout-app
    deactivate browser