bookwhen / opendata

Documentation, Changelog and Issues related to the Bookwhen RPDE endpoint
0 stars 1 forks source link

Update structure to be much more conformant to the validator #11

Open lukehesluke opened 4 years ago

lukehesluke commented 4 years ago

Hi @jopotts ,

Thanks for our call earlier. Further to that, here's some notes about how you might update your feed to be sufficiently conformant so that the feeds can be ingested by our "universal" adapter which should hopefully be quick wins.

I've included an example for a SessionSeries with a Schedule at the end, which might be easier to digest than a big list of changes

Changes

For event_type in general:

For an event_type with a recurrence rule

For an event_type with just one occurrence:

For an event:

Example

This is a SessionSeries with a Schedule. This is how it looks presently:

{
  "@context": [
    "https://www.openactive.io/ns/oa.jsonld",
    "https://www.openactive.io/ns-beta/oa.jsonld"
  ],
  "type": "Event",
  "identifier": "eventType-g6puavnqax9i",
  "name": "Street / 3 - 6 years - TRIAL CLASS ",
  "description": "Funky street dance class for children with lots of attitude and style. Perfect for children of all abilities",
  "category": [],
  "url": "https://bookwhen.com/ddc-kiveton?r=oa",
  "activity": [],
  "offer": [],
  "maximumAttendeeCapacity": 8,
  "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
  "beta:formattedDescription": "<p>Funky street dance class for children with lots of attitude and style. Perfect for children of all abilities</p>\n",
  "organizer": {
    "type": "Organization",
    "identifier": "organization-1fihlz2a8ot5",
    "name": "Studio 44",
    "email": "hello@studio-44.co.uk",
    "telephone": "01246641000",
    "beta:website": "https://www.studio-44.co.uk"
  },
  "location": {
    "type": "Place",
    "identifier": "location-d94pg2jx4unp",
    "description": "",
    "address": "St John&#39;s Room 107 Wales Road\nKiveton Park\nSheffield\nS26 6RA",
    "geo": {
      "latitude": 53.340761,
      "longitude": -1.2731072
    }
  },
  "subEvent": [
    {
      "type": "Event",
      "duration": "PT45M",
      "beta:urlTemplate": "https://bookwhen.com/ddc-kiveton/e/ev-sdfo-{YYYYMMDDHHMISS}?r=oa",
      "eventSchedule": {
        "type": "Schedule",
        "startDate": "2019-02-11",
        "frequency": "weekly",
        "byDay": [
          "https://schema.org/Monday"
        ],
        "startTime": "16:45",
        "endTime": "17:30",
        "exceptDate": [
          "2019-05-06T15:45:00Z",
          "2019-05-27T15:45:00Z"
        ],
        "interval": 1
      }
    }
  ]
}

This is how it would look with the changes detailed above:

{
  "@context": [
    "https://openactive.io/",
    "https://openactive.io/ns-beta"
  ],
  "type": "SessionSeries",
  "id": "https://bookwhen.com/api/openactive/session-series/pysafz84ka8vp",
  "identifier": "g6puavnqax9i",
  "name": "Street / 3 - 6 years - TRIAL CLASS ",
  "description": "Funky street dance class for children with lots of attitude and style. Perfect for children of all abilities",
  "category": [],
  "url": "https://bookwhen.com/ddc-kiveton?r=oa",
  "activity": [],
  "offers": [],
  "maximumAttendeeCapacity": 8,
  "eventAttendanceMode": "https://schema.org/OfflineEventAttendanceMode",
  "beta:formattedDescription": "<p>Funky street dance class for children with lots of attitude and style. Perfect for children of all abilities</p>\n",
  "organizer": {
    "type": "Organization",
    "identifier": "organization-1fihlz2a8ot5",
    "name": "Studio 44",
    "email": "hello@studio-44.co.uk",
    "telephone": "01246641000",
    "beta:website": "https://www.studio-44.co.uk"
  },
  "location": {
    "type": "Place",
    "identifier": "location-d94pg2jx4unp",
    "description": "",
    "address": "St John&#39;s Room 107 Wales Road\nKiveton Park\nSheffield\nS26 6RA",
    "geo": {
      "type": "GeoCoordinates",
      "latitude": 53.340761,
      "longitude": -1.2731072
    }
  },
  "eventSchedule": [
    {
      "type": "Schedule",
      "scheduledEventType": "ScheduledSession",
      "scheduleTimezone": "Europe/London",
      "beta:urlTemplate": "https://bookwhen.com/ddc-kiveton/e/ev-sdfo-{YYYYMMDDHHMISS}?r=oa",
      "startDate": "2019-02-11",
      "repeatFrequency": "P1W",
      "byDay": [
        "https://schema.org/Monday"
      ],
      "startTime": "16:45",
      "endTime": "17:30",
      "duration": "PT45M",
      "exceptDate": [
        "2019-05-06T15:45:00Z",
        "2019-05-27T15:45:00Z"
      ]
    }
  ]
}
nickevansuk commented 4 years ago

