openactive / modelling-opportunity-data

OpenActive Modelling Opportunity Data specification
https://www.openactive.io/modelling-opportunity-data/
Other
6 stars 6 forks source link

Ticketing / Density Party / High Frequency sessions #301

Open nickevansuk opened 2 years ago

nickevansuk commented 2 years ago

Proposer

imin, MCRactive, GLL, OpenPlay (also ref Legend, Gladstone, Everyone Active and Westminster)

Use Case

There is an opportunity type that is often expressed within different systems in different ways:

It is characterised by very frequent slots, as would be expected for a FacilityUse, however it is a "Session".

As well as data model implications, there's also UX implications for this use case: as there are often a very high number of sessions on a particular day.

An example can be found here: https://bookings.better.org.uk/location/cambridge-ice-arena/public-skating/2021-12-14/by-time

Illustrative examples include:

Comprehensive list of examples from GLL - Air Venture - Air-Max Inflatable - Aqua Play - Aqua Splash - Aqua Splash Slide - Casual Cycling Session - Cave - Climbing Wall - Clip n Climb - Coffee Skate - Disability Jump Session - Drop In Basketball - Family Fun Swim - Footgolf - General Jump Session - Golf - 18 holes - Inclusive Bounce - Inclusive Skate - Inclusive Swim - Junior Basketball - Junior Turbo - Laserquest - Leap of Faith - Multi Sports Drop In - Netball Drop In - Pay & Play Football - Pitch and Putt - Play Park - Public Skating - Rollerskating - Sensory Swim - Skate Park - Skate Park 3 Hour - Skate Park Beginners - Skate Park Under 16s - Soft Play - Soft Play Under 3's - Surf Belfast - Swim For All - Swim for All Outdoor - Swim for Free - Swim for Men & Boys - Swim for Women & Child - Swim for Women & Girls - Table Tennis Drop In - Toddler Bounce Session - Toddler Splash - Toddlers World - Turkish Baths - Female Only - Turkish Baths - Male Only - Turkish Baths Mixed - Ultimate Aqua Splash - Waterslides

Why is this not covered the existing data model?

The current OpenActive data model has two close matches:

The properties of these classes have some overlap. Properties that would be useful in this use case are highlighted in bold:

SessionSeries FacilityUse
accessibilityInformation accessibilityInformation
accessibilitySupport accessibilitySupport
activity facilityType
additionalAdmissionRestriction additionalAdmissionRestriction
ageRange  
ageRestriction  
attendeeInstructions attendeeInstructions
category category
contributor  
description description
duration  
endDate  
  event
eventAttendanceMode  
eventSchedule  
eventStatus  
genderRestriction  
  hoursAvailable
id id
identifier identifier
image image
  individualFacilityUse
isAccessibleForFree  
isCoached  
leader  
level  
location location
maximumAttendeeCapacity  
meetingPoint  
name name
offers offers
organizer provider
programme  
remainingAttendeeCapacity  
schedulingNote  
startDate  
subEvent  
superEvent  
type type
url url

Modelling options

Option 1: Use SessionSeries with some kind of highFrequencySession flag

Option 2: Use FacilityUse with some kind of highFrequencySession flag

Option 3: Create a new subclass of Event

Proposal

To simplify the modelling and reasoning about high frequency sessions, as well as ease implementation, a simple flag could be defined (Option 1 above), either:

a) beta:isScheduledAsSlots could live alongside schedulingNote in the Event b) beta:isHighFrequencySchedule could live within the Schedule or PartialSchedule

(a) is likely more robust, as eventSchedule is an array. Additionally for (a) eventSchedule could be optional when isScheduledAsSlots is set to true, which reduces the need to render a likely complex PartialSchedule of limited value.

For ease of implementation for booking systems that have relatively few high frequency schedules (i.e. so as not to create complexity by adding more feeds), it is important to still allow the use of Schedule / schedule expansion, even though it will likely not be presented to the user due to its complexity.

Additionally, hoursAvailable could be added to SessionSeries, only for use with isScheduledAsSlots.

nickevansuk commented 2 years ago

The proposed isScheduledAsSlots has been added as a beta property to aid implementation

