feat: align integration configuration endpoints with api suite v1.0.0
This commit is contained in:
parent
fe524a719d
commit
54565d9b6d
@ -9,6 +9,8 @@ Source checked: Uber Eats "Integration Configuration Flows" section shared by yo
|
||||
- Uses merchant token (`authorization_code` / `eats.pos_provisioning`)
|
||||
- Store activation via POS data:
|
||||
- `POST /api/v1/uber/stores/{storeId}/pos-data`
|
||||
- Retrieve integration configuration:
|
||||
- `GET /api/v1/uber/stores/{storeId}/pos-data`
|
||||
- Store integration update/deactivation:
|
||||
- `PATCH /api/v1/uber/stores/{storeId}/pos-data`
|
||||
- Store de-provision:
|
||||
@ -26,6 +28,5 @@ Source checked: Uber Eats "Integration Configuration Flows" section shared by yo
|
||||
## Pending
|
||||
|
||||
- Strong store mapping workflow (location-data assisted matching UI flow)
|
||||
- Typed POS data schema once exact request fields are finalized from endpoint reference
|
||||
- Strict nested schema validation for deeper webhook config object variants
|
||||
- Automated post-provisioning follow-up actions (e.g., mandatory menu upload jobs)
|
||||
|
||||
|
||||
@ -0,0 +1,36 @@
|
||||
# 03 Integration Configuration Suite 1.0.0 Audit
|
||||
|
||||
Source checked: "Uber Eats Integration Activation & Configuration API Suite (1.0.0)" shared by you.
|
||||
|
||||
## Endpoint Coverage
|
||||
|
||||
- Activate Integration:
|
||||
- `POST /api/v1/uber/stores/{storeId}/pos-data`
|
||||
- Uses merchant OAuth token (`eats.pos_provisioning`) via `merchantId`
|
||||
- Update Integration Configuration:
|
||||
- `PATCH /api/v1/uber/stores/{storeId}/pos-data`
|
||||
- Uses app token with `eats.store` scope
|
||||
- Retrieve Integration Configuration:
|
||||
- `GET /api/v1/uber/stores/{storeId}/pos-data`
|
||||
- Uses app token with `eats.store` scope
|
||||
- Remove Integration Configuration:
|
||||
- `DELETE /api/v1/uber/stores/{storeId}/pos-data`
|
||||
- Uses app token with `eats.store` scope
|
||||
|
||||
## Schema Alignment
|
||||
|
||||
- Added typed request schema fields for `pos_data`:
|
||||
- `allowed_customer_requests`
|
||||
- `integrator_brand_id`
|
||||
- `integrator_store_id`
|
||||
- `is_order_manager`
|
||||
- `merchant_store_id`
|
||||
- `require_manual_acceptance`
|
||||
- `store_configuration_data`
|
||||
- `webhooks_config`
|
||||
- `integration_enabled` (PATCH)
|
||||
|
||||
## Pending
|
||||
|
||||
- Add stricter nested object typing for all `webhooks_config` variants when final examples are shared.
|
||||
|
||||
@ -629,6 +629,27 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"get": {
|
||||
"summary": "Retrieve integration configuration for selected store (GET /pos_data)",
|
||||
"tags": [
|
||||
"Uber Provisioning"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "storeId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Store integration configuration retrieved"
|
||||
}
|
||||
}
|
||||
},
|
||||
"patch": {
|
||||
"summary": "Update integration settings for selected store (PATCH /pos_data)",
|
||||
"tags": [
|
||||
|
||||
@ -662,7 +662,7 @@
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"merchantId\": \"{{merchantId}}\",\n \"posData\": {\n \"partner_store_id\": \"POS_STORE_001\",\n \"integration_enabled\": true,\n \"store_configuration_data\": {}\n }\n}"
|
||||
"raw": "{\n \"merchantId\": \"{{merchantId}}\",\n \"posData\": {\n \"allowed_customer_requests\": {\n \"allow_single_use_items_requests\": false,\n \"allow_special_instruction_requests\": false\n },\n \"integrator_brand_id\": \"app-brand-1jj9th32\",\n \"integrator_store_id\": \"app-store-001\",\n \"is_order_manager\": true,\n \"merchant_store_id\": \"UberStore1\",\n \"require_manual_acceptance\": false,\n \"store_configuration_data\": \"v1-config\",\n \"webhooks_config\": {\n \"webhooks_version\": \"1.0.0\"\n }\n }\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores/{{storeId}}/pos-data",
|
||||
@ -680,6 +680,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Get POS Data",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "x-api-key",
|
||||
"value": "{{apiKey}}"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores/{{storeId}}/pos-data",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"v1",
|
||||
"uber",
|
||||
"stores",
|
||||
"{{storeId}}",
|
||||
"pos-data"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Patch POS Data (Enable/Disable)",
|
||||
"request": {
|
||||
@ -696,7 +722,7 @@
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"merchantId\": \"{{merchantId}}\",\n \"posData\": {\n \"integration_enabled\": false\n }\n}"
|
||||
"raw": "{\n \"posData\": {\n \"integration_enabled\": false,\n \"require_manual_acceptance\": false\n }\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores/{{storeId}}/pos-data",
|
||||
@ -722,16 +748,8 @@
|
||||
{
|
||||
"key": "x-api-key",
|
||||
"value": "{{apiKey}}"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"merchantId\": \"{{merchantId}}\"\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores/{{storeId}}/pos-data",
|
||||
"host": [
|
||||
|
||||
@ -239,9 +239,37 @@ async function setHolidayHours(req, res) {
|
||||
}
|
||||
|
||||
async function createPosData(req, res) {
|
||||
const allowedCustomerRequestsSchema = z
|
||||
.object({
|
||||
allow_single_use_items_requests: z.boolean().optional(),
|
||||
allow_special_instruction_requests: z.boolean().optional()
|
||||
})
|
||||
.optional();
|
||||
|
||||
const webhooksConfigSchema = z
|
||||
.object({
|
||||
order_release_webhooks: z.record(z.string(), z.any()).optional(),
|
||||
schedule_order_webhooks: z.record(z.string(), z.any()).optional(),
|
||||
delivery_status_webhooks: z.record(z.string(), z.any()).optional(),
|
||||
webhooks_version: z.string().optional()
|
||||
})
|
||||
.optional();
|
||||
|
||||
const posDataSchema = z.object({
|
||||
allowed_customer_requests: allowedCustomerRequestsSchema,
|
||||
integrator_brand_id: z.string().optional(),
|
||||
integrator_store_id: z.string().optional(),
|
||||
is_order_manager: z.boolean().optional(),
|
||||
merchant_store_id: z.string().optional(),
|
||||
require_manual_acceptance: z.boolean().optional(),
|
||||
store_configuration_data: z.string().optional(),
|
||||
webhooks_config: webhooksConfigSchema,
|
||||
integration_enabled: z.boolean().optional()
|
||||
});
|
||||
|
||||
const schema = z.object({
|
||||
merchantId: z.string().min(1),
|
||||
posData: z.any()
|
||||
posData: posDataSchema
|
||||
});
|
||||
const payload = schema.parse(req.body);
|
||||
const data = await proxyService.createPosData({
|
||||
@ -252,14 +280,51 @@ async function createPosData(req, res) {
|
||||
return res.json({ success: true, data });
|
||||
}
|
||||
|
||||
async function getPosData(req, res) {
|
||||
const data = await proxyService.getPosData({
|
||||
storeId: req.params.storeId
|
||||
});
|
||||
return res.json({ success: true, data });
|
||||
}
|
||||
|
||||
async function patchPosData(req, res) {
|
||||
const allowedCustomerRequestsSchema = z
|
||||
.object({
|
||||
allow_single_use_items_requests: z.boolean().optional(),
|
||||
allow_special_instruction_requests: z.boolean().optional()
|
||||
})
|
||||
.optional();
|
||||
|
||||
const webhooksConfigSchema = z
|
||||
.object({
|
||||
order_release_webhooks: z.record(z.string(), z.any()).optional(),
|
||||
schedule_order_webhooks: z.record(z.string(), z.any()).optional(),
|
||||
delivery_status_webhooks: z.record(z.string(), z.any()).optional(),
|
||||
webhooks_version: z.string().optional()
|
||||
})
|
||||
.optional();
|
||||
|
||||
const posDataSchema = z
|
||||
.object({
|
||||
allowed_customer_requests: allowedCustomerRequestsSchema,
|
||||
integrator_brand_id: z.string().optional(),
|
||||
integrator_store_id: z.string().optional(),
|
||||
is_order_manager: z.boolean().optional(),
|
||||
merchant_store_id: z.string().optional(),
|
||||
require_manual_acceptance: z.boolean().optional(),
|
||||
store_configuration_data: z.string().optional(),
|
||||
webhooks_config: webhooksConfigSchema,
|
||||
integration_enabled: z.boolean().optional()
|
||||
})
|
||||
.refine((value) => Object.keys(value).length > 0, {
|
||||
message: "posData must include at least one updatable field"
|
||||
});
|
||||
|
||||
const schema = z.object({
|
||||
merchantId: z.string().min(1),
|
||||
posData: z.any()
|
||||
posData: posDataSchema
|
||||
});
|
||||
const payload = schema.parse(req.body);
|
||||
const data = await proxyService.patchPosData({
|
||||
merchantId: payload.merchantId,
|
||||
storeId: req.params.storeId,
|
||||
payload: payload.posData
|
||||
});
|
||||
@ -267,12 +332,7 @@ async function patchPosData(req, res) {
|
||||
}
|
||||
|
||||
async function deletePosData(req, res) {
|
||||
const schema = z.object({
|
||||
merchantId: z.string().min(1)
|
||||
});
|
||||
const payload = schema.parse(req.body);
|
||||
const data = await proxyService.deletePosData({
|
||||
merchantId: payload.merchantId,
|
||||
storeId: req.params.storeId
|
||||
});
|
||||
return res.json({ success: true, data });
|
||||
@ -298,6 +358,7 @@ module.exports = {
|
||||
getHolidayHours,
|
||||
setHolidayHours,
|
||||
createPosData,
|
||||
getPosData,
|
||||
patchPosData,
|
||||
deletePosData
|
||||
};
|
||||
|
||||
@ -354,28 +354,37 @@ async function createPosData({ merchantId, storeId, payload }) {
|
||||
});
|
||||
}
|
||||
|
||||
async function patchPosData({ merchantId, storeId, payload }) {
|
||||
async function getPosData({ storeId }) {
|
||||
const uberPath = interpolatePath(uberEndpoints.stores.posData, { storeId });
|
||||
return callUberApi({
|
||||
method: "GET",
|
||||
uberPath,
|
||||
wrapperRoute: "/api/v1/uber/stores/:storeId/pos-data",
|
||||
authMode: "app",
|
||||
scopes: AUTH_SCOPES.STORE
|
||||
});
|
||||
}
|
||||
|
||||
async function patchPosData({ storeId, payload }) {
|
||||
const uberPath = interpolatePath(uberEndpoints.stores.posData, { storeId });
|
||||
return callUberApi({
|
||||
merchantId,
|
||||
method: "PATCH",
|
||||
uberPath,
|
||||
body: payload,
|
||||
wrapperRoute: "/api/v1/uber/stores/:storeId/pos-data",
|
||||
authMode: "merchant",
|
||||
scopes: AUTH_SCOPES.POS_PROVISIONING
|
||||
authMode: "app",
|
||||
scopes: AUTH_SCOPES.STORE
|
||||
});
|
||||
}
|
||||
|
||||
async function deletePosData({ merchantId, storeId }) {
|
||||
async function deletePosData({ storeId }) {
|
||||
const uberPath = interpolatePath(uberEndpoints.stores.posData, { storeId });
|
||||
return callUberApi({
|
||||
merchantId,
|
||||
method: "DELETE",
|
||||
uberPath,
|
||||
wrapperRoute: "/api/v1/uber/stores/:storeId/pos-data",
|
||||
authMode: "merchant",
|
||||
scopes: AUTH_SCOPES.POS_PROVISIONING
|
||||
authMode: "app",
|
||||
scopes: AUTH_SCOPES.STORE
|
||||
});
|
||||
}
|
||||
|
||||
@ -399,6 +408,7 @@ module.exports = {
|
||||
getHolidayHours,
|
||||
setHolidayHours,
|
||||
createPosData,
|
||||
getPosData,
|
||||
patchPosData,
|
||||
deletePosData
|
||||
};
|
||||
|
||||
@ -307,6 +307,19 @@ router.put("/uber/stores/hours", asyncHandler(controller.updateHours));
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Store provisioned
|
||||
* get:
|
||||
* summary: Retrieve integration configuration for selected store (GET /pos_data)
|
||||
* tags:
|
||||
* - Uber Provisioning
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: storeId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Store integration configuration retrieved
|
||||
* patch:
|
||||
* summary: Update integration settings for selected store (PATCH /pos_data)
|
||||
* tags:
|
||||
@ -335,6 +348,7 @@ router.put("/uber/stores/hours", asyncHandler(controller.updateHours));
|
||||
* description: Store integration removed
|
||||
*/
|
||||
router.post("/uber/stores/:storeId/pos-data", asyncHandler(controller.createPosData));
|
||||
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));
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user