blob: e25bd0e6145c0f17e4a41bd9629c01a6d77bb2f7 [file] [log] [blame]
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;
}