Align Update Item to v2 sparse item endpoint
This commit is contained in:
parent
d80f9e9baf
commit
519f2f7169
@ -17,7 +17,9 @@ Source checked: Uber Eats "Menu Integration" section shared by you.
|
|||||||
- validates known menu_type enum values
|
- validates known menu_type enum values
|
||||||
- Individual item updates:
|
- Individual item updates:
|
||||||
- `POST /api/v1/uber/menu/items`
|
- `POST /api/v1/uber/menu/items`
|
||||||
- supports stock/price style item-level updates via Menu Items endpoint
|
- aligned to upstream `POST /v2/eats/stores/{store_id}/menus/items/{item_id}`
|
||||||
|
- request body is sparse update (only provided fields are changed)
|
||||||
|
- supports `menu_type` enum for split delivery/pickup/dine-in menus
|
||||||
|
|
||||||
## Existing Before
|
## Existing Before
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,13 @@ Current wrapper route for full replacement:
|
|||||||
Item update route:
|
Item update route:
|
||||||
|
|
||||||
- `POST /api/v1/uber/menu/items`
|
- `POST /api/v1/uber/menu/items`
|
||||||
|
- upstream mapped to `POST /v2/eats/stores/{store_id}/menus/items/{item_id}`
|
||||||
|
- sparse update only (only provided fields are changed)
|
||||||
|
- wrapper payload shape:
|
||||||
|
- `merchantId`
|
||||||
|
- `storeId`
|
||||||
|
- `itemId`
|
||||||
|
- `update` object with fields such as `price_info`, `suspension_info`, `menu_type`, `product_info`, `classifications`, `beverage_info`, `physical_properties_info`, `medication_info`, `nutritional_info`, `selling_info`
|
||||||
|
|
||||||
Menu fetch route:
|
Menu fetch route:
|
||||||
|
|
||||||
|
|||||||
@ -318,13 +318,13 @@
|
|||||||
},
|
},
|
||||||
"/api/v1/uber/menu/items": {
|
"/api/v1/uber/menu/items": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "Update individual menu items (stock/price updates)",
|
"summary": "Update single menu item (POST /v2/eats/stores/{store_id}/menus/items/{item_id})",
|
||||||
"tags": [
|
"tags": [
|
||||||
"Uber Menu"
|
"Uber Menu"
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
"200": {
|
"200": {
|
||||||
"description": "Menu items updated"
|
"description": "Menu item sparsely updated (Uber returns 204 No Content)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -200,7 +200,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "Update Menu Items",
|
"name": "Update Item (v2 Sparse)",
|
||||||
"request": {
|
"request": {
|
||||||
"method": "POST",
|
"method": "POST",
|
||||||
"header": [
|
"header": [
|
||||||
@ -215,7 +215,7 @@
|
|||||||
],
|
],
|
||||||
"body": {
|
"body": {
|
||||||
"mode": "raw",
|
"mode": "raw",
|
||||||
"raw": "{\n \"merchantId\": \"{{merchantId}}\",\n \"storeId\": \"{{storeId}}\",\n \"items\": [\n {\n \"id\": \"item_1\",\n \"price_info\": {\n \"price\": 799\n },\n \"suspension_info\": {\n \"suspend_until\": null\n }\n }\n ]\n}"
|
"raw": "{\n \"merchantId\": \"{{merchantId}}\",\n \"storeId\": \"{{storeId}}\",\n \"itemId\": \"item_1\",\n \"update\": {\n \"menu_type\": \"MENU_TYPE_FULFILLMENT_DELIVERY\",\n \"price_info\": {\n \"price\": 799\n },\n \"suspension_info\": {\n \"suspension\": null\n }\n }\n}"
|
||||||
},
|
},
|
||||||
"url": {
|
"url": {
|
||||||
"raw": "{{baseUrl}}/api/v1/uber/menu/items",
|
"raw": "{{baseUrl}}/api/v1/uber/menu/items",
|
||||||
|
|||||||
@ -3,7 +3,7 @@ module.exports = {
|
|||||||
upsert: "/v1/eats/stores/{storeId}/menus",
|
upsert: "/v1/eats/stores/{storeId}/menus",
|
||||||
upload: "/v2/eats/stores/{storeId}/menus",
|
upload: "/v2/eats/stores/{storeId}/menus",
|
||||||
get: "/v2/eats/stores/{storeId}/menus",
|
get: "/v2/eats/stores/{storeId}/menus",
|
||||||
itemsUpdate: "/v1/eats/stores/{storeId}/menus/items"
|
itemUpdate: "/v2/eats/stores/{storeId}/menus/items/{itemId}"
|
||||||
},
|
},
|
||||||
orders: {
|
orders: {
|
||||||
list: "/v1/eats/stores/{storeId}/orders",
|
list: "/v1/eats/stores/{storeId}/orders",
|
||||||
|
|||||||
@ -90,16 +90,41 @@ async function replaceMenu(req, res) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function updateMenuItems(req, res) {
|
async function updateMenuItems(req, res) {
|
||||||
|
const menuTypeEnum = z.enum([
|
||||||
|
"MENU_TYPE_FULFILLMENT_DELIVERY",
|
||||||
|
"MENU_TYPE_FULFILLMENT_PICK_UP",
|
||||||
|
"MENU_TYPE_FULFILLMENT_DINE_IN"
|
||||||
|
]);
|
||||||
|
|
||||||
|
const updateSchema = z
|
||||||
|
.object({
|
||||||
|
price_info: z.any().optional(),
|
||||||
|
suspension_info: z.any().optional(),
|
||||||
|
menu_type: menuTypeEnum.optional(),
|
||||||
|
product_info: z.any().optional(),
|
||||||
|
classifications: z.any().optional(),
|
||||||
|
beverage_info: z.any().optional(),
|
||||||
|
physical_properties_info: z.any().optional(),
|
||||||
|
medication_info: z.any().optional(),
|
||||||
|
nutritional_info: z.any().optional(),
|
||||||
|
selling_info: z.any().optional()
|
||||||
|
})
|
||||||
|
.refine((value) => Object.keys(value).length > 0, {
|
||||||
|
message: "update must include at least one sparse-update field"
|
||||||
|
});
|
||||||
|
|
||||||
const schema = z.object({
|
const schema = z.object({
|
||||||
merchantId: z.string().min(1),
|
merchantId: z.string().min(1),
|
||||||
storeId: z.string().min(1),
|
storeId: z.string().min(1),
|
||||||
items: z.array(z.any()).min(1)
|
itemId: z.string().min(1),
|
||||||
|
update: updateSchema
|
||||||
});
|
});
|
||||||
const payload = schema.parse(req.body);
|
const payload = schema.parse(req.body);
|
||||||
const data = await proxyService.updateMenuItems({
|
const data = await proxyService.updateMenuItems({
|
||||||
merchantId: payload.merchantId,
|
merchantId: payload.merchantId,
|
||||||
storeId: payload.storeId,
|
storeId: payload.storeId,
|
||||||
payload: { items: payload.items }
|
itemId: payload.itemId,
|
||||||
|
payload: payload.update
|
||||||
});
|
});
|
||||||
return res.json({ success: true, data });
|
return res.json({ success: true, data });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -188,8 +188,8 @@ async function menuGet({ merchantId, storeId, menuType }) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function updateMenuItems({ merchantId, storeId, payload }) {
|
async function updateMenuItems({ merchantId, storeId, itemId, payload }) {
|
||||||
const uberPath = interpolatePath(uberEndpoints.menu.itemsUpdate, { storeId });
|
const uberPath = interpolatePath(uberEndpoints.menu.itemUpdate, { storeId, itemId });
|
||||||
return callUberApi({
|
return callUberApi({
|
||||||
merchantId,
|
merchantId,
|
||||||
method: "POST",
|
method: "POST",
|
||||||
|
|||||||
@ -47,12 +47,12 @@ router.put("/uber/menu/replace", asyncHandler(controller.replaceMenu));
|
|||||||
* @openapi
|
* @openapi
|
||||||
* /api/v1/uber/menu/items:
|
* /api/v1/uber/menu/items:
|
||||||
* post:
|
* post:
|
||||||
* summary: Update individual menu items (stock/price updates)
|
* summary: Update single menu item (POST /v2/eats/stores/{store_id}/menus/items/{item_id})
|
||||||
* tags:
|
* tags:
|
||||||
* - Uber Menu
|
* - Uber Menu
|
||||||
* responses:
|
* responses:
|
||||||
* 200:
|
* 200:
|
||||||
* description: Menu items updated
|
* description: Menu item sparsely updated (Uber returns 204 No Content)
|
||||||
*/
|
*/
|
||||||
router.post("/uber/menu/items", asyncHandler(controller.updateMenuItems));
|
router.post("/uber/menu/items", asyncHandler(controller.updateMenuItems));
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user