From d4042fb656a0868afe3b6f88f60f657daa58b1fd Mon Sep 17 00:00:00 2001 From: MOHAN Date: Sun, 29 Mar 2026 18:18:38 +0530 Subject: [PATCH] feat: implement uber store api v1.0.0 delivery endpoints and validations --- .../04-store-api-1-0-0-audit.md | 40 +++ docs/developer-portal/04-stores.md | 10 + docs/openapi/openapi.json | 147 +++++++++++ postman/Uber_Wrapper.postman_collection.json | 229 ++++++++++++++++++ src/config/uberEndpoints.js | 9 + src/modules/auth/auth.controller.js | 3 +- src/modules/auth/auth.service.js | 4 +- src/modules/proxy/proxy.controller.js | 115 ++++++++- src/modules/proxy/proxy.service.js | 91 ++++++- src/routes/proxy.routes.js | 129 ++++++++++ 10 files changed, 773 insertions(+), 4 deletions(-) create mode 100644 docs/developer-portal/04-store-api-1-0-0-audit.md diff --git a/docs/developer-portal/04-store-api-1-0-0-audit.md b/docs/developer-portal/04-store-api-1-0-0-audit.md new file mode 100644 index 0000000..356f344 --- /dev/null +++ b/docs/developer-portal/04-store-api-1-0-0-audit.md @@ -0,0 +1,40 @@ +# 04 Store API 1.0.0 Audit + +Source checked: "Uber Eats Marketplace Store API (1.0.0)" shared by you. + +## Implemented Now (Dedicated Wrapper Namespace) + +- Get Stores: + - `GET /api/v1/uber/delivery-store/stores` + - upstream: `/v1/delivery/stores` +- Get Store Details: + - `GET /api/v1/uber/delivery-store/stores/{storeId}` + - upstream: `/v1/delivery/store/{store_id}` +- Update Store Information: + - `POST /api/v1/uber/delivery-store/stores/{storeId}` + - upstream: `/v1/delivery/store/{store_id}` + - supports contact/location/pickup_instructions only +- Retrieve Store Status: + - `GET /api/v1/uber/delivery-store/stores/{storeId}/status` + - upstream: `/v1/delivery/store/{store_id}/status` +- Set Store Status: + - `POST /api/v1/uber/delivery-store/stores/{storeId}/status` + - upstream: `/v1/delivery/store/{store_id}/update-store-status` +- Update Prep Time: + - `POST /api/v1/uber/delivery-store/stores/{storeId}/prep-time` + - upstream: `/v1/delivery/store/{store_id}/update-store-prep-time` +- Update Fulfillment Configuration (BYOC): + - `POST /api/v1/uber/delivery-store/stores/{storeId}/fulfillment-configuration` + - upstream: `/v1/delivery/store/{store_id}/update-fulfillment-configuration` + +## Validation Added + +- status: `ONLINE|OFFLINE` enum +- prep time max: 10,800 seconds +- store update restricted to contact/location/pickup fields + +## Pending + +- Optional stricter schemas for nested location/contact formats per country-specific variants +- Dedicated request-builder helpers for BYOC fulfillment override fields + diff --git a/docs/developer-portal/04-stores.md b/docs/developer-portal/04-stores.md index a9f519e..b10bd39 100644 --- a/docs/developer-portal/04-stores.md +++ b/docs/developer-portal/04-stores.md @@ -15,3 +15,13 @@ Typed routes available: - `POST /api/v1/uber/stores/{storeId}/status` - `GET /api/v1/uber/stores/{storeId}/holiday-hours` - `POST /api/v1/uber/stores/{storeId}/holiday-hours` + +Store API 1.0.0 coverage (delivery namespace): + +- `GET /api/v1/uber/delivery-store/stores` +- `GET /api/v1/uber/delivery-store/stores/{storeId}` +- `POST /api/v1/uber/delivery-store/stores/{storeId}` +- `GET /api/v1/uber/delivery-store/stores/{storeId}/status` +- `POST /api/v1/uber/delivery-store/stores/{storeId}/status` +- `POST /api/v1/uber/delivery-store/stores/{storeId}/prep-time` +- `POST /api/v1/uber/delivery-store/stores/{storeId}/fulfillment-configuration` diff --git a/docs/openapi/openapi.json b/docs/openapi/openapi.json index b224264..10af0fc 100644 --- a/docs/openapi/openapi.json +++ b/docs/openapi/openapi.json @@ -693,6 +693,153 @@ } } }, + "/api/v1/uber/delivery-store/stores": { + "get": { + "summary": "Store API 1.0.0 - Get stores (/v1/delivery/stores)", + "tags": [ + "Uber Delivery Store v1" + ], + "responses": { + "200": { + "description": "Stores retrieved" + } + } + } + }, + "/api/v1/uber/delivery-store/stores/{storeId}": { + "get": { + "summary": "Store API 1.0.0 - Get store details", + "tags": [ + "Uber Delivery Store v1" + ], + "parameters": [ + { + "in": "path", + "name": "storeId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Store details retrieved" + } + } + }, + "post": { + "summary": "Store API 1.0.0 - Update store information", + "tags": [ + "Uber Delivery Store v1" + ], + "parameters": [ + { + "in": "path", + "name": "storeId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Store information updated" + } + } + } + }, + "/api/v1/uber/delivery-store/stores/{storeId}/status": { + "get": { + "summary": "Store API 1.0.0 - Retrieve store status", + "tags": [ + "Uber Delivery Store v1" + ], + "parameters": [ + { + "in": "path", + "name": "storeId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Store status retrieved" + } + } + }, + "post": { + "summary": "Store API 1.0.0 - Set store status", + "tags": [ + "Uber Delivery Store v1" + ], + "parameters": [ + { + "in": "path", + "name": "storeId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Store status updated" + } + } + } + }, + "/api/v1/uber/delivery-store/stores/{storeId}/prep-time": { + "post": { + "summary": "Store API 1.0.0 - Update prep time", + "tags": [ + "Uber Delivery Store v1" + ], + "parameters": [ + { + "in": "path", + "name": "storeId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Prep time updated" + } + } + } + }, + "/api/v1/uber/delivery-store/stores/{storeId}/fulfillment-configuration": { + "post": { + "summary": "Store API 1.0.0 - Update BYOC fulfillment configuration", + "tags": [ + "Uber Delivery Store v1" + ], + "parameters": [ + { + "in": "path", + "name": "storeId", + "required": true, + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Fulfillment configuration updated" + } + } + } + }, "/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 6c04d0a..8c7be56 100644 --- a/postman/Uber_Wrapper.postman_collection.json +++ b/postman/Uber_Wrapper.postman_collection.json @@ -287,6 +287,235 @@ } } }, + { + "name": "Delivery Store API - Get Stores", + "request": { + "method": "GET", + "header": [ + { + "key": "x-api-key", + "value": "{{apiKey}}" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/uber/delivery-store/stores?page_size=50", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "uber", + "delivery-store", + "stores" + ], + "query": [ + { + "key": "page_size", + "value": "50" + } + ] + } + } + }, + { + "name": "Delivery Store API - Get Store Details", + "request": { + "method": "GET", + "header": [ + { + "key": "x-api-key", + "value": "{{apiKey}}" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/uber/delivery-store/stores/{{storeId}}?expand=holiday_hours,internal_contact_emails", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "uber", + "delivery-store", + "stores", + "{{storeId}}" + ], + "query": [ + { + "key": "expand", + "value": "holiday_hours,internal_contact_emails" + } + ] + } + } + }, + { + "name": "Delivery Store API - Update Store", + "request": { + "method": "POST", + "header": [ + { + "key": "x-api-key", + "value": "{{apiKey}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"contact\": {\n \"email\": \"abc@restaurant.com\",\n \"name\": \"Jane Doe\",\n \"phone_number\": \"+1-800-999-9999\"\n },\n \"pickup_instructions\": \"Enter from the north side\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/api/v1/uber/delivery-store/stores/{{storeId}}", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "uber", + "delivery-store", + "stores", + "{{storeId}}" + ] + } + } + }, + { + "name": "Delivery Store API - Get Status", + "request": { + "method": "GET", + "header": [ + { + "key": "x-api-key", + "value": "{{apiKey}}" + } + ], + "url": { + "raw": "{{baseUrl}}/api/v1/uber/delivery-store/stores/{{storeId}}/status", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "uber", + "delivery-store", + "stores", + "{{storeId}}", + "status" + ] + } + } + }, + { + "name": "Delivery Store API - Set Status", + "request": { + "method": "POST", + "header": [ + { + "key": "x-api-key", + "value": "{{apiKey}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"status\": \"OFFLINE\",\n \"is_offline_until\": \"2026-04-01T10:00:00.000Z\",\n \"reason\": \"Scheduled maintenance\"\n}" + }, + "url": { + "raw": "{{baseUrl}}/api/v1/uber/delivery-store/stores/{{storeId}}/status", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "uber", + "delivery-store", + "stores", + "{{storeId}}", + "status" + ] + } + } + }, + { + "name": "Delivery Store API - Update Prep Time", + "request": { + "method": "POST", + "header": [ + { + "key": "x-api-key", + "value": "{{apiKey}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"default_prep_time\": 500\n}" + }, + "url": { + "raw": "{{baseUrl}}/api/v1/uber/delivery-store/stores/{{storeId}}/prep-time", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "uber", + "delivery-store", + "stores", + "{{storeId}}", + "prep-time" + ] + } + } + }, + { + "name": "Delivery Store API - Update Fulfillment Config", + "request": { + "method": "POST", + "header": [ + { + "key": "x-api-key", + "value": "{{apiKey}}" + }, + { + "key": "Content-Type", + "value": "application/json" + } + ], + "body": { + "mode": "raw", + "raw": "{\n \"override_config\": {\n \"custom_min_etd_minutes\": 30\n }\n}" + }, + "url": { + "raw": "{{baseUrl}}/api/v1/uber/delivery-store/stores/{{storeId}}/fulfillment-configuration", + "host": [ + "{{baseUrl}}" + ], + "path": [ + "api", + "v1", + "uber", + "delivery-store", + "stores", + "{{storeId}}", + "fulfillment-configuration" + ] + } + } + }, { "name": "Get Store By ID", "request": { diff --git a/src/config/uberEndpoints.js b/src/config/uberEndpoints.js index 18b8ccc..7a50b43 100644 --- a/src/config/uberEndpoints.js +++ b/src/config/uberEndpoints.js @@ -22,6 +22,15 @@ module.exports = { inventory: "/v1/eats/stores/{storeId}/inventory", posData: "/v1/eats/stores/{storeId}/pos_data" }, + deliveryStore: { + list: "/v1/delivery/stores", + getById: "/v1/delivery/store/{storeId}", + update: "/v1/delivery/store/{storeId}", + getStatus: "/v1/delivery/store/{storeId}/status", + setStatus: "/v1/delivery/store/{storeId}/update-store-status", + updatePrepTime: "/v1/delivery/store/{storeId}/update-store-prep-time", + updateFulfillmentConfig: "/v1/delivery/store/{storeId}/update-fulfillment-configuration" + }, webhooks: { events: "/v1/eats/stores/{storeId}/event_feed" } diff --git a/src/modules/auth/auth.controller.js b/src/modules/auth/auth.controller.js index b0bc3dd..d46175c 100644 --- a/src/modules/auth/auth.controller.js +++ b/src/modules/auth/auth.controller.js @@ -130,7 +130,8 @@ async function getAuthCapabilities(req, res) { AUTH_SCOPES.STORE_STATUS_WRITE, AUTH_SCOPES.ORDER, AUTH_SCOPES.STORE_ORDERS_READ, - AUTH_SCOPES.REPORT + AUTH_SCOPES.REPORT, + AUTH_SCOPES.BYOC_FULFILLMENT_CONFIG ], authorization_code: [AUTH_SCOPES.POS_PROVISIONING] }, diff --git a/src/modules/auth/auth.service.js b/src/modules/auth/auth.service.js index 01a38c7..a340fa6 100644 --- a/src/modules/auth/auth.service.js +++ b/src/modules/auth/auth.service.js @@ -11,11 +11,13 @@ const AUTH_GRANT_TYPES = { const AUTH_SCOPES = { STORE: "eats.store", + STORE_WRITE: "eats.store", STORE_STATUS_WRITE: "eats.store.status.write", ORDER: "eats.order", STORE_ORDERS_READ: "eats.store.orders.read", REPORT: "eats.report", - POS_PROVISIONING: "eats.pos_provisioning" + POS_PROVISIONING: "eats.pos_provisioning", + BYOC_FULFILLMENT_CONFIG: "eats.byoc.fulfillment.config" }; const uberAuthClient = axios.create({ diff --git a/src/modules/proxy/proxy.controller.js b/src/modules/proxy/proxy.controller.js index 5661473..83460a9 100644 --- a/src/modules/proxy/proxy.controller.js +++ b/src/modules/proxy/proxy.controller.js @@ -338,6 +338,112 @@ async function deletePosData(req, res) { return res.json({ success: true, data }); } +async function deliveryListStores(req, res) { + const schema = z.object({ + next_page_token: z.string().optional(), + page_size: z.coerce.number().int().min(1).max(200).optional() + }); + const query = schema.parse(req.query || {}); + const data = await proxyService.deliveryListStores({ query }); + return res.json({ success: true, data }); +} + +async function deliveryGetStoreDetails(req, res) { + const schema = z.object({ + expand: z.string().optional() + }); + const query = schema.parse(req.query || {}); + const data = await proxyService.deliveryGetStoreDetails({ + storeId: req.params.storeId, + query + }); + return res.json({ success: true, data }); +} + +async function deliveryUpdateStore(req, res) { + const contactSchema = z + .object({ + email: z.string().optional(), + name: z.string().optional(), + phone_number: z.string().optional() + }) + .optional(); + const locationSchema = z + .object({ + latitude: z.number().optional(), + longitude: z.number().optional(), + street_address_line_one: z.string().optional(), + street_address_line_two: z.string().optional(), + city: z.string().optional(), + country: z.string().optional(), + postal_code: z.union([z.string(), z.number()]).optional(), + unit_number: z.union([z.string(), z.number()]).optional(), + business_name: z.string().optional() + }) + .optional(); + const schema = z.object({ + contact: contactSchema, + location: locationSchema, + pickup_instructions: z.string().optional() + }); + const payload = schema + .refine((value) => Object.keys(value).length > 0, { + message: "At least one of contact/location/pickup_instructions is required" + }) + .parse(req.body || {}); + + const data = await proxyService.deliveryUpdateStore({ + storeId: req.params.storeId, + payload + }); + return res.json({ success: true, data }); +} + +async function deliveryGetStoreStatus(req, res) { + const data = await proxyService.deliveryGetStoreStatus({ + storeId: req.params.storeId + }); + return res.json({ success: true, data }); +} + +async function deliverySetStoreStatus(req, res) { + const schema = z.object({ + status: z.enum(["ONLINE", "OFFLINE"]), + is_offline_until: z.string().optional(), + reason: z.string().optional() + }); + const payload = schema.parse(req.body || {}); + const data = await proxyService.deliverySetStoreStatus({ + storeId: req.params.storeId, + payload + }); + return res.json({ success: true, data }); +} + +async function deliveryUpdatePrepTime(req, res) { + const schema = z.object({ + default_prep_time: z.coerce.number().int().min(0).max(10800) + }); + const payload = schema.parse(req.body || {}); + const data = await proxyService.deliveryUpdatePrepTime({ + storeId: req.params.storeId, + payload + }); + return res.json({ success: true, data }); +} + +async function deliveryUpdateFulfillmentConfig(req, res) { + const schema = z.object({ + override_config: z.record(z.string(), z.any()) + }); + const payload = schema.parse(req.body || {}); + const data = await proxyService.deliveryUpdateFulfillmentConfig({ + storeId: req.params.storeId, + payload + }); + return res.json({ success: true, data }); +} + module.exports = { genericProxy, upsertMenu, @@ -360,5 +466,12 @@ module.exports = { createPosData, getPosData, patchPosData, - deletePosData + deletePosData, + deliveryListStores, + deliveryGetStoreDetails, + deliveryUpdateStore, + deliveryGetStoreStatus, + deliverySetStoreStatus, + deliveryUpdatePrepTime, + deliveryUpdateFulfillmentConfig }; diff --git a/src/modules/proxy/proxy.service.js b/src/modules/proxy/proxy.service.js index 24c4771..0d09e03 100644 --- a/src/modules/proxy/proxy.service.js +++ b/src/modules/proxy/proxy.service.js @@ -388,6 +388,88 @@ async function deletePosData({ storeId }) { }); } +async function deliveryListStores({ query }) { + return callUberApi({ + method: "GET", + uberPath: uberEndpoints.deliveryStore.list, + query, + wrapperRoute: "/api/v1/uber/delivery-store/stores", + authMode: "app", + scopes: AUTH_SCOPES.STORE + }); +} + +async function deliveryGetStoreDetails({ storeId, query }) { + const uberPath = interpolatePath(uberEndpoints.deliveryStore.getById, { storeId }); + return callUberApi({ + method: "GET", + uberPath, + query, + wrapperRoute: "/api/v1/uber/delivery-store/stores/:storeId", + authMode: "app", + scopes: AUTH_SCOPES.STORE + }); +} + +async function deliveryUpdateStore({ storeId, payload }) { + const uberPath = interpolatePath(uberEndpoints.deliveryStore.update, { storeId }); + return callUberApi({ + method: "POST", + uberPath, + body: payload, + wrapperRoute: "/api/v1/uber/delivery-store/stores/:storeId", + authMode: "app", + scopes: AUTH_SCOPES.STORE_WRITE + }); +} + +async function deliveryGetStoreStatus({ storeId }) { + const uberPath = interpolatePath(uberEndpoints.deliveryStore.getStatus, { storeId }); + return callUberApi({ + method: "GET", + uberPath, + wrapperRoute: "/api/v1/uber/delivery-store/stores/:storeId/status", + authMode: "app", + scopes: AUTH_SCOPES.STORE + }); +} + +async function deliverySetStoreStatus({ storeId, payload }) { + const uberPath = interpolatePath(uberEndpoints.deliveryStore.setStatus, { storeId }); + return callUberApi({ + method: "POST", + uberPath, + body: payload, + wrapperRoute: "/api/v1/uber/delivery-store/stores/:storeId/status", + authMode: "app", + scopes: AUTH_SCOPES.STORE_STATUS_WRITE + }); +} + +async function deliveryUpdatePrepTime({ storeId, payload }) { + const uberPath = interpolatePath(uberEndpoints.deliveryStore.updatePrepTime, { storeId }); + return callUberApi({ + method: "POST", + uberPath, + body: payload, + wrapperRoute: "/api/v1/uber/delivery-store/stores/:storeId/prep-time", + authMode: "app", + scopes: AUTH_SCOPES.STORE_WRITE + }); +} + +async function deliveryUpdateFulfillmentConfig({ storeId, payload }) { + const uberPath = interpolatePath(uberEndpoints.deliveryStore.updateFulfillmentConfig, { storeId }); + return callUberApi({ + method: "POST", + uberPath, + body: payload, + wrapperRoute: "/api/v1/uber/delivery-store/stores/:storeId/fulfillment-configuration", + authMode: "app", + scopes: AUTH_SCOPES.BYOC_FULFILLMENT_CONFIG + }); +} + module.exports = { genericProxy, menuUpsert, @@ -410,5 +492,12 @@ module.exports = { createPosData, getPosData, patchPosData, - deletePosData + deletePosData, + deliveryListStores, + deliveryGetStoreDetails, + deliveryUpdateStore, + deliveryGetStoreStatus, + deliverySetStoreStatus, + deliveryUpdatePrepTime, + deliveryUpdateFulfillmentConfig }; diff --git a/src/routes/proxy.routes.js b/src/routes/proxy.routes.js index a09454f..2ff822e 100644 --- a/src/routes/proxy.routes.js +++ b/src/routes/proxy.routes.js @@ -352,4 +352,133 @@ router.get("/uber/stores/:storeId/pos-data", asyncHandler(controller.getPosData) router.patch("/uber/stores/:storeId/pos-data", asyncHandler(controller.patchPosData)); router.delete("/uber/stores/:storeId/pos-data", asyncHandler(controller.deletePosData)); +/** + * @openapi + * /api/v1/uber/delivery-store/stores: + * get: + * summary: Store API 1.0.0 - Get stores (/v1/delivery/stores) + * tags: + * - Uber Delivery Store v1 + * responses: + * 200: + * description: Stores retrieved + */ +router.get("/uber/delivery-store/stores", asyncHandler(controller.deliveryListStores)); + +/** + * @openapi + * /api/v1/uber/delivery-store/stores/{storeId}: + * get: + * summary: Store API 1.0.0 - Get store details + * tags: + * - Uber Delivery Store v1 + * parameters: + * - in: path + * name: storeId + * required: true + * schema: + * type: string + * responses: + * 200: + * description: Store details retrieved + * post: + * summary: Store API 1.0.0 - Update store information + * tags: + * - Uber Delivery Store v1 + * parameters: + * - in: path + * name: storeId + * required: true + * schema: + * type: string + * responses: + * 200: + * description: Store information updated + */ +router.get("/uber/delivery-store/stores/:storeId", asyncHandler(controller.deliveryGetStoreDetails)); +router.post("/uber/delivery-store/stores/:storeId", asyncHandler(controller.deliveryUpdateStore)); + +/** + * @openapi + * /api/v1/uber/delivery-store/stores/{storeId}/status: + * get: + * summary: Store API 1.0.0 - Retrieve store status + * tags: + * - Uber Delivery Store v1 + * parameters: + * - in: path + * name: storeId + * required: true + * schema: + * type: string + * responses: + * 200: + * description: Store status retrieved + * post: + * summary: Store API 1.0.0 - Set store status + * tags: + * - Uber Delivery Store v1 + * parameters: + * - in: path + * name: storeId + * required: true + * schema: + * type: string + * responses: + * 200: + * description: Store status updated + */ +router.get( + "/uber/delivery-store/stores/:storeId/status", + asyncHandler(controller.deliveryGetStoreStatus) +); +router.post( + "/uber/delivery-store/stores/:storeId/status", + asyncHandler(controller.deliverySetStoreStatus) +); + +/** + * @openapi + * /api/v1/uber/delivery-store/stores/{storeId}/prep-time: + * post: + * summary: Store API 1.0.0 - Update prep time + * tags: + * - Uber Delivery Store v1 + * parameters: + * - in: path + * name: storeId + * required: true + * schema: + * type: string + * responses: + * 200: + * description: Prep time updated + */ +router.post( + "/uber/delivery-store/stores/:storeId/prep-time", + asyncHandler(controller.deliveryUpdatePrepTime) +); + +/** + * @openapi + * /api/v1/uber/delivery-store/stores/{storeId}/fulfillment-configuration: + * post: + * summary: Store API 1.0.0 - Update BYOC fulfillment configuration + * tags: + * - Uber Delivery Store v1 + * parameters: + * - in: path + * name: storeId + * required: true + * schema: + * type: string + * responses: + * 200: + * description: Fulfillment configuration updated + */ +router.post( + "/uber/delivery-store/stores/:storeId/fulfillment-configuration", + asyncHandler(controller.deliveryUpdateFulfillmentConfig) +); + module.exports = router;