feat: add self-operated analytics and enforce Lastleg module boundaries
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Self-operated Analytics Internal Egress Authority
|
||||
version: 1.0.0
|
||||
paths:
|
||||
/internal/lastleg/self-operated-analytics/egress/authorize:
|
||||
post:
|
||||
operationId: authorizeSelfoperatedEgressAttempt
|
||||
summary: 一次性消费已持久预留的领星请求许可
|
||||
description: >-
|
||||
仅内部服务令牌。客户端已登记的 context 和 operation 必须完全匹配;
|
||||
requestHash 是 Integration 对 OMP 路径和有序业务 JSON 的摘要,首次消费绑定,
|
||||
后续完成必须完全匹配。同 attemptId 再次消费拒绝。allowedAttempts 固定 1,
|
||||
expiresAt 最多 30 秒且不超过验证根截止或人工独占窗口。OFF 默认拒绝,
|
||||
非 production 环境拒绝 BUSINESS。独占交接证明及接续预算由服务端配置核验。
|
||||
security: [{ internalServiceToken: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/AuthorizationRequest' }
|
||||
responses:
|
||||
'200':
|
||||
description: HTTP 200;许可 code=200,正常拒绝 code=B0001,data 为显式预算决策
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: { type: string }
|
||||
data:
|
||||
oneOf:
|
||||
- { $ref: '#/components/schemas/AttemptPermit' }
|
||||
- { $ref: '#/components/schemas/AuthorizationDenial' }
|
||||
'401': { description: 内部令牌无效 }
|
||||
'503': { description: 内部令牌未配置 }
|
||||
/internal/lastleg/self-operated-analytics/egress/complete:
|
||||
post:
|
||||
operationId: completeSelfoperatedEgressAttempt
|
||||
summary: 记录真实尝试次数和账号冷却
|
||||
description: >-
|
||||
回调 context、operation、requestHash 必须匹配已消费许可。actualHttpAttempts 仅 0 或 1;
|
||||
即使 0 也不退回预留,响应丢失同样保留保守消耗。重复已确认完成为幂等成功。
|
||||
429 对账号全部采集族持久冷却;验证根 DEAD、run FAILED、禁止自动续跑。
|
||||
未确认结果的许可到期后保守冷却,不使用换日、换仓、重试或重启清零预算。
|
||||
security: [{ internalServiceToken: [] }]
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema: { $ref: '#/components/schemas/CompletionRequest' }
|
||||
responses:
|
||||
'200':
|
||||
description: ApiResponse code 字符串 200,data 为布尔 true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: { type: string }
|
||||
data: { type: boolean, enum: [true] }
|
||||
'401': { description: 内部令牌无效 }
|
||||
components:
|
||||
securitySchemes:
|
||||
internalServiceToken: { type: apiKey, in: header, name: X-Internal-Service-Token }
|
||||
schemas:
|
||||
EgressContext:
|
||||
type: object
|
||||
required: [sourceAccount, executionPurpose, rootTaskId, sessionId, attemptId, exclusiveGrantId]
|
||||
properties:
|
||||
sourceAccount: { type: string, maxLength: 64 }
|
||||
executionPurpose: { type: string, enum: [VALIDATION, BUSINESS] }
|
||||
rootTaskId: { type: string, pattern: '^[0-9]+$' }
|
||||
sessionId: { type: string, maxLength: 128 }
|
||||
attemptId: { type: string, maxLength: 128 }
|
||||
exclusiveGrantId: { type: string, maxLength: 128 }
|
||||
Operation:
|
||||
type: string
|
||||
enum: [WAREHOUSES, OUTBOUND_QUERY, OUTBOUND_LOCATE, OUTBOUND_DETAIL, PRODUCT_INVENTORY]
|
||||
AuthorizationRequest:
|
||||
type: object
|
||||
required: [context, operation, requestHash]
|
||||
properties:
|
||||
context: { $ref: '#/components/schemas/EgressContext' }
|
||||
operation: { $ref: '#/components/schemas/Operation' }
|
||||
requestHash: { type: string, pattern: '^[a-f0-9]{64}$' }
|
||||
AuthorizationDenial:
|
||||
type: object
|
||||
required: [errorCode, sampleDone, waitUntil]
|
||||
properties:
|
||||
errorCode: { type: string, pattern: '^[A-Z][A-Z0-9_]{0,63}$' }
|
||||
sampleDone: { type: boolean }
|
||||
waitUntil: { type: string, format: date-time, nullable: true, description: UTC Instant 或显式 null }
|
||||
AttemptPermit:
|
||||
allOf:
|
||||
- { $ref: '#/components/schemas/AuthorizationRequest' }
|
||||
- type: object
|
||||
required: [allowedAttempts, expiresAt, exclusiveConfirmed, budgetConsumed]
|
||||
properties:
|
||||
allowedAttempts: { type: integer, enum: [1] }
|
||||
expiresAt: { type: string, format: date-time }
|
||||
exclusiveConfirmed: { type: boolean, enum: [true] }
|
||||
budgetConsumed: { type: boolean, enum: [true] }
|
||||
CompletionRequest:
|
||||
allOf:
|
||||
- { $ref: '#/components/schemas/AuthorizationRequest' }
|
||||
- type: object
|
||||
required: [actualHttpAttempts, accountPaused]
|
||||
properties:
|
||||
actualHttpAttempts: { type: integer, minimum: 0, maximum: 1 }
|
||||
errorCode: { type: string, nullable: true }
|
||||
upstreamStatus: { type: integer, nullable: true }
|
||||
sourceCode: { type: integer, nullable: true }
|
||||
accountPaused: { type: boolean }
|
||||
cooldownUntil: { type: string, format: date-time, nullable: true }
|
||||
Reference in New Issue
Block a user