Lessons Learned by Implementing Parties - UnionInternationalCheminsdeFer/OSDM GitHub Wiki

OSDM prototype between Amadeus as distributor and Sqills as provider

During the integration in the Amadeus platform of the content exposed by Sqills via their OSDM implementation, both Sqills and Amadeus realized that there were some areas subject to interpretation and that would deserve improvements either in the OSDM grammar or in its documentation.

Representation of ancillaries in the booking resources

Two optional ancillaries exists in the OSDM Sqills test dataset: bike and luggage. Bike is not considered a train-bound ancillary, while luggage is. Both ancillaries are returned at shopping step as optional ancillaries in the offer containing the admission for the passengers, but at booking time bike ends up in a dedicated offer, distinct from the one representing the admission and the luggage. The standard as of today lacks guidance on the expected offer structure (coherency with shopping step expected? functional meaning to be derived from the offer structure in booking, e.g. which elements could be refunded/exchanged together? But then why not having these information in a structured way instead?).

It could be worth to also document that it is expected that offers with optional reservations will keep the same structure between offer and booking.

passenger information

external references

This field is expected to be used only at shopping time, for the API client to be able to reconcile the passengers from the request with those in the reply without complex logic. However the grammar supports it in every step. It's a good point for the API user, but only if all railways implement it in the same way. Can we say that support is mandatory if received at offer time? At least for the shopping step?

Clarify in documentation that mandatory at offer time and test in verification process.

abstract

Mandatory in the grammar, however not meaningful as input attribute.

Optional

links

Mandatory in the grammar, however not meaningful as input attribute.

Optional

passengers in commonOfferPartAttributes

The whole passenger structure is part of commonOfferPartAttributes (with mandatory links and abstract), however in a shopping reply the only necessary information at this level is the passenger resource ID. Passengers with full details (in particular external references) are already in the tripOffer resource, the only verb that would not self-contain passenger information is GET /offers/{offerId}. At booking time, passengers are at the booking root level and there are no granular verbs to retrieve single offers. Two options:

  1. clearly document obligation to return passenger id despite its optionality in the grammar.
  2. replace passenger structure by mandatory passenger ID. Not HATEOAS, but highly effective.

Passenger is replaced by its PassengerId

segment.vehicle

number or line: one of the two mandatory?

Can we say in the description that either vehicle number of line number must be mandatory?

Clarify this in description to be tested in certification

can serviceBrand be mandatory?

Yes.

carrierName in offer.offerSummary.overallServiceClass

Attribute name is a bit misleading and induces to return in this field the name of the carrier, while it's expected to convey the service class name given by the carrier.

Rename carrierName to name

Admission.isReservationRequired

Is this attribute necessary? In an offer there is already the possibility to specify a mandatory reservation.

Remove isReservationRequired

refundable exchangeable

to which extent an offer can be returned as refundable=yes exchangeable=yes? Shall we give recommendation?

Define refundable=YES: "Refundable without a fee before the day of departure" define refundable=NO: "Not refundable or with a 100% fee"

Define exchangable=YES : "Exchangable without a fee before departure"

overallFlexibility, overallComfortClass, overallServiceClass

The semantic deserves some explanation.

overallFlexibility is mandatory, the only one, but at booking time overall attributes are not meaningful (offerSummary in its entirety is not meaningful).

Document semantics of overall: It expresses the intended service

Reliability of hand-generated mocks

Given the complexity of the structures and the time it took to manually validate in Amadeus the responses received from the Sqills prototype, I (Elisa - this is a personal opinion not discussed with Sqills) am a bit doubtful about the idea of splitting the work of manually generating mocks. In particular I fear:

  • differences in interpretations
  • human errors

A documentation with inconsistent examples may be more an hindrance that an help. How to ensure validation of the provided examples?

Sqills kindly provides more data for others to generate the mocked data.

Seat Reservation distribution between Bileto (AVL) as provider and Cendis (OneTicket) as distributor

(Work in progress) Sub-set of OSDM specification was provided by Bileto and implemented into OneTicket backend in order to distribute seat reservations to combine them with admissions issued by internal OneTicket system.

BLT-1: Inconsistent design of API to accept a Refund Offer

Documented in #204.

confirmedRefundOfferId is strange indeed

Fix: pass in state to be changed in body.

BLT-2 Offer vs Booking vs Fulfillment roles in model, allocation, expiration, status transition

In order to match internal workflow to OSDM, we had to match resources and their statuses to perform the booking process. We were partially successful with OSDM Models document.

BLT-2.1: First, we were unsure if, when Offer is provided, no query to actual capacity is performed into the inventory and no allocation from inventory is performed.

BLT-2.2: Second, we were wondering if Offer and Booking share the same TTL validity and if Offer is the entity to bare the expiration timestamp.

BLT-2.3: Offer vs Reservation validity. We expected Offer to carry sale validity (TTL of the Offer) and Reservation to carry the validity during the travel. However, it is opposite. This results in situation when we put Reservation into Booking, Reservation validity is in the past, however its Offer carries its correct validity presented during ticket inspection. Excerpt from Swagger:

  • Offer.validFrom/validTo: Defines the minimum validity period of the trip booked, meaning the period during which it will be possible to travel with the fulfillments for this offer.
  • Reservation.CommonOfferPartAttributes.validFrom/validTo: Validity of offer towards passenger

Add an optional attribute to indicate how long an offer's price is guaranteed to be available (if the underlying system supports it)

BLT-2.4: We also did not clearly understand from the specification in what step, the distributor confirms that the payment was successful. Out internal workflow requires explicit confirmation from the distributor about the payment. If that is any post-paid method such as invoice, we use “Remote Payment Method” for such case.

BLT-2.5: We expected Offers to be short-lived object that can be discarded after the Booking confirmation and/or Fulfillment and Booking to contain all snapshot data. Having to retain and reference the Offer is not clear for us.

BLT-3: Fulfillment

When producing paperless or A4 PDF representation of a Fulfillment, we were missing clear link between Fulfillment and snapshot data to render it on Fulfillment Document.

There is Fulfillment.offerParts collection, however OfferPartReference is not usable as-is. It contains an OfferPart.id but API does not define a consolidated GET endpoint for OfferParts regardless of sub-class. To use GET endpoints for Admissions, Reservations, Ancillaries, Fees separately, OfferPartReference shoud have property such as resource type.

Workaround was join all underlying data while querying from DB and do not walk through the API.

Needs fixing, Nicolas does the patch.

BLT-4: Ticket inspection

We were uncertain which code/control number should be presented for ticket inspection and/or for customer enquiries/refunds.

Initially we advised OneTicket to print Booking.reference onto their fulfillment documents (PDF or paper) but we later noticed the Fulfillment.controlNumber field.

Should we also change Fulfillment.status to CHECKEDIN when the first inspection is performed, and data send to backend system? Are there any OSDM requirements how to handle multiple check-ins, or is it provider-specific?

BLT-5: HTTP response on DELETE operation

Was HTTP 410 Gone considered as success response on delete operations, e.g. DELETE /booking/{{bookingId}}? This could also help differ response on first and consecutive deletion request when confirmed Booking is being deleted by distributor for a reason.

BLT-6: Cascade on deletion

Does deletion of a Booking cascades the delete operation onto Offers? There is not a separate deletion API endpoint to delete offers if the distributor wishes to clean-up unfinished transactions.

BLT-7: Ambiguous examples and documentation of Vehicle.serviceBrand

Documented in #211.