Files
baiyue-firstleg/lastleg-service/src/main/resources/openapi/selfop-quantity-diagnostics-internal-v1.yaml
T

535 lines
15 KiB
YAML

openapi: 3.0.3
info:
title: Internal next-root bounded quantity diagnostics
version: 2.0.0
description: Explicit arm only; no automatic rearm. Bind next normal automatic historical OUTBOUND_QUERY root
within 6h. Sampling expires 4h after first LIST observedAt, never later than armedAt+10h. Lastleg session lock
is receiver acceptance. Source root creation may predate arm. LOCATE, manual/validation roots, current excluded
root and different bound root are rejected/ignored. At most 100 distinct LIST candidates total, 2000 retained
SKU rows across both sides, 2MiB canonical evidence plus promotion overhead. Pending-to-final never refunds
quota. First unknown or SKU mismatch persists INCONCLUSIVE and stops; any known inequality among list/forecast/actual
persists QUANTITY_DIFFERENCE and stops. Original side timestamps/attempts are immutable; exact replay returns
stored receipt even after termination, changed same-side evidence is rejected. Root termination drains only
accepted candidates via an explicit Integration FIFO boundary without extending expiry. Fewer than 100 complete
pairs is ROOT_ENDED_INSUFFICIENT; unpaired/lost tail is INCOMPLETE. Producer restart retains persisted candidates
but marks delivery uncertain. Every request/response is stream-bounded to 262144 bytes. Never exposed through
Gateway, never creates supplier requests or changes business facts.
paths:
/internal/lastleg/self-operated-analytics/quantity-diagnostics/arm:
post:
operationId: quantityDiagnosticArm
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Arm'
responses:
'200':
description: ApiResponse code 200. status data is null if no grant exists.
content:
application/json:
schema:
type: object
additionalProperties: false
properties:
code:
type: string
message:
type: string
nullable: true
data:
$ref: '#/components/schemas/View'
nullable: true
required:
- code
- data
'400':
description: Invalid scope, changed frozen evidence, invalid observation or disabled feature.
'401':
description: Missing or invalid internal service token.
'503':
description: Diagnostic admission, dedicated connection or storage unavailable; collection is unaffected.
/internal/lastleg/self-operated-analytics/quantity-diagnostics/status:
post:
operationId: quantityDiagnosticStatus
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Status'
responses:
'200':
description: ApiResponse code 200. status data is null if no grant exists.
content:
application/json:
schema:
type: object
additionalProperties: false
properties:
code:
type: string
message:
type: string
nullable: true
data:
$ref: '#/components/schemas/View'
nullable: true
required:
- code
- data
'400':
description: Invalid scope, changed frozen evidence, invalid observation or disabled feature.
'401':
description: Missing or invalid internal service token.
'503':
description: Diagnostic admission, dedicated connection or storage unavailable; collection is unaffected.
/internal/lastleg/self-operated-analytics/quantity-diagnostics/observe:
post:
operationId: quantityDiagnosticObserve
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Event'
responses:
'200':
description: ApiResponse code 200. status data is null if no grant exists.
content:
application/json:
schema:
type: object
additionalProperties: false
properties:
code:
type: string
message:
type: string
nullable: true
data:
$ref: '#/components/schemas/Receipt'
nullable: true
required:
- code
- data
'400':
description: Invalid scope, changed frozen evidence, invalid observation or disabled feature.
'401':
description: Missing or invalid internal service token.
'503':
description: Diagnostic admission, dedicated connection or storage unavailable; collection is unaffected.
/internal/lastleg/self-operated-analytics/quantity-diagnostics/stop:
post:
operationId: quantityDiagnosticStop
security:
- internalServiceToken: []
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/Stop'
responses:
'200':
description: ApiResponse code 200. status data is null if no grant exists.
content:
application/json:
schema:
type: object
additionalProperties: false
properties:
code:
type: string
message:
type: string
nullable: true
data:
$ref: '#/components/schemas/View'
nullable: true
required:
- code
- data
'400':
description: Invalid scope, changed frozen evidence, invalid observation or disabled feature.
'401':
description: Missing or invalid internal service token.
'503':
description: Diagnostic admission, dedicated connection or storage unavailable; collection is unaffected.
components:
securitySchemes:
internalServiceToken:
type: apiKey
in: header
name: X-Internal-Service-Token
schemas:
Arm:
type: object
additionalProperties: false
properties:
diagnosticSessionId:
type: string
maxLength: 128
minLength: 1
sourceAccount:
type: string
maxLength: 64
minLength: 1
warehouseCodes:
type: array
minItems: 1
maxItems: 8
uniqueItems: true
items:
type: string
maxLength: 64
minLength: 1
ownerCode:
type: string
maxLength: 128
minLength: 1
description: Explicit owner code, or * for all allowed owners.
excludedRootTaskId:
type: string
maxLength: 128
minLength: 1
nullable: true
description: Must match the actual started, unfinished automatic root at arm; null only when none exists.
required:
- diagnosticSessionId
- sourceAccount
- warehouseCodes
- ownerCode
Status:
type: object
additionalProperties: false
properties:
sourceAccount:
type: string
maxLength: 64
minLength: 1
producerId:
type: string
maxLength: 128
minLength: 1
attach:
type: boolean
description: True only on Integration process attachment; replacement marks delivery uncertain and fences
prior producer.
drained:
type: boolean
description: Only after observing DRAINING, closing intake and draining previously queued callbacks.
required:
- sourceAccount
- producerId
- attach
- drained
Stop:
type: object
additionalProperties: false
properties:
diagnosticSessionId:
type: string
maxLength: 128
minLength: 1
sourceAccount:
type: string
maxLength: 64
minLength: 1
producerId:
type: string
maxLength: 128
minLength: 1
reason:
type: string
enum:
- INCOMPLETE
- QUEUE_FULL
- OBSERVER_FAILED
- SHUTDOWN
required:
- diagnosticSessionId
- sourceAccount
- producerId
- reason
Observation:
type: object
additionalProperties: false
properties:
status:
type: string
maxLength: 32
minLength: 1
nullable: true
outboundTime:
type: string
maxLength: 64
minLength: 1
nullable: true
observedAt:
type: string
format: date-time
attemptId:
type: string
maxLength: 128
minLength: 1
skuSetComplete:
type: boolean
required:
- status
- outboundTime
- observedAt
- attemptId
- skuSetComplete
Sku:
type: object
additionalProperties: false
properties:
sku:
type: string
maxLength: 128
minLength: 1
listQty:
type: number
nullable: true
minimum: 0
description: Up to 32 integer digits, at most 6 decimal places; unknown stays null.
forecastQty:
type: number
nullable: true
minimum: 0
description: Up to 32 integer digits, at most 6 decimal places; unknown stays null.
actualQty:
type: number
nullable: true
minimum: 0
description: Up to 32 integer digits, at most 6 decimal places; unknown stays null.
required:
- sku
- listQty
- forecastQty
- actualQty
Key:
type: object
additionalProperties: false
properties:
warehouseCode:
type: string
maxLength: 64
minLength: 1
ownerCode:
type: string
maxLength: 128
minLength: 1
orderNo:
type: string
maxLength: 128
minLength: 1
paired:
type: boolean
required:
- warehouseCode
- ownerCode
- orderNo
- paired
Event:
type: object
additionalProperties: false
properties:
diagnosticSessionId:
type: string
maxLength: 128
minLength: 1
sourceAccount:
type: string
maxLength: 64
minLength: 1
producerId:
type: string
maxLength: 128
minLength: 1
rootTaskId:
type: string
maxLength: 128
minLength: 1
collectionSessionId:
type: string
maxLength: 128
minLength: 1
operation:
type: string
enum:
- OUTBOUND_QUERY
- OUTBOUND_DETAIL
warehouseCode:
type: string
maxLength: 64
minLength: 1
ownerCode:
type: string
maxLength: 128
minLength: 1
orderNo:
type: string
maxLength: 128
minLength: 1
side:
type: string
enum:
- LIST
- DETAIL
observation:
$ref: '#/components/schemas/Observation'
skus:
type: array
maxItems: 200
items:
$ref: '#/components/schemas/Sku'
description: Empty allowed only when skuSetComplete=false; persists inconclusive evidence.
required:
- diagnosticSessionId
- sourceAccount
- producerId
- rootTaskId
- collectionSessionId
- operation
- warehouseCode
- ownerCode
- orderNo
- side
- observation
- skus
View:
type: object
additionalProperties: false
properties:
diagnosticSessionId:
type: string
maxLength: 128
minLength: 1
sourceAccount:
type: string
maxLength: 64
minLength: 1
rootTaskId:
type: string
maxLength: 128
minLength: 1
nullable: true
collectionSessionId:
type: string
maxLength: 128
minLength: 1
nullable: true
state:
type: string
enum:
- ARMED
- BOUND
- DRAINING
- TERMINAL
stopReason:
type: string
nullable: true
startsAt:
type: string
format: date-time
nullable: true
expiresAt:
type: string
format: date-time
nullable: true
bindBefore:
type: string
format: date-time
nullable: true
warehouseCodes:
type: array
maxItems: 8
items:
type: string
maxLength: 64
minLength: 1
ownerCode:
type: string
maxLength: 128
minLength: 1
excludedRootTaskId:
type: string
maxLength: 128
minLength: 1
nullable: true
candidates:
type: integer
minimum: 0
maximum: 100
pairedOrders:
type: integer
minimum: 0
maximum: 100
retainedRows:
type: integer
minimum: 0
maximum: 2000
retainedBytes:
type: integer
minimum: 0
maximum: 2097152
deliveryUncertain:
type: boolean
selected:
type: array
maxItems: 100
items:
$ref: '#/components/schemas/Key'
required:
- diagnosticSessionId
- sourceAccount
- rootTaskId
- collectionSessionId
- state
- stopReason
- startsAt
- expiresAt
- bindBefore
- warehouseCodes
- ownerCode
- excludedRootTaskId
- candidates
- pairedOrders
- retainedRows
- retainedBytes
- deliveryUncertain
- selected
Receipt:
type: object
additionalProperties: false
properties:
outcome:
type: string
enum:
- ACCEPTED
- IGNORED
- DUPLICATE
- STOPPED
comparison:
type: string
nullable: true
enum:
- ALL_EQUAL
- QUANTITY_DIFFERENCE
- INCONCLUSIVE
session:
$ref: '#/components/schemas/View'
required:
- outcome
- comparison
- session