diff --git a/docs/developer-portal/06-delivery-byoc-api-1-0-0-audit.md b/docs/developer-portal/06-delivery-byoc-api-1-0-0-audit.md new file mode 100644 index 0000000..9ffcd55 --- /dev/null +++ b/docs/developer-portal/06-delivery-byoc-api-1-0-0-audit.md @@ -0,0 +1,22 @@ +# 06 Delivery BYOC API 1.0.0 Audit + +Source checked: "Delivery BYOC API (1.0.0)" shared by you. + +## Implemented Now + +- Ingest Courier Live Location endpoint: + - `POST /api/v1/uber/delivery-byoc/courier-location` + - upstream: `/v1/eats/byoc/restaurants/orders/event/location` + +## Validation Added + +- `location_request.order_workflow_uuid` required UUID +- `location_request.restaurant_uuid` required UUID +- `location_request.location_events` required array +- optional batched-order and location telemetry fields supported + +## Pending + +- Exact nested `location_events` schema expansion once full reference object is shared +- Region/partner-level eligibility checks prior to ingestion (operational policy layer) + diff --git a/docs/developer-portal/06-orders.md b/docs/developer-portal/06-orders.md index bc43a5c..6014e74 100644 --- a/docs/developer-portal/06-orders.md +++ b/docs/developer-portal/06-orders.md @@ -43,3 +43,7 @@ Order API 1.0.0 coverage (delivery namespace): Delivery Partner API 1.0.0 coverage: - `POST /api/v1/uber/delivery-partner/orders/{orderId}/partner-count` (Dispatch Multiple Courier) + +Delivery BYOC API 1.0.0 coverage: + +- `POST /api/v1/uber/delivery-byoc/courier-location` (Ingest Courier Live Location) diff --git a/docs/openapi/openapi.json b/docs/openapi/openapi.json index 4b1ea8b..6a06089 100644 --- a/docs/openapi/openapi.json +++ b/docs/openapi/openapi.json @@ -1013,6 +1013,19 @@ } } }, + "/api/v1/uber/delivery-byoc/courier-location": { + "post": { + "summary": "Delivery BYOC API 1.0.0 - Ingest courier live location", + "tags": [ + "Uber Delivery BYOC v1" + ], + "responses": { + "200": { + "description": "Courier location ingested" + } + } + } + }, "/api/v1/uber/reporting/fetch": { "post": { "summary": "Fetch Uber reporting CSV with retries and header-based parsing", diff --git a/postman/Uber_Wrapper.postman_collection.json b/postman/Uber_Wrapper.postman_collection.json index b28e97a..1a42297 100644 --- a/postman/Uber_Wrapper.postman_collection.json +++ b/postman/Uber_Wrapper.postman_collection.json @@ -894,6 +894,39 @@ } } }, + { + "name": "Delivery BYOC API - Ingest Courier Location", + "request": { + "method": "POST", + "header": [ + { + "key": "x-api-key", + "value": "{{apiKey}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"location_request\": {\n \"order_workflow_uuid\": \"96057115-4fb3-474a-bbeb-dd65b7405a80\",\n \"restaurant_uuid\": \"4f6d8de4-bb1d-4cf6-81c3-fe981b184751\",\n \"is_batched_order\": false,\n \"location_events\": []\n }\n}" + }, + "url": { + "raw": "{{baseUrl}}/api/v1/uber/delivery-byoc/courier-location", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "uber", + "delivery-byoc", + "courier-location" + ] + } + } + }, { "name": "Get Store By ID", "request": { diff --git a/src/config/uberEndpoints.js b/src/config/uberEndpoints.js index 65b0a90..1465f51 100644 --- a/src/config/uberEndpoints.js +++ b/src/config/uberEndpoints.js @@ -46,6 +46,9 @@ module.exports = { deliveryPartner: { updateDeliveryPartnerCount: "/v1/delivery/order/{orderId}/update-delivery-partner-count" }, + deliveryByoc: { + ingestCourierLocation: "/v1/eats/byoc/restaurants/orders/event/location" + }, webhooks: { events: "/v1/eats/stores/{storeId}/event_feed" } diff --git a/src/modules/proxy/proxy.controller.js b/src/modules/proxy/proxy.controller.js index 64cb757..747bc26 100644 --- a/src/modules/proxy/proxy.controller.js +++ b/src/modules/proxy/proxy.controller.js @@ -609,6 +609,32 @@ async function deliveryUpdatePartnerCount(req, res) { return res.json({ success: true, data }); } +async function deliveryByocIngestCourierLocation(req, res) { + const locationEventSchema = z.object({ + timestamp: z.union([z.number(), z.string()]).optional(), + latitude: z.number().optional(), + longitude: z.number().optional(), + accuracy_meters: z.number().optional(), + speed_mps: z.number().optional(), + heading_degrees: z.number().optional() + }); + + const schema = z.object({ + location_request: z.object({ + order_workflow_uuid: z.string().uuid(), + restaurant_uuid: z.string().uuid(), + is_batched_order: z.boolean().optional(), + location_events: z.array(locationEventSchema) + }) + }); + + const payload = schema.parse(req.body || {}); + const data = await proxyService.deliveryByocIngestCourierLocation({ + payload + }); + return res.json({ success: true, data }); +} + module.exports = { genericProxy, upsertMenu, @@ -649,5 +675,6 @@ module.exports = { deliveryUpdateReadyTime, deliveryResolveFulfillmentIssues, deliveryGetReplacementRecommendations, - deliveryUpdatePartnerCount + deliveryUpdatePartnerCount, + deliveryByocIngestCourierLocation }; diff --git a/src/modules/proxy/proxy.service.js b/src/modules/proxy/proxy.service.js index ffe8c54..79fe16e 100644 --- a/src/modules/proxy/proxy.service.js +++ b/src/modules/proxy/proxy.service.js @@ -601,6 +601,17 @@ async function deliveryUpdatePartnerCount({ orderId, payload }) { }); } +async function deliveryByocIngestCourierLocation({ payload }) { + return callUberApi({ + method: "POST", + uberPath: uberEndpoints.deliveryByoc.ingestCourierLocation, + body: payload, + wrapperRoute: "/api/v1/uber/delivery-byoc/courier-location", + authMode: "app", + scopes: AUTH_SCOPES.BYOC_FULFILLMENT_CONFIG + }); +} + module.exports = { genericProxy, menuUpsert, @@ -641,5 +652,6 @@ module.exports = { deliveryUpdateReadyTime, deliveryResolveFulfillmentIssues, deliveryGetReplacementRecommendations, - deliveryUpdatePartnerCount + deliveryUpdatePartnerCount, + deliveryByocIngestCourierLocation }; diff --git a/src/routes/proxy.routes.js b/src/routes/proxy.routes.js index e3ce2ef..a893366 100644 --- a/src/routes/proxy.routes.js +++ b/src/routes/proxy.routes.js @@ -672,4 +672,20 @@ router.post( asyncHandler(controller.deliveryUpdatePartnerCount) ); +/** + * @openapi + * /api/v1/uber/delivery-byoc/courier-location: + * post: + * summary: Delivery BYOC API 1.0.0 - Ingest courier live location + * tags: + * - Uber Delivery BYOC v1 + * responses: + * 200: + * description: Courier location ingested + */ +router.post( + "/uber/delivery-byoc/courier-location", + asyncHandler(controller.deliveryByocIngestCourierLocation) +); + module.exports = router;