(Class) Property Expected Type Description
(schema:Event)
beta:isScheduledAsSlots
schema:Boolean A property that indicates whether the event contains a high frequency of occurrences. Intended as a UI hint for interfaces that represent these occurrences.
drinkynet commented 2 years ago

So if I understand this proposal the defining characteristic of this use case is that you can have a scheduled time that multiple unconnected individuals can book separately up to a capacity limit?

Where is the line between a normal and a 'highFrequencySession' this feels a bit too subjective?

If you were going to use the FacilityUse/Slot model it feels like you'd need a capacity property which would default to 1 (the current slot scenario - each slot is bookable once). If the capacity was >1 this would both be the flag for slot allows multiple bookings and the limit, you could even set it to 0 for allow infinite bookings (a rare edge case i've seen on sessions).

Option 3 feels a better answer to the question, as you could define a multi-booking slot event as above. The disadvantages listed for Option 3 sound bad, but options 1 and 2 do not list business logic changes in existing systems to handle the model changes.

nickevansuk commented 2 years ago

Hey @drinkynet! Great comments!

Agreed it is a little subjective, and concretely within some systems it may be the case that a "high frequency session" actually only has a couple of occurrences in a specific day. A good example is "Family Swimming", which could only happen a couple of times a day in some pools, but happen hourly for the whole of Saturday and Sunday in another pool.

The idea with the proposal is that the organiser of the event would generally know whether the event they're describing is likely to be "high frequency", so the proposal above expects this to be a manual judgement by the organiser rather than an automatic judgement by the booking system. Continuing with the example, "Family Swimming" would be tagged as "high frequency" by the organizer as it's the kind of the session that is expected to occur in slots (even if on some days there are only a couple of slots scheduled).

Re: FacilityUse/Slot and a capacity property, noting that there's already a remainingUses property which represents the number of times the Slot can be booked - and introducing multiple properties to represent this (and multiple ways to book the same slot?) may create confusion/complexity?

Option 3 feels a better answer to the question, as you could define a multi-booking slot event as above. The disadvantages listed for Option 3 sound bad, but options 1 and 2 do not list business logic changes in existing systems to handle the model changes.

Yes agreed - there's a certain semantic purity to Option 3, though defining new subclasses is quite a substantial undertaking (from a spec and tooling perspective), and more difficult to promote in beta.

Perhaps having the beta:isScheduledAsSlots beta property as a short-term solution could be a pragmatic way to drive early adoption of this to improve existing data quality, and then when we look at incorporating this into the next point release of the Modelling Specification, we consider it as a new subclass and feed structure?

For example it could be two new feeds (perhaps with better names than these):

drinkynet commented 2 years ago

Re: FacilityUse/Slot and a capacity property, noting that there's already a remainingUses property which represents the number of times the Slot can be booked - and introducing multiple properties to represent this (and multiple ways to book the same slot?) may create confusion/complexity?

Ah, Interesting. I'm still learning how it all works :) if there is already a property that does the job there is no need for another one.

So, would this not already handle the case - meaning you could use the FacilityUse/Slot with a remainingUses above 1 to model this use case?

The idea with the proposal is that the organiser of the event would generally know whether the event they're describing is likely to be "high frequency", so the proposal above expects this to be a manual judgement by the organiser rather than an automatic judgement by the booking system…

Why does it need to be explicit rather than implicit?

In the booking system I'm involved with, slots are auto-generated from patterns and sessions are pre-defined by staff. It doesn't yet have a concept of sessions auto-generated from patterns, which is how I'm visualising this proposal.

nathansalter commented 2 years ago

So, would this not already handle the case - meaning you could use the FacilityUse/Slot with a remainingUses above 1 to model this use case?

I think the issue with this is that FacilityUse/Slot with remainingUses is reserved for handling a grouping of IndividualFacilityUse entities (e.g. a group of Squash Courts). So using this for the ticketing approach would definitely cause issues for some Booking systems (Bookteq Included). I think using SessionSeries makes the most sense from a purist point of view, but we'd need to put the ScheduledSession objects in a separate feed to reduce the amount of data transferred on purchase.

