feat: add typed store integration endpoints for status and holiday hours
This commit is contained in:
parent
8f58a64bc8
commit
1474781c08
27
docs/developer-portal/04-store-integration-audit.md
Normal file
27
docs/developer-portal/04-store-integration-audit.md
Normal file
@ -0,0 +1,27 @@
|
||||
# 04 Store Integration Audit
|
||||
|
||||
Source checked: Uber Eats "Store Integration" section shared by you.
|
||||
|
||||
## Implemented Now
|
||||
|
||||
- Retrieve all stores:
|
||||
- `GET /api/v1/uber/stores`
|
||||
- Retrieve store by ID:
|
||||
- `GET /api/v1/uber/stores/{storeId}`
|
||||
- Retrieve and set online/offline store status:
|
||||
- `GET /api/v1/uber/stores/{storeId}/status`
|
||||
- `POST /api/v1/uber/stores/{storeId}/status`
|
||||
- Retrieve and set date-specific holiday hours:
|
||||
- `GET /api/v1/uber/stores/{storeId}/holiday-hours`
|
||||
- `POST /api/v1/uber/stores/{storeId}/holiday-hours`
|
||||
|
||||
## Existing Before
|
||||
|
||||
- Store hours update route (`PUT /api/v1/uber/stores/hours`)
|
||||
- Provisioning routes and store discovery via merchant auth flow
|
||||
|
||||
## Pending
|
||||
|
||||
- Exact status payload schema hardening once official request examples are finalized
|
||||
- Extended store settings endpoints not yet included in shared doc dump
|
||||
|
||||
@ -7,3 +7,11 @@ Uber Eats store-focused integrations:
|
||||
- Holiday/special hours
|
||||
- Operational metadata sync
|
||||
|
||||
Typed routes available:
|
||||
|
||||
- `GET /api/v1/uber/stores`
|
||||
- `GET /api/v1/uber/stores/{storeId}`
|
||||
- `GET /api/v1/uber/stores/{storeId}/status`
|
||||
- `POST /api/v1/uber/stores/{storeId}/status`
|
||||
- `GET /api/v1/uber/stores/{storeId}/holiday-hours`
|
||||
- `POST /api/v1/uber/stores/{storeId}/holiday-hours`
|
||||
|
||||
@ -280,6 +280,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/uber/stores": {
|
||||
"get": {
|
||||
"summary": "Retrieve all stores provisioned to developer account",
|
||||
"tags": [
|
||||
"Uber Stores"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Stores retrieved"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/uber/stores/provisionable": {
|
||||
"get": {
|
||||
"summary": "Retrieve stores associated with merchant OAuth token",
|
||||
@ -303,6 +316,117 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/uber/stores/{storeId}": {
|
||||
"get": {
|
||||
"summary": "Retrieve store details by store ID",
|
||||
"tags": [
|
||||
"Uber Stores"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "storeId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Store retrieved"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/uber/stores/{storeId}/status": {
|
||||
"get": {
|
||||
"summary": "Retrieve store online/offline status",
|
||||
"tags": [
|
||||
"Uber Stores"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "storeId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Store status retrieved"
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"summary": "Set store online/offline status",
|
||||
"tags": [
|
||||
"Uber Stores"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "storeId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Store status updated"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/uber/stores/{storeId}/holiday-hours": {
|
||||
"get": {
|
||||
"summary": "Retrieve store holiday hours",
|
||||
"tags": [
|
||||
"Uber Stores"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "storeId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Holiday hours retrieved"
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"summary": "Set store holiday hours",
|
||||
"tags": [
|
||||
"Uber Stores"
|
||||
],
|
||||
"parameters": [
|
||||
{
|
||||
"in": "path",
|
||||
"name": "storeId",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Holiday hours updated"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/uber/orders/{orderId}/action": {
|
||||
"post": {
|
||||
"summary": "Trigger order action (accept, deny, ready, cancel)",
|
||||
|
||||
@ -230,6 +230,175 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "List Stores (App)",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "x-api-key",
|
||||
"value": "{{apiKey}}"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"v1",
|
||||
"uber",
|
||||
"stores"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Get Store By ID",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "x-api-key",
|
||||
"value": "{{apiKey}}"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores/{{storeId}}",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"v1",
|
||||
"uber",
|
||||
"stores",
|
||||
"{{storeId}}"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Get Store Status",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "x-api-key",
|
||||
"value": "{{apiKey}}"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores/{{storeId}}/status",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"v1",
|
||||
"uber",
|
||||
"stores",
|
||||
"{{storeId}}",
|
||||
"status"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Set Store 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 \"reason\": \"maintenance\"\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores/{{storeId}}/status",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"v1",
|
||||
"uber",
|
||||
"stores",
|
||||
"{{storeId}}",
|
||||
"status"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Get Holiday Hours",
|
||||
"request": {
|
||||
"method": "GET",
|
||||
"header": [
|
||||
{
|
||||
"key": "x-api-key",
|
||||
"value": "{{apiKey}}"
|
||||
}
|
||||
],
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores/{{storeId}}/holiday-hours",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"v1",
|
||||
"uber",
|
||||
"stores",
|
||||
"{{storeId}}",
|
||||
"holiday-hours"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Set Holiday Hours",
|
||||
"request": {
|
||||
"method": "POST",
|
||||
"header": [
|
||||
{
|
||||
"key": "x-api-key",
|
||||
"value": "{{apiKey}}"
|
||||
},
|
||||
{
|
||||
"key": "Content-Type",
|
||||
"value": "application/json"
|
||||
}
|
||||
],
|
||||
"body": {
|
||||
"mode": "raw",
|
||||
"raw": "{\n \"holiday_hours\": []\n}"
|
||||
},
|
||||
"url": {
|
||||
"raw": "{{baseUrl}}/api/v1/uber/stores/{{storeId}}/holiday-hours",
|
||||
"host": [
|
||||
"{{baseUrl}}"
|
||||
],
|
||||
"path": [
|
||||
"api",
|
||||
"v1",
|
||||
"uber",
|
||||
"stores",
|
||||
"{{storeId}}",
|
||||
"holiday-hours"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "Create POS Data (Provision)",
|
||||
"request": {
|
||||
|
||||
@ -14,6 +14,8 @@ module.exports = {
|
||||
stores: {
|
||||
list: "/v1/eats/stores",
|
||||
getById: "/v1/eats/stores/{storeId}",
|
||||
status: "/v1/eats/stores/{storeId}/status",
|
||||
holidayHours: "/v1/eats/stores/{storeId}/holiday_hours",
|
||||
updateHours: "/v1/eats/stores/{storeId}/hours",
|
||||
inventory: "/v1/eats/stores/{storeId}/inventory",
|
||||
posData: "/v1/eats/stores/{storeId}/pos_data"
|
||||
|
||||
@ -115,6 +115,55 @@ async function listProvisionableStores(req, res) {
|
||||
return res.json({ success: true, data });
|
||||
}
|
||||
|
||||
async function listStores(req, res) {
|
||||
const data = await proxyService.listStores({
|
||||
query: req.query
|
||||
});
|
||||
return res.json({ success: true, data });
|
||||
}
|
||||
|
||||
async function getStoreById(req, res) {
|
||||
const data = await proxyService.getStoreById({
|
||||
storeId: req.params.storeId
|
||||
});
|
||||
return res.json({ success: true, data });
|
||||
}
|
||||
|
||||
async function getStoreStatus(req, res) {
|
||||
const data = await proxyService.getStoreStatus({
|
||||
storeId: req.params.storeId
|
||||
});
|
||||
return res.json({ success: true, data });
|
||||
}
|
||||
|
||||
async function setStoreStatus(req, res) {
|
||||
const schema = z.object({
|
||||
status: z.string().optional(),
|
||||
reason: z.string().optional()
|
||||
});
|
||||
const payload = schema.partial().parse(req.body || {});
|
||||
const data = await proxyService.setStoreStatus({
|
||||
storeId: req.params.storeId,
|
||||
payload
|
||||
});
|
||||
return res.json({ success: true, data });
|
||||
}
|
||||
|
||||
async function getHolidayHours(req, res) {
|
||||
const data = await proxyService.getHolidayHours({
|
||||
storeId: req.params.storeId
|
||||
});
|
||||
return res.json({ success: true, data });
|
||||
}
|
||||
|
||||
async function setHolidayHours(req, res) {
|
||||
const data = await proxyService.setHolidayHours({
|
||||
storeId: req.params.storeId,
|
||||
payload: req.body || {}
|
||||
});
|
||||
return res.json({ success: true, data });
|
||||
}
|
||||
|
||||
async function createPosData(req, res) {
|
||||
const schema = z.object({
|
||||
merchantId: z.string().min(1),
|
||||
@ -164,6 +213,12 @@ module.exports = {
|
||||
orderAction,
|
||||
updateHours,
|
||||
listProvisionableStores,
|
||||
listStores,
|
||||
getStoreById,
|
||||
getStoreStatus,
|
||||
setStoreStatus,
|
||||
getHolidayHours,
|
||||
setHolidayHours,
|
||||
createPosData,
|
||||
patchPosData,
|
||||
deletePosData
|
||||
|
||||
@ -215,6 +215,74 @@ async function listProvisionableStores({ merchantId, query }) {
|
||||
});
|
||||
}
|
||||
|
||||
async function listStores({ query }) {
|
||||
return callUberApi({
|
||||
method: "GET",
|
||||
uberPath: uberEndpoints.stores.list,
|
||||
query,
|
||||
wrapperRoute: "/api/v1/uber/stores",
|
||||
authMode: "app",
|
||||
scopes: AUTH_SCOPES.STORE
|
||||
});
|
||||
}
|
||||
|
||||
async function getStoreById({ storeId }) {
|
||||
const uberPath = interpolatePath(uberEndpoints.stores.getById, { storeId });
|
||||
return callUberApi({
|
||||
method: "GET",
|
||||
uberPath,
|
||||
wrapperRoute: "/api/v1/uber/stores/:storeId",
|
||||
authMode: "app",
|
||||
scopes: AUTH_SCOPES.STORE
|
||||
});
|
||||
}
|
||||
|
||||
async function getStoreStatus({ storeId }) {
|
||||
const uberPath = interpolatePath(uberEndpoints.stores.status, { storeId });
|
||||
return callUberApi({
|
||||
method: "GET",
|
||||
uberPath,
|
||||
wrapperRoute: "/api/v1/uber/stores/:storeId/status",
|
||||
authMode: "app",
|
||||
scopes: AUTH_SCOPES.STORE
|
||||
});
|
||||
}
|
||||
|
||||
async function setStoreStatus({ storeId, payload }) {
|
||||
const uberPath = interpolatePath(uberEndpoints.stores.status, { storeId });
|
||||
return callUberApi({
|
||||
method: "POST",
|
||||
uberPath,
|
||||
body: payload,
|
||||
wrapperRoute: "/api/v1/uber/stores/:storeId/status",
|
||||
authMode: "app",
|
||||
scopes: AUTH_SCOPES.STORE_STATUS_WRITE
|
||||
});
|
||||
}
|
||||
|
||||
async function getHolidayHours({ storeId }) {
|
||||
const uberPath = interpolatePath(uberEndpoints.stores.holidayHours, { storeId });
|
||||
return callUberApi({
|
||||
method: "GET",
|
||||
uberPath,
|
||||
wrapperRoute: "/api/v1/uber/stores/:storeId/holiday-hours",
|
||||
authMode: "app",
|
||||
scopes: AUTH_SCOPES.STORE
|
||||
});
|
||||
}
|
||||
|
||||
async function setHolidayHours({ storeId, payload }) {
|
||||
const uberPath = interpolatePath(uberEndpoints.stores.holidayHours, { storeId });
|
||||
return callUberApi({
|
||||
method: "POST",
|
||||
uberPath,
|
||||
body: payload,
|
||||
wrapperRoute: "/api/v1/uber/stores/:storeId/holiday-hours",
|
||||
authMode: "app",
|
||||
scopes: AUTH_SCOPES.STORE
|
||||
});
|
||||
}
|
||||
|
||||
async function createPosData({ merchantId, storeId, payload }) {
|
||||
const uberPath = interpolatePath(uberEndpoints.stores.posData, { storeId });
|
||||
return callUberApi({
|
||||
@ -262,6 +330,12 @@ module.exports = {
|
||||
orderAction,
|
||||
updateStoreHours,
|
||||
listProvisionableStores,
|
||||
listStores,
|
||||
getStoreById,
|
||||
getStoreStatus,
|
||||
setStoreStatus,
|
||||
getHolidayHours,
|
||||
setHolidayHours,
|
||||
createPosData,
|
||||
patchPosData,
|
||||
deletePosData
|
||||
|
||||
@ -69,6 +69,19 @@ router.get("/uber/menu", asyncHandler(controller.getMenu));
|
||||
*/
|
||||
router.get("/uber/orders", asyncHandler(controller.listOrders));
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* /api/v1/uber/stores:
|
||||
* get:
|
||||
* summary: Retrieve all stores provisioned to developer account
|
||||
* tags:
|
||||
* - Uber Stores
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Stores retrieved
|
||||
*/
|
||||
router.get("/uber/stores", asyncHandler(controller.listStores));
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* /api/v1/uber/stores/provisionable:
|
||||
@ -88,6 +101,91 @@ router.get("/uber/orders", asyncHandler(controller.listOrders));
|
||||
*/
|
||||
router.get("/uber/stores/provisionable", asyncHandler(controller.listProvisionableStores));
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* /api/v1/uber/stores/{storeId}:
|
||||
* get:
|
||||
* summary: Retrieve store details by store ID
|
||||
* tags:
|
||||
* - Uber Stores
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: storeId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Store retrieved
|
||||
*/
|
||||
router.get("/uber/stores/:storeId", asyncHandler(controller.getStoreById));
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* /api/v1/uber/stores/{storeId}/status:
|
||||
* get:
|
||||
* summary: Retrieve store online/offline status
|
||||
* tags:
|
||||
* - Uber Stores
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: storeId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Store status retrieved
|
||||
* post:
|
||||
* summary: Set store online/offline status
|
||||
* tags:
|
||||
* - Uber Stores
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: storeId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Store status updated
|
||||
*/
|
||||
router.get("/uber/stores/:storeId/status", asyncHandler(controller.getStoreStatus));
|
||||
router.post("/uber/stores/:storeId/status", asyncHandler(controller.setStoreStatus));
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* /api/v1/uber/stores/{storeId}/holiday-hours:
|
||||
* get:
|
||||
* summary: Retrieve store holiday hours
|
||||
* tags:
|
||||
* - Uber Stores
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: storeId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Holiday hours retrieved
|
||||
* post:
|
||||
* summary: Set store holiday hours
|
||||
* tags:
|
||||
* - Uber Stores
|
||||
* parameters:
|
||||
* - in: path
|
||||
* name: storeId
|
||||
* required: true
|
||||
* schema:
|
||||
* type: string
|
||||
* responses:
|
||||
* 200:
|
||||
* description: Holiday hours updated
|
||||
*/
|
||||
router.get("/uber/stores/:storeId/holiday-hours", asyncHandler(controller.getHolidayHours));
|
||||
router.post("/uber/stores/:storeId/holiday-hours", asyncHandler(controller.setHolidayHours));
|
||||
|
||||
/**
|
||||
* @openapi
|
||||
* /api/v1/uber/orders/{orderId}/action:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user