# New booking wizard (booking checkout) [TOC] ## Flow ### Step A. Bookings availability check and booking creation ```plantuml @startuml autonumber actor frontend as front control backend as back database DB as db group Step A. Bookings availability check == Flow starts == == (User is not yet authorized) == front -> front : user picks a type of a service eg. **/covid-19 test/** front -> front : user picks the date of the booking front -> back : front queries for booking possibility for service and date note over front query { availableHours( zip: "0155", startDate: "2021-07-09", endDate: "2021-07-15", startHour: "12:00", endHour: "12:30" ) { availableBookings { spServices spTypesName spServicesNames startsAt endsAt date rebooking lat lng zip serviceProvider { id firstName lastName phoneNumber } } } } end note back -> db : fetches available Hours through matcher db -> back : results back -> front : serves results front -> front : user picks time (hour) of the booking from available options front -> back : new booking is created **IMPLICITLY** note over front mutation { createBooking( zip: "12345", lat: 11.11111, lng: 22.22222, serviceProviderId: 99, startHour: "12:00", endHour: "12:30", service: "covid-19-test") { id price } } <b>perhaps at this stage, booking does not</b> <b>yet have an order or lineItem attached to it (TBC)</b> end note == at this point we should be able \n to fetch price and display it in UI == front -> back : fetching price based on (service,patientCount, zip) note over front query { orderPrice( zip: "0160", lineItemAttributes: [ { serviceSlug: "hcl-vac-flu-or", quantity: 3 } ] ) } end note back -> back :calculates price back -> front: returns calculated price back -> back : new booking is validated back -> db : new booking is persisted back -> front : booking object returned front -> front : **<color red>user can proceed to next form step</color>** == (booking object is at this time already created) == end @enduml ``` ### Step B. Authentication ![](https://i.imgur.com/0vFYJAC.png) ```plantuml @startuml autonumber actor frontend as front control backend as back database DB as db entity "Otp provider" as otp group Step B. Authentication == (User not yet authorized) == front -> front : user picks the date & time of the booking front -> front : user inputs his phone num. front -> back : request new OTP session note over front, back mutation { newOtpSession(phoneNumber: "+4791222121") { otpCode } } end note back -> db : backend fetches user by phone number back -> back : if no user is found, new user obj is created back --> db : (optional) new user persisted back -> otp : requests OTP to send SMS with code otp --> front: (sends user an SMS to his phone) front -> front : user inputs OTP code he just got front -> back : front authorizes user with OTP note over front, back mutation { signInUserOtp(phoneNumber: "+4791222121", code: "4444") { id firstName lastName ... } } end note back -> db : backend updates user last sign in time etc. if user exists == or in case of user-to-be == front -> back : front authorizes user-to-be with OTP note over front, back mutation { signInOtp(phoneNumber: "+4791222121", code: "4444") { } } end note == active session is established, \nalthough user obj may not yet be created == front -> front : **<color red>user can proceed to next form step</color>** end @enduml ``` ### Step B1. (optional) Creating | Updating user (only if a user clicks **Endre oppysninger** btn, or is a new user. Otherwise user was supposed to confirm that his info are up-to-date) ```plantuml @startuml autonumber actor frontend as front control backend as back database DB as db group Step B Authentication front -> front : user fills his data form (address, email, name) front -> back : update user details note over front, back mutation { createUser | updateUser( id: 299, zip: "12345", email: "jens.eriksson@example.com", street: "SomeStreet 31") { id } } end note back -> back : validates user params \nin interactor (service obj) back -> db : persists updated user @enduml ``` ### Step C. Updating booking details ```plantuml @startuml autonumber actor frontend as front control backend as back database DB as db group Step C. Updating booking details front -> front : user fills booking address form note over front i.e. (address, zip, info on parking) info get to be saved on front for the time being (not yet sent to API) end note group adding Patients note over front i.e. (patients name, email, phone no, personnumber [is this ID number?]) info get to be saved on front for the time being (not yet sent to API) end note note over front #aqua we can consider sth like typeahead API-assisted feature to facilitate adding patients from those previously added end note front -> front : user fills patients form == after each addition of the patient price is updated == front -> back : fetching price based on (service,patientCount, zip) note over front query { orderPrice( zip: "0160", lineItemAttributes: [ { serviceSlug: "hcl-vac-flu-or", quantity: 3 } ] ) } end note back -> back :calculates price back -> front: returns calculated price and shows in the UI end front -> back : update Booking **<color blue>M:updateBooking(....)</color>** back -> back : params are passed to BookingUpdater\n interactor, validation etc. back -> db : persists updated booking front -> front : **<color red>user can proceed to next form step</color>** end @enduml ``` ![](https://i.imgur.com/YY3cFss.png) ### Step D. Confirm booking ```plantuml @startuml autonumber actor frontend as front control backend as back entity Stripe as stripe group Step D. Confirm booking == at this point we should make sure user made it possible for us\n to charge him with at least 1 payment method == front -> front : let user fill payment method form (business card only?) front --> stripe : updates payment information note over front #aqua that happens through stripe's own control most likely (tbc) end note front -> front : user clicks some button (Purchase, Confirm, whatever) front -> back : confirms booking and thus initiates order creation note over front, back mutation { createOrder | purchaseBooking :-) ( booking_id: 12345, paymentMethodId: 7894567 ) { redirectUrl id } } end note == at this point an order is created, along with the booking \n(order + line_item + linked booking that is) == note over front, back #aqua there goes some continuation of the payment flow, to be discussed at later stage end note front -> front : **<color red>user is taken to payment step (can vary depending on the method)</color>** @enduml ``` ### Step E. Payment ```plantuml @startuml autonumber actor frontend as front control backend as back entity Stripe as stripe @enduml ``` ## Doubts to discuss