| syntax = "proto3"; |
| |
| package maps.booking.feeds; |
| |
| message FeedMetadata { |
| enum ProcessingInstruction { |
| // By default we will assume that this feed is an incremental feed. |
| PROCESS_UNKNOWN = 0; |
| |
| // This Feed message is one shard of a complete feed. Anything previously |
| // supplied by this partner will be deleted; the contents of this feed |
| // represent the entire state of the world. |
| PROCESS_AS_COMPLETE = 1; |
| |
| // This Feed message is one shard of an incremental feed. Existing entities |
| // will be left untouched except as modified in this feed. |
| PROCESS_AS_INCREMENTAL = 2; |
| } |
| |
| // Instructs us how to process the feed: either as a shard of a complete feed, |
| // or as a shard of an incremental update. |
| ProcessingInstruction processing_instruction = 1; |
| |
| // The current shard and total number of shards for this feed. |
| // |
| // Shard number is assumed to be zero-based. |
| // |
| // There does not need to be any relationship to the file name. |
| // |
| // Shards do not need to be transferred in order, and they may not be |
| // processed in order. |
| int32 shard_number = 2; |
| int32 total_shards = 3; |
| |
| // An identifier that must be consistent across all shards in a feed. |
| // This value must be globally unique across each feed type. |
| // |
| // This value ensures that complete feeds spanning multiple shards are |
| // processed together correctly. |
| // |
| // Clients only need to set this value when the processing_instruction is set |
| // to PROCESS_AS_COMPLETE and the feed spans multiple shards (defined by |
| // total_shards). |
| // |
| // Feeds that span multiple shards must set this nonce to the same value. |
| uint64 nonce = 5; |
| |
| // The timestamp at which this feed shard was generated. |
| // |
| // In Unix time format (seconds since the epoch). |
| int64 generation_timestamp = 4; |
| } |
| |
| message AvailabilityFeed { |
| FeedMetadata metadata = 1; |
| repeated ServiceAvailability service_availability = 2; |
| } |
| |
| message ServiceAvailability { |
| // If provided, we will consider the Availability entities provided to be a |
| // complete snapshot from [start_timestamp_restrict, end_timestamp_restrict). |
| // That is, all existing availability will be deleted if the following |
| // condition holds true: |
| // |
| // start_timestamp_restrict <= Availability.start_sec && |
| // Availability.start_sec < end_timestamp_restrict |
| // |
| // If a resource_restrict message is set, the condition is further restricted: |
| // |
| // Availability.resource.staff_id == resource_restrict.staff_id && |
| // Availability.resource.room_id == resource_restrict.room_id |
| // |
| // These fields are typically used to provide a complete update of |
| // availability in a given time range. |
| // |
| // Setting start_timestamp_restrict while leaving end_timestamp_restrict unset |
| // is interpreted to mean all time beginning at start_timestamp_restrict. |
| // |
| // Setting end_timestamp_restrict while leaving start_timestamp_restrict unset |
| // is interpreted to mean all time up to the end_timestamp_restrict. |
| // |
| // In Unix time format (seconds since the epoch). |
| int64 start_timestamp_restrict = 1; |
| int64 end_timestamp_restrict = 2; |
| |
| // If provided, the timestamp restricts will be applied only to the given |
| // merchant or service. |
| // |
| // These fields are typically used to provide complete snapshot of |
| // availability in a given range (defined above) for a specific merchant or |
| // service. |
| // |
| // Leaving these fields unset, or setting these to the empty string or null, |
| // is interpreted to mean that no restrict is intended. |
| string merchant_id_restrict = 3; |
| string service_id_restrict = 4; |
| |
| // Setting resources_restrict further restricts the scope of the update to |
| // just this set of resources. All id fields of the resources must match |
| // exactly. |
| Resources resources_restrict = 6; |
| |
| repeated Availability availability = 5; |
| } |
| |
| // An availability of the merchant's service, indicating time and number |
| // of spots. |
| // The availability feed should be a list of this message. |
| // Please note that it's up to the partner to call out all the possible |
| // availabilities. |
| // If a massage therapist is available 9am-12pm, and they provide |
| // one-hour massage sessions, the aggregator should provide the feed as |
| // availability {start_sec: 9am, duration: 60 minutes, ...} |
| // availability {start_sec: 10am, duration: 60 minutes, ...} |
| // availability {start_sec: 11am, duration: 60 minutes, ...} |
| // instead of |
| // availability {start_sec: 9am, duration: 180 minutes, ...} |
| // |
| message Availability { |
| // An opaque string from an aggregator to identify a merchant. |
| string merchant_id = 1; |
| // An opaque string from aggregator to identify a service of the |
| // merchant. |
| string service_id = 2; |
| // Start time of this availability, using epoch time in seconds. |
| int64 start_sec = 3; |
| // Duration of the service in seconds, e.g. 30 minutes for a chair massage. |
| int64 duration_sec = 4; |
| // Number of total spots and open spots of this availability. |
| // E.g. a Yoga class of 10 spots with 3 booked. |
| // availability {spots_total: 10, spots_open: 7 ...} |
| // E.g. a chair massage session which was already booked. |
| // availability {spots_total: 1, spots_open: 0 ...} |
| // |
| // Note: If sending requests using the availability compression format defined |
| // below, these two fields will be inferred. A Recurrence |
| // implies spots_total=1 and spots_open=1. A ScheduleException implies |
| // spots_total=1 and spots_open=0. |
| int64 spots_total = 5; |
| int64 spots_open = 6; |
| // An optional opaque string to identify this availability slot. If set, it |
| // will be included in the requests that book/update/cancel appointments. |
| string availability_tag = 7; |
| |
| // Optional resources used to disambiguate this availability slot from |
| // others when different staff, room, or party_size values are part |
| // of the service. |
| // |
| // E.g. the same Yoga class with two 2 instructors. |
| // availability { resources { staff_id: "1" staff_name: "Amy" } |
| // spots_total: 10 spots_open: 7 } |
| // availability { resources { staff_id: "2" staff_name: "John" } |
| // spots_total: 5 spots_open: 2 } |
| Resources resources = 8; |
| |
| // A list of ids referencing the payment options which can be used to pay |
| // for this slot. The actual payment options are defined at the Merchant |
| // level, and can also be shared among multiple Merchants. |
| // |
| // This field overrides any payment_option_ids specified in the service |
| // message. Similarly payment_option_ids specified here do NOT have to be |
| // present in the service message, though must be defined at the |
| // Merchant level. |
| repeated string payment_option_id = 9; |
| |
| // Recurrence messages are optional, but allow for a more compact |
| // representation of consistently repeating availability slots. They typically |
| // represent a day's working schedule. |
| // ScheduleException messages are then used to represent booked/unavailable |
| // time ranges within the work day. |
| // |
| // Requirements: |
| // 1. The expansion of availability slots or recurrences must NOT create |
| // identical slots. If the ids, start_sec, duration_sec, and resources |
| // match, slots are considered identical. |
| // 2. Do NOT mix the standard availability format and recurrence within the |
| // slots of a single service. Recurrence benefits merchants/services that |
| // offer appointments. The standard format is geared towards |
| // merchants/services with regularly scheduled classes. |
| message Recurrence { |
| // The inclusive maximum UTC timestamp the availability repeats until. |
| int64 repeat_until_sec = 1; |
| // Defines the time between successive availability slots. |
| // |
| // E.g. An availability with a duration of 20 min, a repeat_every_sec of |
| // 30 min, a start_sec of 9:00am, and a repeat_until_sec of 11:00am will |
| // yield slots at 9-9:20am, 9:30-9:50am, 10-10:20am, 10:30-10:50am, |
| // 11-11:20am. |
| int32 repeat_every_sec = 2; |
| } |
| // The recurrence information for the availability, representing more than one |
| // start time. A recurrence should contain appointments for one working day. |
| Recurrence recurrence = 10; |
| |
| // ScheduleException messages are used to represent booked/unavailable time |
| // ranges within the work day. As time slots are booked, the list of |
| // exceptions should grow to reflect the newly unavailable time ranges. |
| // The recurrence itself shouldn't be modified. |
| message ScheduleException { |
| // The time range of the exception. |
| TimeRange time_range = 1; |
| } |
| // When this service cannot be scheduled. To limit the number of |
| // schedule_exception messages consider joining adjacent exceptions. |
| repeated ScheduleException schedule_exception = 11; |
| } |
| |
| // A resource is used to disambiguate availability slots from one another when |
| // different staff, room or party_size values are part of the service. |
| // Multiple slots for the same service and time interval can co-exist when they |
| // have different resources. |
| message Resources { |
| // Optional id for a staff member providing the service. This field identifies |
| // the staff member across all merchants, services, and availability records. |
| // It also needs to be stable over time to allow correlation with past |
| // bookings. |
| // This field must be present if staff_name is present. |
| string staff_id = 1; |
| |
| // Optional name of a staff member providing the service. This field will be |
| // displayed to users making a booking, and should be human readable, as |
| // opposed to an opaque identifier. |
| // This field must be present if staff_id is present. |
| string staff_name = 2; |
| |
| // An optional id for the room the service is located in. This field |
| // identifies the room across all merchants, services, and availability |
| // records. It also needs to be stable over time to allow correlation with |
| // past bookings. |
| // This field must be present if room_name is present. |
| string room_id = 3; |
| |
| // An optional name for the room the service is located in. This |
| // field will be displayed to users making a booking, and should be human |
| // readable, as opposed to an opaque identifier. |
| // This field must be present if room_id is present. |
| string room_name = 4; |
| |
| // Applicable only for Dining: The party size which can be accommodated |
| // during this time slot. A restaurant can be associated with multiple Slots |
| // for the same time, each specifying a different party_size, if for instance |
| // 2, 3, or 4 people can be seated with a reservation. |
| int32 party_size = 5; |
| } |
| |
| message TimeRange { |
| int64 begin_sec = 1; |
| int64 end_sec = 2; |
| } |