@lukehesluke looks great! Just a couple of additions...

There is a new virtual events requirement for organizer @id (https://developer.openactive.io/publishing-data/virtual-events#conformance-criteria), based on what Sport England require for #StayInWorkOut - hopefully simple to add.

So the above would look something like this (using the preferred @type and @id for better compatibility with JSON-LD, though type and id are still valid):

  "organizer": {
    "@type": "Organization",
    "@id": "https://id.bookwhen.com/organizer/1fihlz2a8ot5",
    "identifier": "organization-1fihlz2a8ot5",
    "name": "Studio 44",
    "email": "hello@studio-44.co.uk",
    "telephone": "01246641000",
    "url": "https://www.studio-44.co.uk"
  },

Additionally, to pass validation properties with values that are empty arrays and empty strings must be omitted.

domfennell commented 4 years ago

Hi @jopotts,

We thought it might be helpful to split @lukehesluke's suggestions into 3 categories ("Simple re-names / moving fields around", "Logic changes" and "Nice-to-haves") to make it easier for you. Hopefully this will save you time and allow you to focus on those quick-win changes ("simple re-names / moving fields around" - maybe <30 mins total time?) that will bring your feed more inline with the Spec. and allow your virtual classes to be advertised across user-facing platforms.

Simple re-names / moving fields around

(we estimate <30 mins total time for all of these)

For event_type in general:

For event_type with a recurrence rule:

For an event_type with just one occurrence:

For an event:

Logic changes

(we estimate 30-35 mins total time for both of these - the first one could take less than 5 minutes!)

Nice-to-haves

nickevansuk commented 4 years ago

@gregjoy1 as discussed issues below:

1 Split into three feeds

So there should be three feeds here: a SessionSeries and ScheduledSession feed pair for recurring events (documentation), and an Event feed for one-off events (documentation).

2 activity is missing

https://bookwhen.com/api/openactive/session_series?afterId=5wkobfev8rwr&afterTimestamp=1573822146

Has activity been accidentally missed here?

Example below:

"activity": [
  {
    "@type": "Concept",
    "@id": "https://openactive.io/activity-list#5e78bcbe-36db-425a-9064-bf96d09cc351",
    "prefLabel": "Bodypump™",
    "inScheme": "https://openactive.io/activity-list"
  }
]

4 price must be a decimal

https://bookwhen.com/api/openactive/session_series?afterId=5wkobfev8rwr&afterTimestamp=1573822146

"price": "5.00"

should be

"price": 5.00

5 Use beta:virtualLocation for online events

https://bookwhen.com/api/openactive/session_series?afterId=5wkobfev8rwr&afterTimestamp=1573822146

location is not permitted for online-only events

  "location": {
    "type": "Place",
    "identifier": "izdxleom4a4b",
    "description": "Example description",
    "name": "Online"
  },

should be replaced by

   "beta:virtualLocation": {
     "@type": "VirtualLocation",
     "identifier": "izdxleom4a4b",
     "description": "Example description",
     "name": "Online"
   }

6 eventAttendanceMode only required in SessionSeries

eventAttendanceMode is not required in ScheduledSession, unless it has a different value from the related parent SessionSeries.

7 Use @type and @id consistently

8 Remove empty strings and empty arrays

Properties should not be included where their value is an empty string and or empty array, or an empty object that contains only an @type (e.g. below):

"ageRange": {
"@type": "QuantitativeValue"
},

The OpenActive Ruby library will do this for you.

nickevansuk commented 4 years ago

@gregjoy1 just reviewed the latest feeds, great work so far! Fresh feedback below:

1 Use Schedule without beta properties

Include the idTemplate and urlTemplate as specified in https://developer.openactive.io/publishing-data/schedules. Note for your usecase we recommend creating a simple 301 redirect that takes users from e.g. https://bookwhen.com/openactive/events/s51e/2018-04-25T18-00-00Z (or whatever urlTemplate you use) to e.g. https://bookwhen.com/hulafit/e/ev-s51e-20180425180000 This means you can stop using the long-since deprecated beta:urlTemplate.

2 Event capacity

remainingAttendeeCapacity and beta:attendanceCount appear to be missing from https://bookwhen.com/api/openactive/events

3 price must be a decimal

https://bookwhen.com/api/openactive/session_series?afterId=5wkobfev8rwr&afterTimestamp=1573822146

"price": "5.00"

should be

"price": 5.00

4 url should be used instead of beta:website

"organizer": {
  "@type": "Organization",
  "@id": "https://bookwhen.com/api/openactive/organizers/uwdefqoiez8h",
  "beta:website": "http:/www.kasostudios.co.uk",
  ...
},

Should be

"organizer": {
  "@type": "Organization",
  "@id": "https://bookwhen.com/api/openactive/organizers/uwdefqoiez8h",
  "url": "http:/www.kasostudios.co.uk",
  ...
},

5 eventAttendanceMode only required in SessionSeries

eventAttendanceMode is not required in ScheduledSession, unless it has a different value from the related parent SessionSeries.

6 Add a courses feed

I've just noticed the property "beta:course": true, and realised that Bookwhen also supports courses! Courses should in fact be a separate feed at /course-instances using the CourseInstance type, as they are different to regularly scheduled sessions.

See here for an example: https://validator.openactive.io/?url=https%3A%2F%2Fopenactive.io%2Fdata-models%2Fversions%2F2.x%2Fexamples%2Fcourseinstance_event_example_1.json&version=2.x

Note that you don't need to include beta:course property referenced in the example, just put everything that was in the SessionSeries into the CourseInstance.

Also you'll need to add the course-related subEvents to that feed instead of putting them in the ScheduledSession feed (as per example)

7 byDay is an array

"byDay": "1SU", should be "byDay": [ "1SU" ],

gregjoy1 commented 4 years ago

Hi @nickevansuk, @domfennell and @lukehesluke, thank you all for helpfully and clearly setting out these requirements, sorry for the delay in responding to them. We have recently released the requested updates :)

