feat: add go-live readiness metric for pilot launch gating
This commit is contained in:
parent
7fe725b00e
commit
1ac6899898
26
docs/developer-portal/11-going-live-audit.md
Normal file
26
docs/developer-portal/11-going-live-audit.md
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
# 11 Going Live Audit
|
||||||
|
|
||||||
|
Source checked: Uber Eats "Going Live" section shared by you.
|
||||||
|
|
||||||
|
## Implemented Now
|
||||||
|
|
||||||
|
- Go-live readiness metric endpoint for pilot gating:
|
||||||
|
- `GET /api/v1/metrics/go-live-readiness`
|
||||||
|
- computes 3-day injection success and evaluates against configurable threshold (default 98%)
|
||||||
|
- Existing production readiness controls already present:
|
||||||
|
- webhook security (signature + optional basic auth)
|
||||||
|
- OAuth domain pairing checks
|
||||||
|
- injection success monitoring endpoint
|
||||||
|
|
||||||
|
## Existing Before
|
||||||
|
|
||||||
|
- Menu upload and POS integration activation APIs
|
||||||
|
- Provisioning and de-provisioning flow endpoints
|
||||||
|
- Webhook ingestion and order action APIs
|
||||||
|
|
||||||
|
## Pending (Operational / Process)
|
||||||
|
|
||||||
|
- Scheduling formal joint verification run with Uber support team
|
||||||
|
- Production app creation and scope whitelisting workflow in dashboard
|
||||||
|
- Pilot launch operational communication workflow outside API service
|
||||||
|
|
||||||
@ -7,3 +7,13 @@ Go-live readiness:
|
|||||||
- Alerting and log monitoring enabled
|
- Alerting and log monitoring enabled
|
||||||
- Token refresh and failure runbooks ready
|
- Token refresh and failure runbooks ready
|
||||||
- Injection success rate monitoring enabled (`target >= 99%`)
|
- Injection success rate monitoring enabled (`target >= 99%`)
|
||||||
|
- Pilot launch metric check enabled (`>= 98%` over 3 days):
|
||||||
|
- `GET /api/v1/metrics/go-live-readiness`
|
||||||
|
|
||||||
|
Pilot launch workflow:
|
||||||
|
|
||||||
|
1. Provision pilot store to production app.
|
||||||
|
2. Upload menu (`PUT /api/v1/uber/menu/replace`).
|
||||||
|
3. Enable POS integration (`PATCH /api/v1/uber/stores/{storeId}/pos-data` with `integration_enabled=true`).
|
||||||
|
4. Monitor injection success and order response SLA.
|
||||||
|
5. Continue launches after pilot stability target is met.
|
||||||
|
|||||||
@ -246,6 +246,37 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"/api/v1/metrics/go-live-readiness": {
|
||||||
|
"get": {
|
||||||
|
"summary": "Check pilot go-live readiness based on 3-day injection success threshold",
|
||||||
|
"tags": [
|
||||||
|
"Metrics"
|
||||||
|
],
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "merchantId",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"in": "query",
|
||||||
|
"name": "thresholdPercent",
|
||||||
|
"required": false,
|
||||||
|
"schema": {
|
||||||
|
"type": "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "Go-live readiness status"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"/api/v1/uber/request": {
|
"/api/v1/uber/request": {
|
||||||
"post": {
|
"post": {
|
||||||
"summary": "Generic Uber passthrough for any Uber endpoint",
|
"summary": "Generic Uber passthrough for any Uber endpoint",
|
||||||
|
|||||||
@ -549,6 +549,36 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Go Live Readiness Metric",
|
||||||
|
"request": {
|
||||||
|
"method": "GET",
|
||||||
|
"header": [
|
||||||
|
{
|
||||||
|
"key": "x-api-key",
|
||||||
|
"value": "{{apiKey}}"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"url": {
|
||||||
|
"raw": "{{baseUrl}}/api/v1/metrics/go-live-readiness?merchantId={{merchantId}}",
|
||||||
|
"host": [
|
||||||
|
"{{baseUrl}}"
|
||||||
|
],
|
||||||
|
"path": [
|
||||||
|
"api",
|
||||||
|
"v1",
|
||||||
|
"metrics",
|
||||||
|
"go-live-readiness"
|
||||||
|
],
|
||||||
|
"query": [
|
||||||
|
{
|
||||||
|
"key": "merchantId",
|
||||||
|
"value": "{{merchantId}}"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Fetch Reporting CSV",
|
"name": "Fetch Reporting CSV",
|
||||||
"request": {
|
"request": {
|
||||||
|
|||||||
@ -63,7 +63,38 @@ async function getOrderResponseSla(req, res) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getGoLiveReadiness(req, res) {
|
||||||
|
const schema = z.object({
|
||||||
|
merchantId: z.string().optional(),
|
||||||
|
thresholdPercent: z.coerce.number().optional()
|
||||||
|
});
|
||||||
|
|
||||||
|
const query = schema.parse(req.query);
|
||||||
|
const sinceIso = toSinceIso("3");
|
||||||
|
const stats = apiLogRepository.getInjectionSuccessStats({
|
||||||
|
merchantId: query.merchantId,
|
||||||
|
sinceIso
|
||||||
|
});
|
||||||
|
const threshold = query.thresholdPercent ?? 98;
|
||||||
|
const hasData = stats.total > 0;
|
||||||
|
const eligible = hasData && stats.successRate >= threshold;
|
||||||
|
|
||||||
|
return res.json({
|
||||||
|
success: true,
|
||||||
|
data: {
|
||||||
|
metric: "go_live_readiness",
|
||||||
|
merchantId: query.merchantId || "all",
|
||||||
|
pilotWindowDays: 3,
|
||||||
|
requiredInjectionSuccessPercent: threshold,
|
||||||
|
hasData,
|
||||||
|
eligible,
|
||||||
|
...stats
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getInjectionSuccess,
|
getInjectionSuccess,
|
||||||
getOrderResponseSla
|
getOrderResponseSla,
|
||||||
|
getGoLiveReadiness
|
||||||
};
|
};
|
||||||
|
|||||||
@ -2,7 +2,8 @@ const express = require("express");
|
|||||||
const asyncHandler = require("../middleware/asyncHandler");
|
const asyncHandler = require("../middleware/asyncHandler");
|
||||||
const {
|
const {
|
||||||
getInjectionSuccess,
|
getInjectionSuccess,
|
||||||
getOrderResponseSla
|
getOrderResponseSla,
|
||||||
|
getGoLiveReadiness
|
||||||
} = require("../modules/metrics/metrics.controller");
|
} = require("../modules/metrics/metrics.controller");
|
||||||
|
|
||||||
const router = express.Router();
|
const router = express.Router();
|
||||||
@ -55,4 +56,28 @@ router.get("/metrics/injection-success", asyncHandler(getInjectionSuccess));
|
|||||||
*/
|
*/
|
||||||
router.get("/metrics/order-response-sla", asyncHandler(getOrderResponseSla));
|
router.get("/metrics/order-response-sla", asyncHandler(getOrderResponseSla));
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @openapi
|
||||||
|
* /api/v1/metrics/go-live-readiness:
|
||||||
|
* get:
|
||||||
|
* summary: Check pilot go-live readiness based on 3-day injection success threshold
|
||||||
|
* tags:
|
||||||
|
* - Metrics
|
||||||
|
* parameters:
|
||||||
|
* - in: query
|
||||||
|
* name: merchantId
|
||||||
|
* required: false
|
||||||
|
* schema:
|
||||||
|
* type: string
|
||||||
|
* - in: query
|
||||||
|
* name: thresholdPercent
|
||||||
|
* required: false
|
||||||
|
* schema:
|
||||||
|
* type: number
|
||||||
|
* responses:
|
||||||
|
* 200:
|
||||||
|
* description: Go-live readiness status
|
||||||
|
*/
|
||||||
|
router.get("/metrics/go-live-readiness", asyncHandler(getGoLiveReadiness));
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user