diff --git a/rust/schemas/api/fulfillments.json b/rust/schemas/api/fulfillments.json index a05fd54b..7a028b61 100644 --- a/rust/schemas/api/fulfillments.json +++ b/rust/schemas/api/fulfillments.json @@ -133,10 +133,115 @@ "type": "string" }, "Fulfillment": { - "description": "An identifier unique to the fulfillment (`Fulfillment_`). Auto-generated by our system on creation", - "example": "Fulfillment_2G5VsWEFhIktH8PY4qC0iOGDpVJ", - "readOnly": true, - "type": "string" + "$id": "https://godaddy.com/schemas/commerce/fulfillment/fulfillment.v1", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A fulfillment represents a task to fulfill one or more items from a single location for a single fulfillment mode. A Fulfillment can exist in the context of an order or be independent of one.", + "properties": { + "createdAt": { + "$ref": "#/$defs/date-time" + }, + "destination": { + "$ref": "#/$defs/FulfillmentAddress" + }, + "detailedStatus": { + "$ref": "#/$defs/FulfillmentDetailedStatus" + }, + "externalId": { + "description": "External identifier for the fulfillment", + "example": "FM-Y6BN43DB590L", + "type": "string" + }, + "fulfillmentPlanId": { + "description": "Reference to the FulfillmentPlan this fulfillment was created from. Used for linking and reporting.", + "example": "FulfillmentPlan_TG41sWEXyIktH8PY4eI0nOGDoB6", + "type": "string" + }, + "fulfillmentWindow": { + "$ref": "#/$defs/FulfillmentWindow" + }, + "history": { + "description": "List of history events associated to the fulfillment", + "items": { + "$ref": "#/$defs/HistoryEvent" + }, + "readOnly": true, + "type": "array" + }, + "id": { + "description": "An identifier unique to the fulfillment (`Fulfillment_`). Auto-generated by our system on creation", + "example": "Fulfillment_2G5VsWEFhIktH8PY4qC0iOGDpVJ", + "readOnly": true, + "type": "string" + }, + "inventoryBehavior": { + "default": "OBEY_POLICY", + "description": "Inventory policy for this fulfillment. Valid values: OBEY_POLICY (default), BYPASS. OBEY_POLICY decrements inventory and enforces stock checks; BYPASS skips inventory checks and allows fulfillment regardless of stock.", + "enum": [ + "OBEY_POLICY", + "BYPASS" + ], + "type": "string" + }, + "items": { + "description": "Items in the fulfillment", + "items": { + "$ref": "#/$defs/FulfillmentItem" + }, + "minItems": 1, + "type": "array" + }, + "locationId": { + "description": "Reference to the Inventory Location (as defined by the Inventory Service) where the fulfillment was processed at", + "type": "string" + }, + "mode": { + "$ref": "#/$defs/Mode" + }, + "notes": { + "description": "List of FulfillmentNote objects, used for internal or customer-facing notes.", + "items": { + "$ref": "#/$defs/FulfillmentNote" + }, + "type": "array" + }, + "orderId": { + "description": "Reference to an order as defined by the Orders Service", + "example": "Order_2G5VsWEFhIktH8PY4qC0iOGDpVJ", + "type": "string" + }, + "origin": { + "$ref": "#/$defs/FulfillmentAddress" + }, + "status": { + "$ref": "#/$defs/FulfillmentStatus" + }, + "storeId": { + "description": "ID of the store that the fulfillment belongs to", + "example": "fd3d9291-dc9a-445d-aa68-d2ff1a77a83c", + "type": "string" + }, + "trackingData": { + "description": "Tracking information for a fulfillment. The ability to have multiple tracking numbers for a single fulfillment is to support `last mile` shipping use cases. We do not support fulfilling multiple discrete sets of items (e.g. multiple boxes) in a single fulfillment", + "items": { + "$ref": "#/$defs/Tracking" + }, + "type": "array" + }, + "updatedAt": { + "$ref": "#/$defs/date-time" + } + }, + "required": [ + "id", + "storeId", + "mode", + "status", + "detailedStatus", + "locationId", + "items" + ], + "title": "Fulfillment", + "type": "object" }, "FulfillmentAddress": { "$id": "https://godaddy.com/schemas/commerce/fulfillment/fulfillment-address.v1", @@ -346,9 +451,84 @@ "type": "object" }, "FulfillmentPlan": { - "description": "Reference to an order as defined by the Orders Service", - "example": "Order_2G5VsWEFhIktH8PY4qC0iOGDpVJ", - "type": "string" + "$id": "https://godaddy.com/schemas/commerce/fulfillment/fulfillment-plan.v1", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "description": "A fulfillment plan is a task list with instructions on how to fulfill a group of one or more items from an order from a single location for a single fulfillment mode. An order can have multiple fulfillment plans", + "properties": { + "cartId": { + "description": "Optional reference to the cart associated with the order, if the order originated from a cart.", + "type": "string" + }, + "createdAt": { + "$ref": "#/$defs/date-time" + }, + "destination": { + "$ref": "#/$defs/FulfillmentAddress" + }, + "hasErrors": { + "description": "True if any item in the plan encountered an error during inventory sync or fulfillment. This flag is set when errors are detected and is used to block further processing, trigger alerts, and surface issues for operator intervention.", + "type": "boolean" + }, + "history": { + "description": "List of history events associated to the fulfillment plan", + "items": { + "$ref": "#/$defs/HistoryEvent" + }, + "readOnly": true, + "type": "array" + }, + "id": { + "description": "An identifier unique to the fulfillment plan (`FulfillmentPlan_`). Auto-generated by our system on creation", + "example": "FulfillmentPlan_TG41sWEXyIktH8PY4eI0nOGDoB6", + "readOnly": true, + "type": "string" + }, + "items": { + "description": "Items in the fulfillment plan", + "items": { + "$ref": "#/$defs/FulfillmentPlanItem" + }, + "minItems": 1, + "type": "array" + }, + "locationId": { + "description": "Reference to the Inventory Location (as defined by the Inventory Service) where the fulfillment was processed at", + "type": "string" + }, + "mode": { + "$ref": "#/$defs/Mode" + }, + "orderId": { + "description": "Reference to an order as defined by the Orders Service", + "example": "Order_2G5VsWEFhIktH8PY4qC0iOGDpVJ", + "type": "string" + }, + "origin": { + "$ref": "#/$defs/FulfillmentAddress" + }, + "status": { + "$ref": "#/$defs/FulfillmentPlanStatus" + }, + "storeId": { + "description": "ID of the store that the fulfillment plan belongs to", + "example": "6863480a-d0cb-46b5-8560-cd97d2c72d35", + "type": "string" + }, + "updatedAt": { + "$ref": "#/$defs/date-time" + } + }, + "required": [ + "id", + "storeId", + "orderId", + "mode", + "status", + "locationId", + "items" + ], + "title": "Fulfillment Plan", + "type": "object" }, "FulfillmentPlanItem": { "$id": "https://godaddy.com/schemas/commerce/fulfillment/fulfillment-plan-item.v1", @@ -431,6 +611,16 @@ "title": "Fulfillment Plan status", "type": "string" }, + "FulfillmentPlan_orderId": { + "description": "Reference to an order as defined by the Orders Service", + "example": "Order_2G5VsWEFhIktH8PY4qC0iOGDpVJ", + "type": "string" + }, + "FulfillmentPlan_storeId": { + "description": "ID of the store that the fulfillment plan belongs to", + "example": "6863480a-d0cb-46b5-8560-cd97d2c72d35", + "type": "string" + }, "FulfillmentStatus": { "$id": "https://godaddy.com/schemas/commerce/fulfillment/fulfillment-status.v1", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -463,6 +653,12 @@ "title": "Fulfillment Window", "type": "object" }, + "Fulfillment_id": { + "description": "An identifier unique to the fulfillment (`Fulfillment_`). Auto-generated by our system on creation", + "example": "Fulfillment_2G5VsWEFhIktH8PY4qC0iOGDpVJ", + "readOnly": true, + "type": "string" + }, "HistoryEvent": { "$id": "https://godaddy.com/schemas/commerce/fulfillment/history-event.v1", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -702,7 +898,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/FulfillmentPlan" + "$ref": "#/$defs/FulfillmentPlan_storeId" } }, { @@ -711,7 +907,7 @@ "name": "orderId", "required": true, "schema": { - "$ref": "#/$defs/FulfillmentPlan" + "$ref": "#/$defs/FulfillmentPlan_orderId" } }, { @@ -837,7 +1033,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/FulfillmentPlan" + "$ref": "#/$defs/FulfillmentPlan_storeId" } }, { @@ -1000,7 +1196,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/FulfillmentPlan" + "$ref": "#/$defs/FulfillmentPlan_storeId" } } ], @@ -1103,7 +1299,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/FulfillmentPlan" + "$ref": "#/$defs/FulfillmentPlan_storeId" } }, { @@ -1112,7 +1308,7 @@ "name": "fulfillmentId", "required": true, "schema": { - "$ref": "#/$defs/Fulfillment" + "$ref": "#/$defs/Fulfillment_id" } } ], diff --git a/rust/schemas/api/manifest.json b/rust/schemas/api/manifest.json index 6e68fbd4..ae7bb884 100644 --- a/rust/schemas/api/manifest.json +++ b/rust/schemas/api/manifest.json @@ -1,90 +1,75 @@ { - "generated": "2026-07-30T20:05:32.981342381+00:00", + "generated": "2026-07-30T22:49:51.251324536+00:00", "domains": { - "transactions": { - "file": "transactions.json", - "title": "Transactions API", - "endpointCount": 17 - }, - "customer-profiles": { - "file": "customer-profiles.json", - "title": "Customers API", - "endpointCount": 9 - }, - "orders": { - "file": "orders.json", - "title": "Order Service", - "endpointCount": 15 + "catalog-products": { + "file": "catalog-products.json", + "title": "Catalog GraphQL API", + "endpointCount": 1 }, "onboarding": { "file": "onboarding.json", "title": "Commerce Onboarding API", "endpointCount": 5 }, - "fulfillments": { - "file": "fulfillments.json", - "title": "Fulfillment Service", - "endpointCount": 4 - }, - "payments": { - "file": "payments.json", - "title": "Payments API", - "endpointCount": 43 - }, - "hosting-nodejs": { - "file": "hosting-nodejs.json", - "title": "Node.js Hosting Public API", - "endpointCount": 20 - }, - "payment-requests": { - "file": "payment-requests.json", - "title": "Payment Requests API", - "endpointCount": 5 - }, - "recommendations": { - "file": "recommendations.json", - "title": "GoDaddy Recommendation API", - "endpointCount": 1 + "price-adjustments": { + "file": "price-adjustments.json", + "title": "GoDaddy Price Adjustment API", + "endpointCount": 10 }, - "catalog-products": { - "file": "catalog-products.json", - "title": "Catalog GraphQL API", - "endpointCount": 1 + "metafields": { + "file": "metafields.json", + "title": "Metafields API", + "endpointCount": 12 }, "shipping": { "file": "shipping.json", "title": "Shipping Service", "endpointCount": 7 }, - "metafields": { - "file": "metafields.json", - "title": "Metafields API", - "endpointCount": 12 + "orders": { + "file": "orders.json", + "title": "Order Service", + "endpointCount": 15 }, - "location-addresses": { - "file": "location-addresses.json", - "title": "Addresses API", - "endpointCount": 2 + "taxes": { + "file": "taxes.json", + "title": "Tax GraphQL API", + "endpointCount": 1 }, - "price-adjustments": { - "file": "price-adjustments.json", - "title": "GoDaddy Price Adjustment API", - "endpointCount": 10 + "customer-profiles": { + "file": "customer-profiles.json", + "title": "Customers API", + "endpointCount": 9 }, - "chargebacks": { - "file": "chargebacks.json", - "title": "Chargeback Management", - "endpointCount": 10 + "recommendations": { + "file": "recommendations.json", + "title": "GoDaddy Recommendation API", + "endpointCount": 1 + }, + "stores": { + "file": "stores.json", + "title": "Commerce Store API", + "endpointCount": 8 }, "channels": { "file": "channels.json", "title": "Channels API", "endpointCount": 8 }, - "stores": { - "file": "stores.json", - "title": "Commerce Store API", - "endpointCount": 8 + "hosting-nodejs": { + "file": "hosting-nodejs.json", + "title": "Node.js Hosting Public API", + "endpointCount": 20 + }, + "payments": { + "file": "payments.json", + "title": "Payments API", + "endpointCount": 43 + }, + "fulfillments": { + "file": "fulfillments.json", + "title": "Fulfillment Service", + "endpointCount": 4 }, "domains": { "file": "domains.json", @@ -101,15 +86,30 @@ "title": "Commerce Business API", "endpointCount": 8 }, + "transactions": { + "file": "transactions.json", + "title": "Transactions API", + "endpointCount": 17 + }, + "chargebacks": { + "file": "chargebacks.json", + "title": "Chargeback Management", + "endpointCount": 10 + }, "subscriptions": { "file": "subscriptions.json", "title": "Commerce Subscription API", "endpointCount": 8 }, - "taxes": { - "file": "taxes.json", - "title": "Tax GraphQL API", - "endpointCount": 1 + "location-addresses": { + "file": "location-addresses.json", + "title": "Addresses API", + "endpointCount": 2 + }, + "payment-requests": { + "file": "payment-requests.json", + "title": "Payment Requests API", + "endpointCount": 5 } } } \ No newline at end of file diff --git a/rust/schemas/api/orders.json b/rust/schemas/api/orders.json index c2463e18..b936e001 100644 --- a/rust/schemas/api/orders.json +++ b/rust/schemas/api/orders.json @@ -711,10 +711,265 @@ "type": "object" }, "Order": { - "description": "An identifier unique to the order (Order_). Auto-generated by the service on creation", - "example": "Order_2G5VsWEFhIktH8PY4qC0iOGDpVJ", - "readOnly": true, - "type": "string" + "$id": "https://godaddy.com/schemas/commerce/orders/order.v1", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "definitions": { + "tax": { + "$ref": "#/$defs/Tax" + } + }, + "description": "A order has to have at least 1 line item which is a representation of what the customer purchased", + "properties": { + "archived": { + "default": false, + "deprecated": true, + "description": "Whether the order is archived", + "type": "boolean" + }, + "archivedAt": { + "$ref": "#/$defs/date-time" + }, + "billing": { + "$ref": "#/$defs/Billing" + }, + "canceledAt": { + "$ref": "#/$defs/date-time" + }, + "cartId": { + "description": "ID associated with a cart. Used to link orders and carts for Inventory tracking purposes", + "type": "string" + }, + "completedAt": { + "$ref": "#/$defs/date-time" + }, + "context": { + "description": "Context for an order", + "properties": { + "businessId": { + "description": "ID of the business that the order belongs to", + "example": "5d370f50-05f8-4dc3-9b20-80a7552232b2", + "type": "string" + }, + "channelId": { + "description": "ID of the channel that the order belongs to", + "example": "54ee725f-8dee-4b0f-908b-e0334e6628f5", + "type": "string" + }, + "owner": { + "default": "urn:com.godaddy:commerce.order", + "description": "Owner creating the order in the order service. This is distinct from a channel. If not provided, the owner will be the Central Order Service", + "example": "urn:com.godaddy:poynt.commerce.order", + "type": "string" + }, + "storeId": { + "description": "ID of the store that the order belongs to", + "example": "fd3d9291-dc9a-445d-aa68-d2ff1a77a83c", + "type": "string" + }, + "ventureId": { + "description": "ID of the venture that the order belongs to", + "example": "7226696b-1482-444e-ba03-cd07bbe97d45", + "type": "string" + } + }, + "required": [ + "channelId", + "storeId" + ], + "type": "object" + }, + "createdAt": { + "$ref": "#/$defs/date-time" + }, + "customerId": { + "description": "Reference to a Customer as defined by the Connections service", + "type": "string" + }, + "deprecatedNote": { + "deprecated": true, + "description": "Deprecated note field - use notes array instead", + "type": "string" + }, + "discounts": { + "description": "Discounts for an order", + "items": { + "$ref": "#/$defs/Discount" + }, + "type": "array" + }, + "externalId": { + "description": "External identifier for the order. If provided, it must be a unique identifier at a channel level", + "example": "CI-C8ACE3DB52D7", + "type": "string" + }, + "fees": { + "description": "Fees for an order", + "items": { + "$ref": "#/$defs/Fee" + }, + "type": "array" + }, + "fulfilledAt": { + "$ref": "#/$defs/date-time" + }, + "fulfillmentModes": { + "description": "Fulfillment modes used across line items for the order", + "items": { + "$ref": "#/$defs/FulfillmentMode" + }, + "readOnly": true, + "type": "array" + }, + "history": { + "description": "List of history events associated to this order", + "items": { + "$ref": "#/$defs/HistoryEvent" + }, + "readOnly": true, + "type": "array" + }, + "id": { + "description": "An identifier unique to the order (Order_). Auto-generated by the service on creation", + "example": "Order_2G5VsWEFhIktH8PY4qC0iOGDpVJ", + "readOnly": true, + "type": "string" + }, + "inventoryAction": { + "$ref": "#/$defs/InventoryAction" + }, + "lineItems": { + "description": "Line items for an order", + "items": { + "$ref": "#/$defs/LineItem" + }, + "type": "array" + }, + "links": { + "description": "List of links associated to this order", + "items": { + "$ref": "#/$defs/link-description" + }, + "readOnly": true, + "type": "array" + }, + "notes": { + "description": "Notes for an order", + "items": { + "$ref": "#/$defs/Note" + }, + "type": "array" + }, + "number": { + "description": "The main number for the order. This is different from the `id` attribute, which is the `ID` of the order used by APIs. Uniqueness is not enforced. This number will show up in Order UIs to the merchant (C1).", + "example": "R409480421", + "type": "string" + }, + "numberDisplay": { + "description": "A human readable number handed out to customers (C2). Uniqueness is not enforced. For example at In-N-Out Burger, they assign an Order a `numberDisplay` from 1 - 100. Once the `numberDisplay` hits 100, the next Order has `numberDisplay` set to 1.", + "example": "110", + "type": "string" + }, + "orderVersion": { + "description": "Version identifier for the order. Changes whenever the order is updated.", + "type": "string" + }, + "paidAt": { + "$ref": "#/$defs/date-time" + }, + "processedAt": { + "$ref": "#/$defs/date-time" + }, + "refundedAt": { + "$ref": "#/$defs/date-time" + }, + "returnTotals": { + "$ref": "#/$defs/OrderReturnTotals" + }, + "shipping": { + "$ref": "#/$defs/Shipping" + }, + "shippingLines": { + "description": "Shipping lines for an order", + "items": { + "$ref": "#/$defs/ShippingLine" + }, + "type": "array" + }, + "staffUserIds": { + "description": "Staff users associated with the order", + "items": { + "description": "Staff user identifier", + "type": "string" + }, + "maxItems": 5, + "type": "array" + }, + "statuses": { + "description": "Current fulfillment status, payment status, and main status for the order", + "properties": { + "fulfillmentStatus": { + "$ref": "#/$defs/FulfillmentStatus" + }, + "paymentStatus": { + "$ref": "#/$defs/PaymentStatus" + }, + "status": { + "$ref": "#/$defs/OrderStatus" + } + }, + "required": [ + "status", + "paymentStatus", + "fulfillmentStatus" + ], + "type": "object" + }, + "tags": { + "description": "Tags associated to this order", + "items": { + "description": "A tag is an attribute of an order that does not change", + "example": "has_digital_goods", + "type": "string" + }, + "maxItems": 5, + "type": "array" + }, + "taxExempted": { + "default": false, + "description": "Details whether the order is tax exempt", + "type": "boolean" + }, + "taxes": { + "description": "Taxes for an order", + "items": { + "$ref": "#/$defs/OrderTax" + }, + "type": "array" + }, + "totals": { + "$ref": "#/$defs/Total" + }, + "transactionIds": { + "description": "List of transactions as defined by the Transaction Service associated with the order", + "items": { + "description": "Transaction ID", + "type": "string" + }, + "type": "array" + }, + "updatedAt": { + "$ref": "#/$defs/date-time" + } + }, + "required": [ + "context", + "statuses", + "totals", + "lineItems", + "processedAt" + ], + "title": "Order", + "type": "object" }, "OrderPatch": { "$id": "https://godaddy.com/schemas/commerce/orders/order-patch.v1", @@ -725,25 +980,25 @@ "$ref": "#/$defs/Billing" }, "canceledAt": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_canceledAt" }, "completedAt": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_completedAt" }, "context": { "description": "Context for an order", "properties": { "businessId": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_businessId" }, "channelId": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_channelId" }, "storeId": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" }, "ventureId": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_ventureId" } }, "required": [ @@ -753,7 +1008,7 @@ "type": "object" }, "customerId": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_customerId" }, "discounts": { "description": "Discounts for an order", @@ -770,7 +1025,7 @@ "type": "array" }, "fulfilledAt": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_fulfilledAt" }, "lineItems": { "description": "Line items", @@ -787,19 +1042,19 @@ "type": "array" }, "number": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_number" }, "numberDisplay": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_numberDisplay" }, "paidAt": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_paidAt" }, "processedAt": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_processedAt" }, "refundedAt": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_refundedAt" }, "shipping": { "$ref": "#/$defs/Shipping" @@ -824,10 +1079,10 @@ "description": "Current fulfillment status, payment status, and main status for the order", "properties": { "fulfillmentStatus": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_statuses_fulfillmentStatus" }, "paymentStatus": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_statuses_paymentStatus" } }, "required": [ @@ -847,7 +1102,7 @@ "type": "array" }, "taxExempted": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_taxExempted" }, "taxes": { "description": "Taxes for an order", @@ -983,6 +1238,75 @@ "title": "Order Tax", "type": "object" }, + "Order_canceledAt": { + "$ref": "#/$defs/date-time" + }, + "Order_completedAt": { + "$ref": "#/$defs/date-time" + }, + "Order_context_businessId": { + "description": "ID of the business that the order belongs to", + "example": "5d370f50-05f8-4dc3-9b20-80a7552232b2", + "type": "string" + }, + "Order_context_channelId": { + "description": "ID of the channel that the order belongs to", + "example": "54ee725f-8dee-4b0f-908b-e0334e6628f5", + "type": "string" + }, + "Order_context_storeId": { + "description": "ID of the store that the order belongs to", + "example": "fd3d9291-dc9a-445d-aa68-d2ff1a77a83c", + "type": "string" + }, + "Order_context_ventureId": { + "description": "ID of the venture that the order belongs to", + "example": "7226696b-1482-444e-ba03-cd07bbe97d45", + "type": "string" + }, + "Order_customerId": { + "description": "Reference to a Customer as defined by the Connections service", + "type": "string" + }, + "Order_fulfilledAt": { + "$ref": "#/$defs/date-time" + }, + "Order_id": { + "description": "An identifier unique to the order (Order_). Auto-generated by the service on creation", + "example": "Order_2G5VsWEFhIktH8PY4qC0iOGDpVJ", + "readOnly": true, + "type": "string" + }, + "Order_number": { + "description": "The main number for the order. This is different from the `id` attribute, which is the `ID` of the order used by APIs. Uniqueness is not enforced. This number will show up in Order UIs to the merchant (C1).", + "example": "R409480421", + "type": "string" + }, + "Order_numberDisplay": { + "description": "A human readable number handed out to customers (C2). Uniqueness is not enforced. For example at In-N-Out Burger, they assign an Order a `numberDisplay` from 1 - 100. Once the `numberDisplay` hits 100, the next Order has `numberDisplay` set to 1.", + "example": "110", + "type": "string" + }, + "Order_paidAt": { + "$ref": "#/$defs/date-time" + }, + "Order_processedAt": { + "$ref": "#/$defs/date-time" + }, + "Order_refundedAt": { + "$ref": "#/$defs/date-time" + }, + "Order_statuses_fulfillmentStatus": { + "$ref": "#/$defs/FulfillmentStatus" + }, + "Order_statuses_paymentStatus": { + "$ref": "#/$defs/PaymentStatus" + }, + "Order_taxExempted": { + "default": false, + "description": "Details whether the order is tax exempt", + "type": "boolean" + }, "PaymentStatus": { "$id": "https://godaddy.com/schemas/commerce/orders/payment-status.v1", "$schema": "https://json-schema.org/draft/2020-12/schema", @@ -2106,7 +2430,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -2413,7 +2737,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } } ], @@ -2519,7 +2843,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } } ], @@ -2625,7 +2949,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -2773,7 +3097,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -2782,7 +3106,7 @@ "name": "orderId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_id" } } ], @@ -2879,7 +3203,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -2888,7 +3212,7 @@ "name": "orderId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_id" } } ], @@ -2993,7 +3317,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -3002,7 +3326,7 @@ "name": "orderId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_id" } } ], @@ -3099,7 +3423,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -3108,7 +3432,7 @@ "name": "orderId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_id" } } ], @@ -3205,7 +3529,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -3214,7 +3538,7 @@ "name": "orderId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_id" } } ], @@ -3311,7 +3635,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -3320,7 +3644,7 @@ "name": "orderId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_id" } } ], @@ -3417,7 +3741,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -3426,7 +3750,7 @@ "name": "orderId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_id" } } ], @@ -3512,7 +3836,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } } ], @@ -3603,7 +3927,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -3697,7 +4021,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { @@ -3802,7 +4126,7 @@ "name": "storeId", "required": true, "schema": { - "$ref": "#/$defs/Order" + "$ref": "#/$defs/Order_context_storeId" } }, { diff --git a/rust/tools/generate-api-catalog/src/main.rs b/rust/tools/generate-api-catalog/src/main.rs index 3df99dee..d2525bf0 100644 --- a/rust/tools/generate-api-catalog/src/main.rs +++ b/rust/tools/generate-api-catalog/src/main.rs @@ -693,11 +693,12 @@ fn json_pointer_escape(s: &str) -> String { /// `./models/Order.yaml` → `"Order"` /// `https://.../error.json` → `"error"` fn derive_defs_key_for_path(ref_str: &str) -> String { + let frag = ref_str.find('#').map(|idx| &ref_str[idx..]); + // External refs with a component-schema fragment (e.g. `./common.yaml#/components/schemas/Foo`) // use the component name as the key, consistent with pure local `#/components/schemas/` refs // and avoiding collisions when the same file is referenced for different components. - if let Some(frag_idx) = ref_str.find('#') { - let frag = &ref_str[frag_idx..]; + if let Some(frag) = frag { for prefix in &["#/components/schemas/", "#/definitions/"] { if let Some(rest) = frag.strip_prefix(prefix) { let name = rest.split('/').next().unwrap_or(rest); @@ -705,13 +706,32 @@ fn derive_defs_key_for_path(ref_str: &str) -> String { } } } + let file_part = ref_str.split('#').next().unwrap_or(ref_str); let last_seg = file_part.rsplit(['/', '\\']).next().unwrap_or(file_part); let stem = match last_seg.rfind('.') { Some(pos) => &last_seg[..pos], None => last_seg, }; - sanitize_defs_key(stem) + let base_key = sanitize_defs_key(stem); + + // A `#/properties/` fragment (optionally nested, e.g. `#/properties/a/properties/b`) + // selects one property's schema out of the file, not the file's root schema — fold the + // property path into the key so two refs into the same file for different properties + // don't collide under one bare file-stem key. Each segment has its literal `_` doubled + // before joining on a single `_`, so a property literally named `a_b` can't collide with + // nested segments `a` + `b` (both would otherwise sanitize to the same `a_b` suffix). + match frag.and_then(|f| f.strip_prefix("#/properties/")) { + Some(rest) => { + let suffix = rest + .split("/properties/") + .map(|seg| seg.replace('_', "__")) + .collect::>() + .join("_"); + sanitize_defs_key(&format!("{base_key}_{suffix}")) + } + None => base_key, + } } fn sanitize_defs_key(s: &str) -> String { @@ -2253,6 +2273,28 @@ components: derive_defs_key_for_path("./shared.yaml#/definitions/Bar"), "Bar" ); + // A `#/properties/` fragment picks out one property's schema, not the + // file's root schema — it must be folded into the key so two refs into the + // same file for different properties don't collide (DEVEX-965). + assert_eq!( + derive_defs_key_for_path("./models/FulfillmentPlan.yaml#/properties/storeId"), + "FulfillmentPlan_storeId" + ); + assert_eq!( + derive_defs_key_for_path("./models/FulfillmentPlan.yaml#/properties/orderId"), + "FulfillmentPlan_orderId" + ); + assert_eq!( + derive_defs_key_for_path("./models/Foo.yaml#/properties/a/properties/b"), + "Foo_a_b" + ); + // A literal property named `a_b` must not collide with nested segments `a` + // then `b` — both would sanitize to the same "a_b" suffix without escaping + // the literal underscore first. + assert_ne!( + derive_defs_key_for_path("./models/Foo.yaml#/properties/a_b"), + derive_defs_key_for_path("./models/Foo.yaml#/properties/a/properties/b") + ); } #[test]