The only thing not included is 3, this is because the JSON serialiser we use at Bookwhen always casts decimals as strings - https://apidock.com/rails/BigDecimal/as_json

It appears the OA Gem also has the same constraint as it also returns strings for decimals - https://github.com/openactive/models-ruby

Is it possible to quietly still consume it considering its known to be a decimal? :)

Also are these changes enough for us to be consumed in your universal feed reader yet? :)

nickevansuk commented 4 years ago

Thanks @gregjoy1! Will take a proper look after the dataset site is updated too.

However one quick thing, free activities (where "isAccessibleForFree": true) for events, courses, and sessions should also include a zero priced Offer (priceCurrency is not required), e.g.:

        "offers": [
          {
            "@type": "Offer",
            "price": 0
          }
        ],
gregjoy1 commented 4 years ago

Hi @nickevansuk, @domfennell and @lukehesluke, the updated the dataset site can be found here - https://data.bookwhen.com/ :)

nickevansuk commented 4 years ago

Great work @gregjoy1 - one small note: you seem to be using a background image hot-linked to another dataset site (https://data.better.org.uk/images/bg.jpg).

Perhaps replace it with something hosted on your own CDN? There's a great selection or relevant free images here: https://unsplash.com/photos/gJtDg6WfMlQ

nickevansuk commented 4 years ago

Also please feel free to delete this old repo: https://github.com/bookwhen/openactive-datasite, so that it's easy to see from the forks that you've migrated successfully.

nickevansuk commented 4 years ago

Hey @gregjoy1, so this round of feedback is by way of extracts in the validator.

Please address the errors shown in the validator for each of the following:

Note: It's fine to keep those items in that are missing activity, though perhaps stronger signposting to let users know they need to fill in this field could be useful?

Will have a think about about the issue with price... TeamUp have also had the same issue. See proposal here

gregjoy1 commented 4 years ago

Thanks @nickevansuk, il get this into an upcoming sprint :)

thill-odi commented 4 years ago

I recommend closing this issue, as all issues listed above have been checked and are resolved (except for price, which needs to be addressed in the standard and the validator).