Not sure if this is already specified, but perhaps it would make sense to advise having separate SessionSeries and ScheduledSession RPDE feeds, as the former won't change very often, but the latter will have a high-rate of churn.

drinkynet commented 2 years ago

I think the issue with this is that FacilityUse/Slot with remainingUses is reserved for handling a grouping of IndividualFacilityUse entities (e.g. a group of Squash Courts).

I see from the linked definition that its a flag rather than a quantity, so it wouldn't work as I thought it might.

nathansalter commented 2 years ago

I think the issue with this is that FacilityUse/Slot with remainingUses is reserved for handling a grouping of IndividualFacilityUse entities (e.g. a group of Squash Courts).

I see from the linked definition that its a flag rather than a quantity, so it wouldn't work as I thought it might.

It's not quite a flag, the relevant part which I think is confusing is this:

Must be 0 or 1 for an IndividualFacilityUse.

So for FacilityUse instead of IndividualFacilityUse it can be higher than 1.

nickevansuk commented 2 years ago

Just catching up on this thread...

Not sure if this is already specified, but perhaps it would make sense to advise having separate SessionSeries and ScheduledSession RPDE feeds, as the former won't change very often, but the latter will have a high-rate of churn.

Yes indeed - this is certainly the recommendation in the docs for a while (ref: https://developer.openactive.io/publishing-data/data-feeds/types-of-feed#exposing-the-model-in-feeds)

nickevansuk commented 1 year ago

Also note that additional guidance should be provided: when "beta:isScheduledAsSlots": true, eventSchedule should be hidden. This ensures that an excessively large object is not generated as the value for this property unnecessarily.

Ref: https://github.com/openplayuk/gll-better/issues/10

lukehesluke commented 1 year ago

Data Model implications?

As well as data model implications, there's also UX implications for this use case: as there are often a very high number of sessions on a particular day.

What are the data model implications?

If I look at the definitions of SessionSeries in the spec and the Developer Docs, a high frequency swimming session doesn't seem to conflict with the definitions (though the examples in all the above documents refer to lower frequency sessions).

UX Implications

I can totally see the UX implications though. Until we encountered these it could have been assumed that facilities would require high-frequency optimised views (like a timetable) whereas sessions would require low-frequency optimised views.

Potential solutions:

  1. Opportunity data providers prescribe whether high- or low-frequency optimised views (or any other kinds of views) are used for a given SessionSeries (e.g. with this beta:isScheduledAsSlots field); OR
  2. Data consumers could make the decision themselves (across their own bespoke categories of views), e.g. based on the density of occurrences as detailed in the Schedule. One benefit of this approach is that it's flexible to UX innovations.
  3. Combination of 1) and 2) by allowing data providers to suggest "hints" as for how data is displayed, which the data consumer can choose to respond to as they please.

Hiding eventSchedule for High Frequency Sessions

@nickevansuk RE https://github.com/openactive/modelling-opportunity-data/issues/301#issuecomment-1282830185 how come? The GLL issue, https://github.com/openplayuk/gll-better/issues/10, states that schedules are not useful for high frequency sessions. Why is this? I'd have thought that this would be a particularly useful field for these kinds of sessions. e.g. if a data consumer wanted to display both low- and high-frequency sessions in a combined view (e.g. "what can I do near me tonight?"), they'd probably want to provide summarised scheduling info for each, for which the eventSchedule would be invaluable

Additionally, it would seem that the eventSchedule allows for large amounts of scheduling data to be compressed (which is a very good thing for high-frequency sessions!) because a Schedule can dictate that a session runs "every 10 minutes from 09:00 to 18:00 on Mondays" without having to express that using 54 distinct ScheduledSessions (though of course individual ScheduledSessions are required to indicate used up capacity or any changes to individual times). Is the underlying issue that Better has labyrinthine scheduling info that defies any possibility of being categorised into simple ideas like "every 10 minutes from 09:00 to 18:00 on Mondays" or is it that Schedule itself is not sufficiently sophisticated to capture what is actually a relatively simple schedule? Because if it is the latter, then could we resolve it by iterating on Schedule until it works well for these high-frequency use cases?