Booking
A Booking is a concept that limits/enforces valid groupings of inventory that can be purchased together at the same time. They are the authoritative record of a customer committing to a specific Product, capturing the exact Inventory consumed, the policy snapshots applied, and the operational state of the reservation at the moment it was created. They are the ledger entry that ties together customer intent, product configuration, Inventory allocation, and pricing logic, forming the durable truth the rest of the system reacts to.
A Booking exists as an isolated, self-contained unit because the system must be able to reason about its contents deterministically. It represents the valid range of inventory groupings that can be purchased together under a single, coherent set of policies. Just as Inventory is the atomic unit of availability, a Booking is the atomic unit of reservation, though the rules around what constitutes a Booking vary much more broadly than Inventory.
Similar to how ProductDates are the date-specific execution of Products, Bookings too have date-specific instances called BookingDates. Each BookingDate corresponds to a specific date within the overall Booking period, allowing the system to track and manage availability and allocations on a per-day basis. This design enables the system to handle complex scenarios like multi-day bookings, partial cancellations, and date-specific adjustments while maintaining a clear and consistent record of the booking history. Each BookingDate is associated with the relevant ProductDate and Inventory units for that date, ensuring that all changes to the booking are accurately reflected in the system's state and availability calculations.
Properties
Booking
| property |
type |
description |
derived from |
evaluated when |
pk |
String |
Partition key |
booking::collectionId:: activityType::activityId:: productId |
Searching for all Bookings related to a specific Product. |
sk |
String |
Sort key |
arrivalDate::bookingId |
Searching for a specific Booking related to a specific Product (disambiguated by bookingId) |
gsipk |
String |
Global secondary index partition key |
userSub |
Querying for all Bookings made by a specific customer |
gsisk |
String |
Global secondary index sort key |
arrivalDate |
Sorting a customer's Bookings by arrival date |
schema |
String |
Data type/Schema |
"booking" |
Identifying that this item is a "booking" |
globalId |
String |
Globally unique UUID |
Automatically generating on Booking POST |
Searching for this specific item using the globalId GSI |
collectionId |
String |
The identifier of the collection this Booking belongs to |
Parent Product's collectionId |
Determining which collection this Booking belongs to |
activityType |
String |
The type of activity this Booking is for |
Parent Product's activityType |
Determining what type of Activity this Booking is for |
activitySubType? |
String |
A further categorization of the type of Activity this Booking is for, if available |
Parent Product's activitySubType |
Determining what type of activitySubType this Booking is for |
activityId |
Number |
The unique identifier of the parent Activity |
Parent Product's activityId |
Determining which specific Activity of activityType within the collectionId that this Booking refers to |
productId |
Number |
The unique identifier of the parent Product |
Parent Product's productId |
Determining which specific Product this Booking refers to |
bookingId |
String |
Unique identifier for this Booking (distinct from globalId for traceability purposes) |
Automatically generating on Booking POST |
Distinguishing this Booking from other Bookings related to the same Product |
userSub |
String |
The unique identifier of the customer who made the booking |
Provided by client on Booking POST |
Associating this Booking with the customer who made it |
status |
String |
The current status of the booking (e.g., "held". "pending", "completed", "cancelled") |
Automatically setting on Booking POST and updating on status changes |
Tracking the lifecycle state of the booking |
timezone |
String |
IANA timezone identifier for the location where this Booking is reserved |
Inherited from parent Product |
Ensuring that all date and time calculations related to this Booking are performed in the correct timezone context |
asset |
AssetRef |
The asset allocated through this Booking |
Derived from parent Product's assetList and Inventory allocation |
Tracking which specific asset is allocated through this Booking |
itineraryRulesSnapshot |
ItineraryRules |
The snapshot of the itinerary rules applied to this Booking at the time of booking |
Derived from parent Product's Itinerary Rules at the time of booking |
Capturing the itinerary rules context for this Booking at the moment it was created |
itinerary? |
ResolvedItinerary |
The resolved itinerary for this Booking, if applicable |
Derived from parent Product's Itinerary Rules and the customer's requested itinerary at the time of booking |
Capturing the specific itinerary for this Booking if the Product has itinerary rules that require resolution at the time of booking |
reservationPolicySnapshot |
BookingReservationPolicSnapshot |
The snapshot of the reservation policy applied to this Booking at the time of booking |
Derived from parent Product's Reservation Policy at the time of booking |
Capturing the reservation policy context for this Booking at the moment it was created |
reservationValues |
BookingReservationValues |
The resolved reservation values of this Booking |
Derived from parent Product's Reservation Policy and client input on Booking POST |
Capturing the specific reservation values for this Booking based on the Product's Reservation Policy and customer input |
partyPolicySnapshot |
BookingPartyPolicySnapshot |
The snapshot of the party policy applied to this Booking at the time of booking |
Derived from parent Product's Party Policy at the time of booking |
Capturing the party policy context for this Booking at the moment it was created |
partyValues |
BookingPartyValues |
The resolved party composition values of this Booking |
Derived from parent Product's Party Policy and client input on Booking POST |
Capturing the specific party composition for this Booking based on the Product's Party Policy and customer input |
feePolicySnapshot |
ProductFeePolicyReference |
The snapshot of the fee policy applied to this Booking at the time of booking |
Derived from parent Product's referenced Fee Policy at the time of booking |
Capturing the fee policy context for this Booking at the moment it was created |
feeValues |
BookingFeeValues |
The resolved fee values of this Booking |
Derived from parent Product's Fee Policy and client input on Booking POST |
Capturing the specific fee values for this Booking based on the Product's Fee Policy and customer input |
changePolicySnapshot |
ProductChangePolicyRef |
The snapshot of the change policy applied to this Booking at the time of booking |
Derived from parent Product's referenced Change Policy at the time of booking |
Capturing the change policy context for this Booking at the moment it was created |
bookingDates |
[PrimaryKey] |
List of primary keys of the BookingDates associated with this Booking |
Automatically generating on Booking POST based on the date range of the booking |
Tracking the specific BookingDates that are part of this Booking |
BookingTemporalWindows
| property |
type |
description |
derived from |
evaluated when |
changeWindow |
ResolvedTemporalWindow |
The change window for this Booking. |
Derived from parent Product's Reservation Policy |
Enforcing the change window for this Booking |
cancellationWindow |
ResolvedTemporalWindow |
The cancellation window for this Booking. |
Derived from parent Product's Reservation Policy |
Enforcing the cancellation window for this Booking |
ResolvedItinerary
| property |
type |
description |
derived from |
evaluated when |
entryPoint? |
ResolvedItineraryPoint |
The resolved entry point for this Booking, if applicable |
Derived from parent Product's Itinerary Rules and the customer's requested itinerary at the time of booking |
Capturing the specific entry point for this Booking if the Product has itinerary rules that require resolution at the time of booking |
exitPoint? |
ResolvedItineraryPoint |
The resolved exit point for this Booking, if applicable |
Derived from parent Product's Itinerary Rules and the customer's requested itinerary at the time of booking |
Capturing the specific exit point for this Booking if the Product has itinerary rules that require resolution at the time of booking |
stayPoints? |
[ResolvedItineraryPoint] |
The resolved stay points for this Booking, if applicable |
Derived from parent Product's Itinerary Rules and the customer's requested itinerary at the time of booking |
Capturing the specific stay points for this Booking if the Product has itinerary rules that require resolution at the time of booking |
ResolvedItineraryPoint
| property |
type |
description |
derived from |
evaluated when |
primaryKey |
PrimaryKey |
The primary key of the referenced Access Point or Overnight Stay point |
Derived from parent Product's Itinerary Rules and the customer's requested itinerary at the time of booking |
Identifying which specific Access Point or Overnight Stay this itinerary point refers to |
date |
Date |
The date of this itinerary point |
Derived from the customer's requested itinerary at the time of booking |
Capturing the specific date for this itinerary point |
displayName |
String |
The display name of this itinerary point |
Derived from the referenced Access Point or Overnight Stay point |
Providing a human-readable name for this itinerary point |
BookingReservationPolicySnapshot
| property |
type |
description |
derived from |
evaluated when |
isDiscoverable |
Boolean |
Whether this Booking was discoverable for reservation searches. |
Parent Product |
Determining if this Product appears in reservation search results |
isReservable |
Boolean |
Whether this Booking was able to be reserved. |
Parent Product |
Determining if this Product can be reserved |
minTotalDays |
Number |
Minimum total days this Booking must span |
Parent Product |
Enforcing minimum total days for reservations of this Booking |
maxTotalDays |
Number |
Maximum total days this Booking can span |
Parent Product |
Enforcing maximum total days for reservations of this Booking |
holdDuration |
Duration |
The length of time that this Booking can be held in a cart before it expires |
Parent Product |
Enforcing cart duration for reservations of this Booking |
temporalAnchors |
BookingTemporalAnchors |
The temporal anchors that define key time points for reservation rules on this Booking. |
Parent Product |
Determining the reference points for time-based reservation rules for this Booking. |
temporalWindows |
ProductReservationTemporalWindows |
Temporal windows that governed reservation availability for this Booking |
Parent Product |
Enforcing temporal windows for reservations of this Booking |
BookingReservationValues
| property |
type |
description |
derived from |
evaluated when |
totalDays |
Number |
The total number of days for this Booking |
Derived from the arrival and departure dates of this Booking |
Calculating the total days for this Booking to enforce reservation policies that depend on total length of stay |
restrictedBookingTriggered |
Boolean |
Whether this Booking has triggered any restricted booking windows based on its temporal anchors |
Derived from the temporal anchors of this Booking and the reservation policy rules that define restricted booking windows |
Determining if this Booking falls within any restricted booking windows that would disallow changes to the booking |
temporalAnchors |
BookingTemporalAnchors |
The resolved temporal anchors for this Booking |
Derived from the Booking's temporal anchors and the specific reservation policy rules that require resolution at the time of booking |
Providing the specific temporal anchor values needed to enforce reservation policies for this Booking |
BookingTemporalAnchors
| property |
type |
description |
derived from |
evaluated when |
reservationTime |
Timestamp |
The reservation time anchor for this Booking |
Derived from client input on Booking POST |
Establishing the reservation time context for this Booking |
holdExpiryTime |
Timestamp |
The hold expiry time anchor for this Booking |
Derived from client input on Booking POST and updated if the booking hold is extended |
Establishing the hold expiry time context for this Booking |
completionTime? |
Timestamp |
The completion time anchor for this Booking |
Derived from client input on Booking POST and updated when the booking is finalized |
Establishing the completion time context for this Booking |
arrivalDate |
Date |
The arrival date anchor for this Booking |
Derived from client input on Booking POST |
Establishing the arrival date context for this Booking |
departureDate |
Date |
The departure date anchor for this Booking |
Derived from client input on Booking POST |
Establishing the departure date context for this Booking |
checkInAfter |
Timestamp |
The check-in after time anchor for this Booking |
Derived from client input on Booking POST |
Establishing the check-in after time context for this Booking |
checkOutBefore |
Timestamp |
The check-out before time anchor for this Booking |
Derived from client input on Booking POST |
Establishing the check-out before time context for this Booking |
noShowAfter |
Timestamp |
The no-show after time anchor for this Booking |
Derived from client input on Booking POST |
Establishing the no-show after time context for this Booking |
BookingPartyPolicySnapshot
| property |
type |
description |
derived from |
evaluated when |
partyCategories |
[PartyCategory] |
The snapshot of the party category rules applied to this Booking at the time of booking |
Derived from parent Product's Party Policy at the time of booking |
Capturing the specific party category rules for this Booking based on the Product's Party Policy at the moment it was created |
partyCompositionRules |
[ElegibilityPrimitive] |
The snapshot of the party composition rules applied to this Booking at the time of booking |
Derived from parent Product's Party Policy at the time of booking |
Capturing the specific party composition rules for this Booking based on the Product's Party Policy at the moment it was created |
PartyCategory
| property |
type |
description |
derived from |
evaluated when |
id |
String |
The unique identifier for this party category |
Derived from parent Product's Party Policy |
Identifying this specific party category |
label |
String |
The display name for this party category |
Derived from parent Product's Party Policy |
Providing a human-readable name for this party category |
minCount |
Number |
The minimum number of party members/equipment that must be included in a booking for this category |
Derived from parent Product's Party Policy |
Enforcing the minimum count for this party category in bookings |
maxCount |
Number |
The maximum number of party members/equipment that can be included in a booking for this category |
Derived from parent Product's Party Policy |
Enforcing the maximum count for this party category in bookings |
BookingPartyValues
| property |
type |
description |
derived from |
evaluated when |
partyComposition |
PartyCompositionUnit |
The resolved party composition for this Booking |
Derived from parent Product's Party Policy and client input on Booking POST |
Capturing the specific party composition for this Booking based on the Product's Party Policy and customer input |
PartyCompositionUnit
| property |
type |
description |
derived from |
evaluated when |
id |
String |
The unique identifier for this party composition unit |
Derived from BookingPartyPolicySnapshot |
Identifying this specific party composition unit |
label |
String |
The display name for this party composition unit |
Derived from BookingPartyPolicySnapshot |
Providing a human-readable name for this party composition unit |
count |
Number |
The number of party members/equipment included in this booking for this unit |
Derived from client input on Booking POST |
Capturing the specific count for this party composition unit in this Booking |
BookingFeePolicySnapshot
| property |
type |
description |
derived from |
evaluated when |
feeSchedule |
FeeSchedule |
The snapshot of the fee schedule applied to this Booking at the time of booking |
Derived from parent Product's referenced Fee Policy at the time of booking |
Capturing the specific fee schedule for this Booking based on the Product's Fee Policy at the moment it was created |
lineItems |
LineItem |
The snapshot of the fee line items applied to this Booking at the time of booking |
Derived from parent Product's referenced Fee Policy and client input on Booking POST at the time of booking |
Capturing the specific fee line items for this Booking based on the Product's Fee Policy and customer input at the moment it was created |
BookingFeeValues
| property |
type |
description |
derived from |
evaluated when |
bookingDateTotals |
BookingDateFeeTotal |
The breakdown of fee totals for each BookingDate within this Booking |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Calculating the fee totals for each BookingDate within this Booking based on the fee schedule, line items, and customer input |
resolvedLineItems |
ResolvedLineItem |
The resolved fee line items for this Booking |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Capturing the specific fee line items for this Booking based on the fee policy snapshot and customer input |
bookingDiscounts |
ResolvedLineItemDiscount |
The total discount amount for this Booking |
Derived from the discounts applied to the resolved line items for this Booking |
Calculating the total discount for this Booking based on the discounts applied to the resolved line items |
bookingTaxes |
ResolvedLineItemTax |
The total tax amount for this Booking |
Derived from the taxes applied to the resolved line items for this Booking |
Calculating the total tax for this Booking based on the taxes applied to the resolved line items |
bookingSubTotal |
Number |
The subtotal fee amount for this Booking before taxes and discounts |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Calculating the subtotal fee for this Booking based on the fee schedule, line items, and customer input |
bookingTotal |
Number |
The grand total fee amount for this Booking |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Calculating the grand total fee for this Booking based on the fee schedule, line items, and customer input |
BookingDateFeeTotal
| property |
type |
description |
derived from |
evaluated when |
date |
Date |
The date for this BookingDate fee total |
Derived from the specific BookingDate this fee total corresponds to |
Identifying which BookingDate this fee total corresponds to |
total |
Number |
The total fee amount for this BookingDate |
Derived from the fee schedule, line items, and customer input for this specific date |
Calculating the total fee for this BookingDate based on the fee policy and customer input |
ResolvedLineItem
| property |
type |
description |
derived from |
evaluated when |
id |
String |
The unique identifier for this resolved line item |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Identifying this specific resolved line item |
label |
String |
The display name for this resolved line item |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Providing a human-readable name for this resolved line item |
type |
String |
The type of this resolved line item (e.g., "flat", "unit") |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Determining how this resolved line item is processed in the overall fee calculation |
isReturnable |
Boolean |
Whether this resolved line item is returnable/refundable |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Determining if this resolved line item can be refunded in the case of a cancellation or change |
units |
[ResolvedLineItemUnitBreakdown] |
The breakdown of units for this resolved line item, if applicable |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Providing a detailed breakdown of units for this resolved line item if it is of type "unit" |
lineTaxes |
[ResolvedLineItemTax] |
The breakdown of taxes for this resolved line item, if applicable |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Providing a detailed breakdown of taxes for this resolved line item if it is taxable |
lineDiscounts |
[ResolvedLineItemDiscount] |
The breakdown of discounts for this resolved line item, if applicable |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Providing a detailed breakdown of discounts for this resolved line item if it is discountable |
lineSubtotal |
Number |
The subtotal amount for this line item before taxes and discounts |
Derived from the quantity, rate, and type of this resolved line item |
Calculating the subtotal for this line item based on its quantity, rate, and type |
lineTotal |
Number |
The total amount for this line item after applying taxes and discounts |
Derived from the line subtotal, taxes, and discounts for this resolved line item |
Calculating the total for this line item based on its subtotal, taxes, and discounts |
ResolvedLineItemUnitBreakdown
| property |
type |
description |
derived from |
evaluated when |
rate |
Number |
The rate for this unit breakdown |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Determining the rate for this unit breakdown of the resolved line item |
discountApplied |
[ResolvedLineItemDiscount] |
The discount applied to this unit breakdown, if applicable |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Determining the discount applied to this unit breakdown of the resolved line item if it is discountable |
unitSubTotal |
Number |
The subtotal amount for this unit breakdown before taxes |
Derived from the rate for this unit breakdown |
Calculating the subtotal for this unit breakdown based on its rate |
taxApplied |
[ResolvedLineItemTax] |
The tax applied to this unit breakdown, if applicable |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Determining the tax applied to this unit breakdown of the resolved line item if it is taxable |
unitSubTotal |
Number |
The subtotal amount for this unit breakdown before taxes |
Derived from the rate for this unit breakdown |
Calculating the subtotal for this unit breakdown based on its rate |
unitTotal |
Number |
The total amount for this unit breakdown after applying taxes and discounts |
Derived from the rate, tax, and discount for this unit breakdown |
Calculating the total for this unit breakdown based on its rate, tax, and discount |
ResolvedLineItemTax
| property |
type |
description |
derived from |
evaluated when |
id |
String |
The unique identifier for this resolved line item tax |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Identifying this specific resolved line item tax |
rate |
Number |
The tax rate for this resolved line item tax |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Determining the tax rate for this resolved line item tax |
amount |
Number |
The tax amount for this resolved line item tax |
Derived from the line subtotal and tax rate for this resolved line item tax |
Calculating the tax amount for this resolved line item tax based on the line subtotal and tax rate |
ResolvedLineItemDiscount
| property |
type |
description |
derived from |
evaluated when |
id |
String |
The unique identifier for this resolved line item discount |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Identifying this specific resolved line item discount |
rate? |
Number |
The discount rate for this resolved line item discount |
Derived from BookingFeePolicySnapshot and client input on Booking POST |
Determining the discount rate for this resolved line item discount |
amount |
Number |
The discount amount for this resolved line item discount |
Derived from the line subtotal and discount rate for this resolved line item discount |
Calculating the discount amount for this resolved line item discount based on the line subtotal and discount rate |
ChangePolicySnapshot
| property |
type |
description |
derived from |
evaluated when |
rules |
[ChangePolicyRule] |
The snapshot of the change policy rules applied to this Booking at the time of booking |
Derived from parent Product's referenced Change Policy at the time of booking |
Capturing the specific change policy rules for this Booking based on the Product's Change Policy at the moment it was created |
Example Booking
{
"pk": "booking::mockPark1::backcountryCamp::1::1",
"sk": "2026-02-09::550e8400-e29b-41d4-a716-446655440000",
"gsi1pk": "user::b7e6c2f2-3a1d-4e8a-9e0d-8c2a1b7e6c2f",
"gsi1sk": "2026-02-09::booking",
"schema": "booking",
"globalId": "550e8400-e29b-41d4-a716-446655440000",
"collectionId": "mockPark1",
"activityType": "backcountryCamp",
"activitySubType": null,
"activityId": "1",
"productId": "1",
"bookingId": "550e8400-e29b-41d4-a716-446655440000",
"userSub": "b7e6c2f2-3a1d-4e8a-9e0d-8c2a1b7e6c2f",
"status": "held",
"timezone": "America/Vancouver",
"asset": {
"primaryKey": {
"pk": "asset::mockPark1::campground::1",
"sk": "campsite::1"
},
"allocationType": "fixed",
"quantity": 1
},
"itineraryRulesSnapshot": {
"entryExit": {
"required": true,
"allowedEntryPoints": [
{
"pk": "facility::mockPark1",
"sk": "accessPoint::1"
},
{
"pk": "facility::mockPark1",
"sk": "accessPoint::2"
}
],
"allowedExitPoints": [
{
"pk": "facility::mockPark1",
"sk": "accessPoint::1"
},
{
"pk": "facility::mockPark1",
"sk": "accessPoint::2"
}
]
},
"stayPoints": {
"required": true,
"allowedStayPoints": [
{
"pk": "facility::mockPark1",
"sk": "campground::1"
},
{
"pk": "facility::mockPark1",
"sk": "campground::2"
}
]
}
},
"itinerary": {},
"reservationPolicySnapshot": {
"isDiscoverable": true,
"isReservable": true,
"minTotalDays": 1,
"maxTotalDays": 14,
"holdDuration": {
"minutes": 30
},
"temporalWindows": {
"discoveryWindow": {
"open": "2026-01-01T07:00:00-08:00",
"close": "2026-12-31T23:59:59-08:00"
}
}
},
"temporalContext": {
"totalDays": 0,
"restrictedBookingTriggered": false,
"discoveryWindow": {
"open": "2026-01-01T07:00:00-08:00",
"close": "2026-12-31T23:59:59-08:00"
},
"checkInAnchor": "2026-02-09T14:00:00-08:00",
"checkOutAnchor": "2026-02-12T11:00:00-08:00",
"noShowAnchor": "2026-02-09T23:59:59-08:00",
"reservationTime": "2026-01-01T07:01:00-08:00",
"completionTime": null,
"arrivalDate": "2026-02-09",
"departureDate": "2026-02-12"
},
"partyPolicySnapshot": {
"partyCategories": [
{
"id": "adult",
"label": "Adult (18+)",
"minCount": 1,
"maxCount": 4
},
{
"id": "child",
"label": "Child <18",
"minCount": 0,
"maxCount": 3
},
{
"id": "tent",
"label": "Tent",
"minCount": 1,
"maxCount": 2
}
],
"partyCompositionRules": [
{
"id": "maxTotalPartySize",
"label": "Maximum Total Party Size",
"failMsg": "Total party size cannot exceed 4 people.",
"if": [],
"then": {
"lhs": [
{
"type": "ref",
"value": "partyCategory.adult"
},
{
"op": "add"
},
{
"type": "ref",
"value": "partyCategory.child"
}
],
"op": "lte",
"rhs": [
{
"type": "constant",
"value": 4
}
]
}
}
]
},
"partyContext": {
"isValid": false,
"bookingDateValidations": [
{
"date": "2026-02-09",
"isValid": false
},
{
"date": "2026-02-11",
"isValid": false
},
{
"date": "2026-02-12",
"isValid": false
}
]
},
"feePolicySnapshot": {
"feeSchedule": [
{
"id": "transactionFee",
"label": "Transaction Fee",
"type": "flat",
"amount": 6.5
},
{
"id": "tax",
"label": "Tax",
"type": "percentage",
"amount": 0.05
}
],
"lineItems": [
{
"id": "transactionFeeLine",
"label": "Transaction Fee",
"type": "flat",
"if": [],
"quantity": {
"type": "constant",
"value": 1
},
"rate": {
"type": "field",
"value": "feeSchedule.transactionFee"
},
"taxApplied": [
{
"type": "field",
"value": "feeSchedule.tax"
}
],
"discountsApplied": [],
"isReturnable": false
}
]
},
"feeValues": {
"bookingDateTotals": [
{
"date": "2026-02-09",
"totalDiscounts": [],
"totalTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 0
}
],
"total": 0
},
{
"date": "2026-02-10",
"totalDiscounts": [],
"totalTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 0
}
],
"total": 0
},
{
"date": "2026-02-11",
"totalDiscounts": [],
"totalTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 0
}
],
"total": 0
}
],
"resolvedLineItems": [
{
"id": "transactionFeeLine",
"label": "Transaction Fee",
"type": "flat",
"isReturnable": false,
"units": [
{
"rate": 6.50,
"discountsApplied": [],
"taxApplied": [
{
"id": "tax",
"rate": 0.05,
"amount": 0.33
}
],
"unitSubTotal": 6.50,
"unitTotal": 6.83
}
],
"lineTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 0.33
}
],
"lineDiscounts": [],
"lineSubTotal": 6.50,
"lineTotal": 6.83
}
],
"bookingDiscounts": [],
"bookingTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 0.33
}
],
"bookingSubTotal": 6.50,
"bookingTotal": 6.83
},
"changePolicySnapshot": {
"rules": [
{
"id": "campingFeeFullRefund",
"label": "Full Camping Fee Refund",
"description": "Full refund of camping fees if cancellation occurs more than 2 weeks before arrival date.",
"if": [],
"type": "percentage",
"amount": 1.0,
"temporalWindow": {
"open": "2026-01-01T07:00:00-08:00",
"close": "2026-01-26T23:59:59-08:00"
}
},
{
"id": "campingFee50PercentRefund",
"label": "Half Camping Fee Refund",
"description": "Half refund of camping fees if cancellation occurs less than 2 weeks but more than 1 week before arrival date.",
"type": "percentage",
"if": [],
"amount": 0.5,
"temporalWindow": {
"open": "2026-01-27T07:00:00-08:00",
"close": "2026-02-02T23:59:59-08:00"
}
}
]
},
"createdAt": "2026-01-01T07:01:00-08:00",
"lastUpdated": "2026-01-01T07:01:00-08:00",
"version": 1
}
After Finalization
{
"pk": "booking::mockPark1::backcountryCamp::1::1",
"sk": "2026-02-09::550e8400-e29b-41d4-a716-446655440000",
"gsi1pk": "user::b7e6c2f2-3a1d-4e8a-9e0d-8c2a1b7e6c2f",
"gsi1sk": "2026-02-09",
"schema": "booking",
"globalId": "550e8400-e29b-41d4-a716-446655440000",
"collectionId": "mockPark1",
"activityType": "backcountryCamp",
"activitySubType": null,
"activityId": "1",
"productId": "1",
"bookingId": "550e8400-e29b-41d4-a716-446655440000",
"userSub": "b7e6c2f2-3a1d-4e8a-9e0d-8c2a1b7e6c2f",
"status": "complete",
"timezone": "America/Vancouver",
"asset": {
"primaryKey": {
"pk": "asset::mockPark1::campground::1",
"sk": "campsite::1"
},
"allocationType": "fixed",
"quantity": 1
},
"itineraryRulesSnapshot": {
"entryExit": {
"required": true,
"allowedEntryPoints": [
{
"pk": "facility::mockPark1",
"sk": "accessPoint::1"
},
{
"pk": "facility::mockPark1",
"sk": "accessPoint::2"
}
],
"allowedExitPoints": [
{
"pk": "facility::mockPark1",
"sk": "accessPoint::1"
},
{
"pk": "facility::mockPark1",
"sk": "accessPoint::2"
}
]
},
"stayPoints": {
"required": true,
"allowedStayPoints": [
{
"pk": "facility::mockPark1",
"sk": "campground::1"
},
{
"pk": "facility::mockPark1",
"sk": "campground::2"
}
]
}
},
"itinerary": {
"entryPoint": {
"primaryKey": {
"pk": "facility::mockPark1",
"sk": "accessPoint::1"
},
"date": "2026-02-09",
"displayName": "Mock Park South Trailhead"
},
"exitPoint": {
"primaryKey": {
"pk": "facility::mockPark1",
"sk": "accessPoint::2"
},
"date": "2026-02-12",
"displayName": "Mock Park North Trailhead"
},
"stayPoints": [
{
"primaryKey": {
"pk": "facility::mockPark1",
"sk": "campground::1"
},
"date": "2026-02-09",
"displayName": "Mock Park Campground A"
},
{
"primaryKey": {
"pk": "facility::mockPark1",
"sk": "campground::1"
},
"date": "2026-02-10",
"displayName": "Mock Park Campground A"
},
{
"primaryKey": {
"pk": "facility::mockPark1",
"sk": "campground::2"
},
"date": "2026-02-11",
"displayName": "Mock Park Campground B"
}
]
},
"reservationPolicySnapshot": {
"isDiscoverable": true,
"isReservable": true,
"minTotalDays": 1,
"maxTotalDays": 14,
"holdDuration": {
"minutes": 30
},
"temporalWindows": {
"discoveryWindow": {
"open": "2026-01-01T07:00:00-08:00",
"close": "2026-12-31T23:59:59-08:00"
}
}
},
"reservationValues": {
"totalDays": 3,
"restrictedBookingTriggered": false,
"temporalAnchors": {
"reservationTime": "2026-01-01T07:00:00-08:00",
"arrivalDate": "2026-02-09",
"departureDate": "2026-02-12",
"checkInAnchor": "2026-02-09T14:00:00-08:00",
"noShowAnchor": "2026-02-09T23:59:59-08:00"
}
},
"partyPolicySnapshot": {
"partyCategories": [
{
"id": "adult",
"label": "Adult (18+)",
"minCount": 1,
"maxCount": 4
},
{
"id": "child",
"label": "Child <18",
"minCount": 0,
"maxCount": 3
},
{
"id": "tent",
"label": "Tent",
"minCount": 1,
"maxCount": 2
}
],
"partyCompositionRules": [
{
"id": "maxTotalPartySize",
"label": "Maximum Total Party Size",
"failMsg": "Total party size cannot exceed 4 people.",
"if": [],
"then": {
"lhs": [
{
"type": "partyCategory",
"value": "adult"
},
{
"op": "add"
},
{
"type": "partyCategory",
"value": "child"
}
],
"op": "lte",
"rhs": [
{
"type": "constant",
"value": 4
}
]
}
}
]
},
"partyContext": {
"isValid": true,
"bookingDateValidations": [
{
"date": "2026-02-09",
"isValid": true
},
{
"date": "2026-02-11",
"isValid": true
},
{
"date": "2026-02-12",
"isValid": true
}
]
},
"feePolicySnapshot": {
"feeSchedule": [
{
"id": "transactionFee",
"label": "Transaction Fee",
"type": "flat",
"amount": 6.5
},
{
"id": "tax",
"label": "Tax",
"type": "percentage",
"amount": 0.05
}
],
"lineItems": [
{
"id": "transactionFeeLine",
"label": "Transaction Fee",
"type": "flat",
"if": [],
"quantity": {
"type": "constant",
"value": 1
},
"rate": {
"type": "field",
"value": "feeSchedule.transactionFee"
},
"taxApplied": [
{
"type": "field",
"value": "feeSchedule.tax"
}
],
"discountsApplied": [],
"isReturnable": false
}
]
},
"feeValues": {
"bookingDateTotals": [
{
"date": "2026-02-09",
"totalDiscounts": [],
"totalTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 2.00
}
],
"subTotal": 40,
"total": 42
},
{
"date": "2026-02-10",
"totalDiscounts": [],
"totalTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 2.00
}
],
"subTotal": 40,
"total": 42
},
{
"date": "2026-02-11",
"totalDiscounts": [],
"totalTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 2.00
}
],
"subTotal": 40,
"total": 42
}
],
"resolvedLineItems": [
{
"id": "transactionFeeLine",
"label": "Transaction Fee",
"type": "flat",
"isReturnable": false,
"units": [
{
"rate": 6.50,
"discountsApplied": [],
"taxApplied": [
{
"id": "tax",
"rate": 0.05,
"amount": 0.33
}
],
"unitSubTotal": 6.50,
"unitTotal": 6.83
}
],
"lineTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 0.33
}
],
"lineDiscounts": [],
"lineSubTotal": 6.50,
"lineTotal": 6.83
}
],
"bookingDiscounts": [],
"bookingTaxes": [
{
"id": "tax",
"rate": 0.05,
"amount": 6.33
}
],
"bookingSubTotal": 126.50,
"bookingTotal": 132.83
},
"changePolicySnapshot": {
"rules": [
{
"id": "campingFeeFullRefund",
"label": "Full Camping Fee Refund",
"description": "Full refund of camping fees if cancellation occurs more than 2 weeks before arrival date.",
"if": [],
"type": "percentage",
"amount": 1.0,
"temporalWindow": {
"open": "2026-01-01T07:00:00-08:00",
"close": "2026-01-26T23:59:59-08:00"
}
},
{
"id": "campingFee50PercentRefund",
"label": "Half Camping Fee Refund",
"description": "Half refund of camping fees if cancellation occurs less than 2 weeks but more than 1 week before arrival date.",
"type": "percentage",
"if": [],
"amount": 0.5,
"temporalWindow": {
"open": "2026-01-27T07:00:00-08:00",
"close": "2026-02-02T23:59:59-08:00"
}
}
]
},
"createdAt": "2026-01-01T07:01:00-08:00",
"lastUpdated": "2026-01-01T07:03:00-08:00",
"version": 2
}