feat: add self-operated analytics and enforce Lastleg module boundaries
This commit is contained in:
@@ -46,6 +46,18 @@ lastleg:
|
||||
enabled: ${LASTLEG_SMART_DISPATCH_API_ENABLED:true}
|
||||
|
||||
baiyue:
|
||||
self-operated-analytics:
|
||||
collection-mode: ${SELFOP_COLLECTION_MODE:OFF}
|
||||
environment: ${DEPLOY_ENV:test}
|
||||
daily-request-budget: ${SELFOP_DAILY_REQUEST_BUDGET:0}
|
||||
business-min-request-interval-ms: ${SELFOP_MIN_REQUEST_INTERVAL_MS:5000}
|
||||
execution-enabled: ${SELFOP_EXECUTION_ENABLED:false}
|
||||
sales-publication-enabled: ${SELFOP_SALES_PUBLICATION_ENABLED:false}
|
||||
integration-base-url: http://integration-service:9210
|
||||
internal-service-token: ${INTERNAL_SERVICE_TOKEN:}
|
||||
source-account: ${SELFOP_SOURCE_ACCOUNT:lingxing-primary}
|
||||
source-query-timezone: Asia/Shanghai
|
||||
quantity-unit: PCS
|
||||
http:
|
||||
clients:
|
||||
unload-photo-file:
|
||||
|
||||
@@ -3588,3 +3588,304 @@ PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
-- 新签收及新合箱必须打印并扫码确认标签;既有实物按原状态继续作业。
|
||||
SET @ddl = IF(EXISTS(SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='ll_return_inventory_carton' AND column_name='label_status'), 'SELECT 1', 'ALTER TABLE ll_return_inventory_carton ADD COLUMN label_status VARCHAR(32) NULL COMMENT ''WAIT_LABEL待贴标 CONFIRMED已扫码确认标签''');
|
||||
PREPARE stmt FROM @ddl; EXECUTE stmt; DEALLOCATE PREPARE stmt;
|
||||
|
||||
|
||||
-- 平台自营领星统计:独立事实与不可变发布版本;仅空库初始化,不自动执行。
|
||||
CREATE TABLE ll_selfop_outbound_discovery_scope (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
source_account VARCHAR(64) NOT NULL COMMENT '受控来源账号别名,不保存密钥',
|
||||
catalog_from_utc DATETIME(3) NULL COMMENT '账号完整目录连续覆盖UTC下界,不等同销量覆盖',
|
||||
catalog_until_utc DATETIME(3) NULL COMMENT '账号完整目录连续覆盖UTC上界,不等同销量覆盖',
|
||||
next_sequence BIGINT NOT NULL DEFAULT 1 COMMENT '新发现任务的单调调度序号;重试沿用,只安排任务,不判断对象内容的新旧',
|
||||
next_observation_sequence BIGINT NOT NULL DEFAULT 1 COMMENT '每次实际出库详情请求前分配的单调采集代次;与 task 调度序号独立,重试请求也分配新代次',
|
||||
active_task_id BIGINT NULL COMMENT '当前共享发现/详情补齐任务',
|
||||
lease_owner VARCHAR(128) NULL COMMENT '账号发现执行者',
|
||||
lease_until_utc DATETIME(3) NULL COMMENT '账号发现租约到期时刻',
|
||||
fence_token BIGINT NOT NULL DEFAULT 0 COMMENT '防止过期发现进程继续写共享暂存或派发任务',
|
||||
request_budget INT NOT NULL COMMENT '一次调度允许的目录、详情请求总预算,必须为正',
|
||||
time_budget_seconds INT NOT NULL COMMENT '一次调度允许占用的执行时长,必须为正',
|
||||
min_request_interval_ms INT NOT NULL COMMENT '同账号请求最小间隔,按已核准配额配置',
|
||||
api_budget_json JSON NULL COMMENT '账号所有采集族共用的预算、统计日、保守预留及确认消耗、尝试许可和独占交接依据',
|
||||
api_cooldown_until_utc DATETIME(3) NULL COMMENT '账号全部真实请求共用冷却UTC截止,重启与跨日不清除',
|
||||
api_pause_reason VARCHAR(64) NULL COMMENT '账号停止或等待的固定原因码,不保存供应商原始错误或凭据',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_discovery_account (source_account),
|
||||
CONSTRAINT chk_selfop_outbound_discovery_scope CHECK (request_budget > 0 AND time_budget_seconds > 0 AND min_request_interval_ms > 0 AND fence_token >= 0 AND next_sequence > 0 AND next_observation_sequence > 0)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='账号共享出库目录与详情发现协调作用域';
|
||||
|
||||
CREATE TABLE ll_selfop_sync_scope (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
source_account VARCHAR(64) NOT NULL COMMENT '受控来源账号别名,不保存密钥',
|
||||
warehouse_code VARCHAR(64) NOT NULL COMMENT '来源仓库原始编码,按仓独立统计',
|
||||
data_family VARCHAR(16) NOT NULL COMMENT 'OUTBOUND 或 INVENTORY;按账号+仓库+任务族互斥',
|
||||
scope_json JSON NOT NULL COMMENT '本仓范围规则,customerMode=ALL_AUTHORIZED,库存为全部品质;当前账号全部授权货主均自营,不将当天出现的货主列表当白名单',
|
||||
scope_hash CHAR(64) NOT NULL COMMENT '仓库、货主范围规则、品质、时区及单位口径的规范化摘要;不包含当天观测到的客户/SKU 集合',
|
||||
business_timezone VARCHAR(64) NOT NULL COMMENT '本仓报表及调度时区,初始建议值为 Asia/Shanghai,各仓独立核准',
|
||||
source_timezone VARCHAR(64) NULL COMMENT '本仓已核准的出库源时间时区',
|
||||
schedule_cron VARCHAR(128) NOT NULL COMMENT '本仓、本任务族的调度表达式,按 business_timezone 执行',
|
||||
stale_after_seconds INT NOT NULL COMMENT '本仓、本任务族数据过期阈值,必须为正;库存初始可采用 26 小时,后续按仓调整',
|
||||
warehouse_policy_ref VARCHAR(128) NULL COMMENT '未来按仓告警/补货策略的稳定引用;一期为空,不建告警规则表',
|
||||
initial_from_utc DATETIME(3) NULL COMMENT '首采固定UTC下界,按本仓业务时区减一个月',
|
||||
initial_until_utc DATETIME(3) NULL COMMENT '首采固定UTC截止,重试不重新取当前时间',
|
||||
discovery_from_utc DATETIME(3) NULL COMMENT '本仓已发布的连续销量覆盖UTC下界',
|
||||
discovery_until_utc DATETIME(3) NULL COMMENT '本仓已发布的连续销量覆盖UTC上界,不含端点',
|
||||
fact_revision BIGINT NOT NULL DEFAULT 0 COMMENT '出库事实归并修订号;内容实际变化才增加',
|
||||
published_fact_revision BIGINT NOT NULL DEFAULT 0 COMMENT '本仓最后已发布销量版所使用的事实修订号',
|
||||
rebuild_required TINYINT NOT NULL DEFAULT 0 COMMENT '事实变化待重建标记;跨仓修订同时置旧、新仓为 1',
|
||||
invalidated_at_utc DATETIME(3) NULL COMMENT '最近一次因事实修订使当前版待重建的时刻',
|
||||
published_run_id BIGINT NULL COMMENT '唯一对外可见版本,指向本任务族已发布执行批次',
|
||||
lease_owner VARCHAR(128) NULL COMMENT '当前执行者令牌,不使用仅进程内锁',
|
||||
lease_until_utc DATETIME(3) NULL COMMENT '租约到期时刻',
|
||||
fence_token BIGINT NOT NULL DEFAULT 0 COMMENT '每次取得租约递增,事实提交和发布均校验',
|
||||
known_order_cursor_id BIGINT NULL COMMENT '本仓已可靠处理的稳定订单内部标识游标',
|
||||
known_order_round_max_id BIGINT NULL COMMENT '本轮已知单复查固定最大内部标识',
|
||||
known_order_round_started_at_utc DATETIME(3) NULL COMMENT '本仓已知单复查轮次开始UTC时间',
|
||||
known_order_round_finished_at_utc DATETIME(3) NULL COMMENT '本仓已知单完整轮转完成UTC时间',
|
||||
history_round_from_utc DATETIME(3) NULL COMMENT '本仓历史核对固定UTC下界',
|
||||
history_round_until_utc DATETIME(3) NULL COMMENT '本仓历史核对固定UTC上界',
|
||||
history_slice_cursor_utc DATETIME(3) NULL COMMENT '本仓下一待核对历史切片UTC位置',
|
||||
history_round_finished_at_utc DATETIME(3) NULL COMMENT '上一轮历史时间片全部完成时刻',
|
||||
review_request_budget INT NOT NULL COMMENT '本仓单次复查最大请求数,必须为正',
|
||||
review_time_budget_seconds INT NOT NULL COMMENT '本仓单次复查最大执行秒数,必须为正',
|
||||
review_target_days INT NOT NULL DEFAULT 7 COMMENT '建议每 7 天轮转一遍,属于待配额验证的目标,不保证首次大量详情在单次调度内完成',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_scope (source_account,warehouse_code,data_family),
|
||||
KEY idx_selfop_scope_lease (lease_until_utc),
|
||||
CONSTRAINT chk_selfop_sync_scope CHECK (data_family IN ('OUTBOUND','INVENTORY') AND stale_after_seconds > 0 AND review_request_budget > 0 AND review_time_budget_seconds > 0 AND review_target_days > 0 AND fact_revision >= 0 AND published_fact_revision >= 0 AND fence_token >= 0)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='分仓任务族租约及发布指针';
|
||||
|
||||
CREATE TABLE ll_selfop_sync_task (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
task_no VARCHAR(64) NOT NULL COMMENT '稳定采集业务任务号,重试沿用,不展示内部数据库标识',
|
||||
execution_purpose VARCHAR(16) NOT NULL COMMENT 'BUSINESS或VALIDATION;由服务端冻结用途,子任务继承',
|
||||
validation_root_task_id BIGINT NULL COMMENT '验证会话唯一预算根任务,根引用自身,正式任务为空',
|
||||
validation_budget_json JSON NULL COMMENT '验证根冻结硬预算、累计消耗、库存分仓页数、截止时刻及停止原因',
|
||||
source_account VARCHAR(64) NOT NULL COMMENT '受控来源账号别名,不保存密钥',
|
||||
task_role VARCHAR(24) NOT NULL COMMENT 'ACCOUNT_DISCOVERY 或 WAREHOUSE_SYNC',
|
||||
scope_id BIGINT NULL COMMENT '分仓任务必须引用分仓作用域;仅账号共享发现为空',
|
||||
warehouse_code VARCHAR(64) NULL COMMENT '来源仓库原始编码,按仓独立统计',
|
||||
discovery_scope_id BIGINT NULL COMMENT '共享发现必填,引用账号发现协调器',
|
||||
upstream_task_id BIGINT NULL COMMENT '出库分仓任务引用已持久化目录的共享发现切片;库存无此上游',
|
||||
discovery_sequence BIGINT NULL COMMENT '共享任务及分仓子任务继承的调度顺序;重试保持不变,不用于事实覆盖判定',
|
||||
observation_baseline BIGINT NULL COMMENT '共享任务建立时已分配的最大详情采集代次,分仓子任务继承;用于识别旧任务恢复期间出现的其他任务新观测',
|
||||
request_key VARCHAR(128) NOT NULL COMMENT '共享发现包含切片/计划槽位;分仓任务包含仓库、任务族及切片或计划槽位;人工附请求幂等键',
|
||||
request_hash CHAR(64) NOT NULL COMMENT '请求类型、查询范围、范围摘要的指纹;同键不同请求拒绝',
|
||||
task_type VARCHAR(24) NOT NULL COMMENT 'SCHEDULED、MANUAL_RETRY、BACKFILL、RECHECK、REBUILD、VALIDATION;验证不由自动计划创建',
|
||||
planned_at_utc DATETIME(3) NULL COMMENT '计划时点;人工请求可空',
|
||||
query_from_utc DATETIME(3) NULL COMMENT '出库查询区间UTC下界,库存不填',
|
||||
query_until_utc DATETIME(3) NULL COMMENT '出库查询区间UTC上界,不含端点,库存不填',
|
||||
query_scope_json JSON NOT NULL COMMENT '不变的账号、货主、仓库、品质和查询条件快照;按单补查在此记录单号',
|
||||
routing_manifest_json JSON NULL COMMENT '共享切片目录完整标记、每仓对象键集合/数量和详情就绪状态;各对象记录 effectiveStageId,需新代次复查时记录 refreshTaskId,完成后指向新有效暂存;不改写旧载荷',
|
||||
scope_hash CHAR(64) NOT NULL COMMENT '建任务时的业务范围摘要',
|
||||
status VARCHAR(20) NOT NULL COMMENT 'WAITING_SOURCE、READY、RUNNING、RETRY_WAIT、SUCCEEDED、DEAD、SAMPLE_DONE;样本结束不等于正式成功',
|
||||
apply_state VARCHAR(20) NOT NULL COMMENT '正式出库归并NOT_STARTED、APPLYING、BLOCKED、APPLIED;共享发现、库存、重建及验证为NOT_APPLICABLE',
|
||||
affected_warehouse_codes_json JSON NULL COMMENT '本次归并可能改变的仓集合,包含原仓与新仓;首段事实写入前登记,扩大集合须先取得新增仓租约并锁 scope,不能写完再补',
|
||||
apply_started_at_utc DATETIME(3) NULL COMMENT '首段事实提交UTC时间',
|
||||
apply_completed_at_utc DATETIME(3) NULL COMMENT '全部必需事实归并完成UTC时间,失败不填',
|
||||
attempt_count INT NOT NULL DEFAULT 0 COMMENT '已创建的执行尝试数',
|
||||
next_retry_at_utc DATETIME(3) NULL COMMENT '有限退避后下一次可执行时刻',
|
||||
requested_by VARCHAR(128) NULL COMMENT '人工请求的平台操作人,仅内部审计',
|
||||
result_published_run_id BIGINT NULL COMMENT '正式成功任务实际发布或复用的版本;验证和共享发现为空',
|
||||
progress_json JSON NULL COMMENT '与可靠检查点一起提交的有界阶段、单位、尝试和质量进度,不保存单据集合',
|
||||
progress_updated_at_utc DATETIME(3) NULL COMMENT '最后可靠业务检查点UTC时间,与执行心跳分开',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_task_no (task_no),
|
||||
UNIQUE KEY uk_selfop_task_request (source_account,request_key),
|
||||
KEY idx_selfop_task_poll (status,next_retry_at_utc,id),
|
||||
KEY idx_selfop_task_upstream (upstream_task_id,warehouse_code),
|
||||
KEY idx_selfop_task_apply (apply_state,id),
|
||||
KEY idx_selfop_task_scope_list (scope_id,created_at,id),
|
||||
KEY idx_selfop_task_account_list (source_account,task_role,created_at,id),
|
||||
CONSTRAINT chk_selfop_sync_task CHECK (attempt_count >= 0 AND execution_purpose IN ('BUSINESS','VALIDATION') AND ((execution_purpose = 'BUSINESS' AND validation_root_task_id IS NULL AND validation_budget_json IS NULL) OR (execution_purpose = 'VALIDATION' AND validation_root_task_id IS NOT NULL AND apply_state = 'NOT_APPLICABLE' AND result_published_run_id IS NULL AND status <> 'SUCCEEDED')) AND ((task_role = 'ACCOUNT_DISCOVERY' AND scope_id IS NULL AND warehouse_code IS NULL AND discovery_scope_id IS NOT NULL) OR (task_role = 'WAREHOUSE_SYNC' AND scope_id IS NOT NULL AND warehouse_code IS NOT NULL)))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='一次计划或人工请求';
|
||||
|
||||
CREATE TABLE ll_selfop_sync_run (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
task_id BIGINT NOT NULL COMMENT '本次执行请求',
|
||||
execution_purpose VARCHAR(16) NOT NULL COMMENT '从逻辑任务冻结继承,验证尝试不能作为正式统计版本',
|
||||
scope_id BIGINT NULL COMMENT '仅账号共享发现为空;分仓执行必须有作用域',
|
||||
source_account VARCHAR(64) NOT NULL COMMENT '受控来源账号别名,不保存密钥',
|
||||
warehouse_code VARCHAR(64) NULL COMMENT '来源仓库原始编码,按仓独立统计',
|
||||
run_role VARCHAR(24) NOT NULL COMMENT 'ACCOUNT_DISCOVERY 或 WAREHOUSE_SYNC',
|
||||
upstream_task_id BIGINT NULL COMMENT '分仓出库计算引用的共享切片及其稳定暂存集合',
|
||||
attempt_no INT NOT NULL COMMENT '同一请求从 1 起递增',
|
||||
scope_hash CHAR(64) NOT NULL COMMENT '本版本的业务范围摘要',
|
||||
scope_snapshot_json JSON NOT NULL COMMENT '分仓版只含本仓货主/品质、固定首采 [B,E0)、时区、调度与过期阈值;账号发现保存待路由仓集合,不冒充业务版',
|
||||
observed_dimensions_json JSON NULL COMMENT '本次实际出现的仓库/货主集合及数量摘要,仅作采集证据;例如已观测 70 货主不等于固定授权范围',
|
||||
fence_token BIGINT NOT NULL COMMENT '本尝试持有的栅栏版本',
|
||||
base_published_run_id BIGINT NULL COMMENT '执行开始时的上一可见版本',
|
||||
reference_sales_run_id BIGINT NULL COMMENT '库存构建开始时固定的本仓已发布销量版,用其不可变 SKU 维度生成出库已知商品占位;没有已发布销量版时为空,不读取半归并订单事实',
|
||||
inventory_daily_sample_date DATE NULL COMMENT '北京时间当日首个合格计划库存发布代表日期,非代表为空',
|
||||
inventory_sample_rule_version VARCHAR(32) NULL COMMENT '日库存代表选择规则 DAILY_SCHEDULED_FIRST_V1,与日标记原子保存',
|
||||
status VARCHAR(24) NOT NULL COMMENT 'FETCHING、VALIDATED、ROUTED、FACTS_APPLIED、BUILDING、READY、PUBLISHED、REUSED、YIELDED、FAILED、ABORTED、SAMPLE_DONE;复用和验证不是版本头',
|
||||
last_phase VARCHAR(24) NOT NULL COMMENT '失败/中止前所在阶段,支持判断是否已经归并事实',
|
||||
fetch_started_at_utc DATETIME(3) NULL COMMENT '实际采集开始UTC时间',
|
||||
fetch_finished_at_utc DATETIME(3) NULL COMMENT '实际采集完成UTC时间,未完成为空',
|
||||
build_started_at_utc DATETIME(3) NULL COMMENT '实际开始有界候选构建UTC时间,用于构建耗时及首采合并间隔',
|
||||
finished_at_utc DATETIME(3) NULL COMMENT '本次尝试终止UTC时间',
|
||||
published_at_utc DATETIME(3) NULL COMMENT '实际原子切换发布指针UTC时间',
|
||||
superseded_at_utc DATETIME(3) NULL COMMENT '被新发布版替代的首次UTC时间,同事务填写且重试不重置',
|
||||
page_count INT NOT NULL DEFAULT 0 COMMENT '已完整获取页数',
|
||||
source_total_count BIGINT NULL COMMENT '上游可靠返回的总数;未返回则为空',
|
||||
unique_object_count BIGINT NOT NULL DEFAULT 0 COMMENT '规范化去重后对象数',
|
||||
progress_snapshot_json JSON NULL COMMENT '尝试终止时冻结的有界可靠进度摘要,历史尝试不随逻辑任务改写',
|
||||
heartbeat_at_utc DATETIME(3) NULL COMMENT '有效执行者最新UTC心跳,不代表业务检查点推进',
|
||||
coverage_status VARCHAR(16) NOT NULL COMMENT 'UNKNOWN、PARTIAL、COMPLETE;分页完整与数值有效性分别判断',
|
||||
covered_from_utc DATETIME(3) NULL COMMENT '本仓销量版本实际连续覆盖UTC下界',
|
||||
covered_until_utc DATETIME(3) NULL COMMENT '本仓销量版本实际连续覆盖UTC上界,不含端点',
|
||||
complete_day_from DATE NULL COMMENT '本仓完整自然日区间首日,包含',
|
||||
complete_day_until DATE NULL COMMENT '本仓完整自然日区间末日,不含',
|
||||
applied_fact_revision BIGINT NULL COMMENT '本次尝试归并后的事实修订号,库存为空',
|
||||
calculated_fact_revision BIGINT NULL COMMENT '候选销量版本计算所依据的固定事实修订号',
|
||||
error_code VARCHAR(64) NULL COMMENT '内部可诊断错误分类,不保存认证信息',
|
||||
error_message VARCHAR(500) NULL COMMENT '脱敏后的固定错误摘要',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_run_attempt (task_id,attempt_no),
|
||||
UNIQUE KEY uk_selfop_inventory_daily (source_account,warehouse_code,inventory_daily_sample_date),
|
||||
KEY idx_selfop_run_scope (scope_id,id),
|
||||
KEY idx_selfop_run_status (status,updated_at),
|
||||
CONSTRAINT chk_selfop_inventory_daily CHECK ((inventory_daily_sample_date IS NULL AND inventory_sample_rule_version IS NULL) OR (inventory_daily_sample_date IS NOT NULL AND inventory_sample_rule_version IS NOT NULL AND inventory_sample_rule_version = 'DAILY_SCHEDULED_FIRST_V1' AND execution_purpose = 'BUSINESS' AND run_role = 'WAREHOUSE_SYNC' AND status = 'PUBLISHED' AND coverage_status = 'COMPLETE')),
|
||||
CONSTRAINT chk_selfop_sync_run CHECK (attempt_no > 0 AND page_count >= 0 AND unique_object_count >= 0 AND execution_purpose IN ('BUSINESS','VALIDATION') AND (execution_purpose <> 'VALIDATION' OR status NOT IN ('PUBLISHED','REUSED')) AND (source_total_count IS NULL OR source_total_count >= 0) AND ((run_role = 'ACCOUNT_DISCOVERY' AND scope_id IS NULL AND warehouse_code IS NULL) OR (run_role = 'WAREHOUSE_SYNC' AND scope_id IS NOT NULL AND warehouse_code IS NOT NULL)))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='执行尝试、覆盖证明和版本头';
|
||||
|
||||
CREATE TABLE ll_selfop_sync_stage (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
run_id BIGINT NOT NULL COMMENT '首次写入该暂存对象的执行尝试',
|
||||
stage_batch_id BIGINT NOT NULL COMMENT '出库取共享发现 task.id,便于断点续取;库存取本次 run.id,严禁跨尝试混页',
|
||||
last_fetch_run_id BIGINT NOT NULL COMMENT '最后一次补齐该对象的执行尝试,保留重试来源',
|
||||
observation_sequence BIGINT NULL COMMENT '该完整出库详情实际请求的采集代次;有效出库对象必填,目录待补对象和库存为空;不能填 task 调度序号',
|
||||
warehouse_code VARCHAR(64) NOT NULL COMMENT '来源仓库原始编码,按仓独立统计',
|
||||
previous_warehouse_code VARCHAR(64) NULL COMMENT '路由时从已有单据识别的原仓库;归并前再校验,跨仓时通知两仓',
|
||||
object_type VARCHAR(16) NOT NULL COMMENT 'OUTBOUND_ORDER 或 PRODUCT_STOCK',
|
||||
object_key_hash CHAR(64) NOT NULL COMMENT '规范化业务键摘要;原业务键保留在载荷中并核对',
|
||||
first_page_no INT NOT NULL COMMENT '首次发现页码',
|
||||
observed_at_utc DATETIME(3) NOT NULL COMMENT '实际接收该对象的时刻',
|
||||
content_hash CHAR(64) NOT NULL COMMENT '完整规范化对象摘要',
|
||||
payload_json JSON NOT NULL COMMENT '目录阶段可先存订单头,详情齐后补完整 SKU;VALID 后不再修改;库存保存产品库存字段',
|
||||
before_payload_json JSON NULL COMMENT '订单归并事务内记录归并前的完整规范化事实;新增单为空',
|
||||
validation_status VARCHAR(16) NOT NULL COMMENT '暂存校验状态:PENDING待核验、VALID有效、INVALID异常',
|
||||
validation_code VARCHAR(64) NULL COMMENT '字段缺失、冲突、未知时区等原因',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_stage_object (stage_batch_id,object_type,object_key_hash),
|
||||
KEY idx_selfop_stage_history (object_type,object_key_hash,stage_batch_id),
|
||||
KEY idx_selfop_stage_observation (object_type,object_key_hash,validation_status,observation_sequence),
|
||||
KEY idx_selfop_stage_route (stage_batch_id,warehouse_code,validation_status),
|
||||
CONSTRAINT chk_selfop_sync_stage CHECK (first_page_no > 0 AND (object_type <> 'OUTBOUND_ORDER' OR validation_status <> 'VALID' OR observation_sequence IS NOT NULL))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='待验证事实与修订证据';
|
||||
|
||||
CREATE TABLE ll_selfop_outbound_order (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
source_account VARCHAR(64) NOT NULL COMMENT '受控来源账号别名,不保存密钥',
|
||||
customer_code VARCHAR(64) NOT NULL COMMENT '领星货主原始编码,不等同平台客户标识',
|
||||
warehouse_code VARCHAR(64) NOT NULL COMMENT '来源仓库原始编码,按仓独立统计',
|
||||
delivery_no VARCHAR(128) NOT NULL COMMENT 'OMP 发货单号,采用列表及详情同一身份',
|
||||
source_no VARCHAR(128) NULL COMMENT 'WMS 来源出库单号,缺失不以内部 ID 回退展示',
|
||||
source_status INT NOT NULL COMMENT '原始状态,100 已出库、99 已取消;不改造成内部状态码',
|
||||
source_created_time VARCHAR(64) NULL COMMENT '来源创建时间原始字符串,不使用采集时间替代',
|
||||
source_outbound_time VARCHAR(64) NULL COMMENT '来源实际出库时间原始字符串,不使用采集时间替代',
|
||||
source_timezone VARCHAR(64) NULL COMMENT '解析采用的源时区',
|
||||
outbound_at_utc DATETIME(3) NULL COMMENT '已核准的实际出库时间点;非出库状态可空',
|
||||
business_date DATE NULL COMMENT '已核准业务时区下的出库日',
|
||||
business_timezone VARCHAR(64) NOT NULL COMMENT '该事实当前归属仓所用业务时区,迁仓后重新确定业务日',
|
||||
sales_eligible TINYINT NOT NULL DEFAULT 0 COMMENT '仅已出库、时间与全部数量有效时为 1',
|
||||
revision_no BIGINT NOT NULL DEFAULT 1 COMMENT '该单内容变更次数,不等于拉取次数',
|
||||
content_hash CHAR(64) NOT NULL COMMENT '订单头及完整 SKU 明细规范化摘要',
|
||||
last_run_id BIGINT NOT NULL COMMENT '最后一次确认或修订的执行尝试',
|
||||
last_observation_sequence BIGINT NOT NULL COMMENT '最后接受的完整详情采集代次;仅防旧观测重放,不按 task 调度序号拒绝较晚实际读取的事实,不冒充领星源版本号',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_order (source_account,customer_code,delivery_no),
|
||||
KEY idx_selfop_order_daily (source_account,warehouse_code,sales_eligible,business_date,id),
|
||||
KEY idx_selfop_order_run (last_run_id),
|
||||
CONSTRAINT chk_selfop_outbound_order CHECK (revision_no > 0 AND last_observation_sequence > 0 AND sales_eligible IN (0,1) AND (sales_eligible = 0 OR (source_status = 100 AND source_timezone IS NOT NULL AND outbound_at_utc IS NOT NULL AND business_date IS NOT NULL)))
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='最后确认的单据事实';
|
||||
|
||||
CREATE TABLE ll_selfop_outbound_item (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
order_id BIGINT NOT NULL COMMENT '对应外部出库事实',
|
||||
sku_code VARCHAR(128) NOT NULL COMMENT '原始 productSku',
|
||||
product_name VARCHAR(255) NULL COMMENT '来源商品名称,仅作展示',
|
||||
actual_quantity DECIMAL(20,6) NOT NULL COMMENT '详情 actualDeliveryQty,必须为非负有效数值',
|
||||
quantity_unit VARCHAR(32) NOT NULL COMMENT '已核准业务单位;未确认单位不发布正式数量统计',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_order_sku (order_id,sku_code),
|
||||
KEY idx_selfop_item_sku (sku_code,order_id),
|
||||
CONSTRAINT chk_selfop_outbound_item CHECK (actual_quantity >= 0)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='整单替换的实际出库明细';
|
||||
|
||||
CREATE TABLE ll_selfop_inventory_snapshot (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
snapshot_run_id BIGINT NOT NULL COMMENT 'INVENTORY 执行尝试;发布后该批明细不可修改',
|
||||
source_account VARCHAR(64) NOT NULL COMMENT '受控来源账号别名,不保存密钥',
|
||||
customer_code VARCHAR(64) NOT NULL COMMENT '领星货主原始编码,不等同平台客户标识',
|
||||
warehouse_code VARCHAR(64) NOT NULL COMMENT '来源仓库原始编码,按仓独立统计',
|
||||
sku_code VARCHAR(128) NOT NULL COMMENT '原始产品 SKU',
|
||||
product_quality SMALLINT NOT NULL COMMENT '来源品质,当前 0 正品、1 次品;全量均保存,不套用整箱库存',
|
||||
product_name VARCHAR(255) NULL COMMENT '来源名称',
|
||||
physical_quantity DECIMAL(20,6) NULL COMMENT '来源stkQty实物库存,未知为空',
|
||||
available_quantity DECIMAL(20,6) NULL COMMENT '来源useStkQty可用库存,未知为空,不再次扣冻结',
|
||||
frozen_quantity DECIMAL(20,6) NULL COMMENT '来源freezeQty冻结库存,未知为空',
|
||||
transit_quantity DECIMAL(20,6) NULL COMMENT '来源transitQty在途数量,未知为空,不计可售库存',
|
||||
source_unique_key VARCHAR(512) NULL COMMENT '原 uniqueKey4tenant,只作来源证据',
|
||||
observed_at_utc DATETIME(3) NOT NULL COMMENT '所在页实际采集时间;缺行占位取本批采集完成时间',
|
||||
quality_status VARCHAR(16) NOT NULL COMMENT 'VALID、UNKNOWN、INVALID;STALE 按批次年龄实时派生',
|
||||
quality_reason VARCHAR(64) NULL COMMENT 'SOURCE_ROW_MISSING、FIELD_MISSING、NEGATIVE_QUANTITY 等',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_stock_snapshot (snapshot_run_id,source_account,customer_code,warehouse_code,sku_code,product_quality),
|
||||
KEY idx_selfop_stock_lookup (source_account,customer_code,warehouse_code,sku_code,product_quality,snapshot_run_id)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='产品库存全量批次明细';
|
||||
|
||||
CREATE TABLE ll_selfop_sku_daily_sales (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
sales_run_id BIGINT NOT NULL COMMENT 'OUTBOUND 执行尝试,同时是计算版本',
|
||||
source_account VARCHAR(64) NOT NULL COMMENT '受控来源账号别名,不保存密钥',
|
||||
customer_code VARCHAR(64) NOT NULL COMMENT '领星货主原始编码,不等同平台客户标识',
|
||||
warehouse_code VARCHAR(64) NOT NULL COMMENT '来源仓库原始编码,按仓独立统计',
|
||||
sku_code VARCHAR(128) NOT NULL COMMENT '原始产品 SKU',
|
||||
business_date DATE NOT NULL COMMENT '已核准业务日',
|
||||
outbound_quantity DECIMAL(20,6) NOT NULL COMMENT '有效出库实际件数之和,非负',
|
||||
outbound_order_count BIGINT NOT NULL COMMENT '该维度去重发货单数,非负',
|
||||
quantity_unit VARCHAR(32) NOT NULL COMMENT '同一统计维度内一致的业务单位',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_daily_version (sales_run_id,source_account,customer_code,warehouse_code,sku_code,business_date),
|
||||
KEY idx_selfop_daily_window (sales_run_id,business_date,customer_code,sku_code),
|
||||
CONSTRAINT chk_selfop_sku_daily_sales CHECK (outbound_quantity >= 0 AND outbound_order_count >= 0)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='完整销量版本的稀疏日事实';
|
||||
|
||||
CREATE TABLE ll_selfop_sku_profile (
|
||||
id BIGINT NOT NULL COMMENT '应用生成的记录标识',
|
||||
created_at DATETIME(3) NOT NULL COMMENT 'UTC创建时间',
|
||||
updated_at DATETIME(3) NOT NULL COMMENT 'UTC更新时间',
|
||||
profile_run_id BIGINT NOT NULL COMMENT '本仓销量或库存候选版本;与对应 daily/snapshot 使用同一 run,发布后该版本全部维度行不可修改',
|
||||
source_account VARCHAR(64) NOT NULL COMMENT '受控来源账号别名,不保存密钥',
|
||||
customer_code VARCHAR(64) NOT NULL COMMENT '领星货主原始编码,不等同平台客户标识',
|
||||
warehouse_code VARCHAR(64) NOT NULL COMMENT '来源仓库原始编码,按仓独立统计',
|
||||
sku_code VARCHAR(128) NOT NULL COMMENT '原始产品 SKU',
|
||||
product_name VARCHAR(255) NULL COMMENT '本版本确认的名称,不实时连接其他版本名称',
|
||||
quantity_unit VARCHAR(32) NULL COMMENT '本版本已核准单位;未知或两版本单位冲突时不计算混合指标',
|
||||
first_seen_at_utc DATETIME(3) NULL COMMENT '本证据族真实观测到本仓商品的最早接收时刻;缺行占位不能生成观察证据',
|
||||
earliest_evidence_at_utc DATETIME(3) NULL COMMENT '库存版取真实库存首次观察时刻;销量版从该版有效事实重新求最早已核准出库时间,可随改期、取消或迁仓撤回/后移',
|
||||
evidence_type VARCHAR(24) NOT NULL COMMENT 'INVENTORY_OBSERVATION、VALID_OUTBOUND、NONE;不得将销量证据复制成库存真实观察证据',
|
||||
evidence_run_id BIGINT NULL COMMENT '本证据族真实依据的采集批次,无证据占位为空',
|
||||
last_seen_run_id BIGINT NULL COMMENT '本证据族最近真实观测批次,无证据占位为空',
|
||||
PRIMARY KEY (id),
|
||||
UNIQUE KEY uk_selfop_profile_version (profile_run_id,source_account,customer_code,warehouse_code,sku_code),
|
||||
KEY idx_selfop_profile_evidence (profile_run_id,earliest_evidence_at_utc,customer_code,sku_code)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='随发布版本固定的 SKU 维度与观察依据';
|
||||
|
||||
@@ -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 }
|
||||
@@ -0,0 +1,62 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: Platform Self-operated Analytics Sync Commands
|
||||
version: 1.0.0
|
||||
paths:
|
||||
/api/platform/v1/last-leg/self-operated-analytics/sync-tasks:
|
||||
post:
|
||||
operationId: requestSelfoperatedAnalyticsSyncTask
|
||||
summary: 创建人工采集、复查、重建或恢复任务
|
||||
description: >-
|
||||
仅平台账号且须 platform:self-operated-analytics:sync 权限。命令先持久化,
|
||||
不在 HTTP 请求内运行历史采集。collectionMode 默认 OFF;VALIDATION 仅用于持久预算内的样本暂存,
|
||||
BUSINESS 仅允许生产环境,并要求真实出口取得服务端核验的人工独占许可。
|
||||
出库来源时间及业务时间统一 Asia/Shanghai;首次正式目标固定为 E0 前两个滚动月。
|
||||
BACKFILL 单片不超过一天。RETRY 使用 taskNo 和非空 reason 恢复原分仓逻辑任务,
|
||||
保留半归并屏障及旧尝试,拒绝验证会话复活、账号共享任务伪装单仓、有效执行租约及上游未齐;
|
||||
requestKey 同键异载荷拒绝。成功受理只表示排队,不表示采集或发布成功。
|
||||
security:
|
||||
- bearerAuth: []
|
||||
x-required-authorities:
|
||||
- platform:self-operated-analytics:sync
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/SyncCommand'
|
||||
responses:
|
||||
'200':
|
||||
description: 平台 ApiResponse 包络,成功 code 为字符串 200;返回稳定业务任务号与 ACCEPTED
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: { type: string }
|
||||
message: { type: string }
|
||||
data:
|
||||
type: object
|
||||
properties:
|
||||
taskNo: { type: string }
|
||||
warehouseCode: { type: string }
|
||||
status: { type: string, enum: [ACCEPTED] }
|
||||
'401': { description: 未认证 }
|
||||
'403': { description: 非平台身份或无独立写权限 }
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth: { type: http, scheme: bearer, bearerFormat: JWT }
|
||||
schemas:
|
||||
SyncCommand:
|
||||
type: object
|
||||
required: [requestKey, warehouseCode, action]
|
||||
properties:
|
||||
requestKey: { type: string, minLength: 1, maxLength: 100 }
|
||||
warehouseCode: { type: string, minLength: 1, maxLength: 64 }
|
||||
action: { type: string, enum: [INVENTORY, BACKFILL, RECHECK, REBUILD, RETRY, VALIDATION] }
|
||||
taskNo: { type: string, minLength: 1, maxLength: 64, description: RETRY 必填,原始分仓业务任务号 }
|
||||
reason: { type: string, minLength: 1, maxLength: 500, description: RETRY 必填,随操作人和原任务审计保存 }
|
||||
sourceFrom: { type: string, example: '2026-10-11T00:00:00' }
|
||||
sourceUntil: { type: string, example: '2026-10-12T00:00:00' }
|
||||
customerCode: { type: string, maxLength: 64, description: RECHECK 必填 }
|
||||
deliveryNo: { type: string, maxLength: 128, description: RECHECK 必填 }
|
||||
@@ -0,0 +1,700 @@
|
||||
openapi: 3.0.3
|
||||
info:
|
||||
title: 平台自营出库销量库存及采集运行只读接口
|
||||
version: 1.0.0
|
||||
description: >-
|
||||
全部GET要求PLATFORM身份、tenantId=0、非代登录及独立platform:self-operated-analytics:list权限。
|
||||
来源及业务时区Asia/Shanghai,单位PCS,账号和仓库由服务端已配置范围校验。
|
||||
经营查询首屏生成context,包含版本对、独立范围摘要、queryAsOf/queryExpiresAt。
|
||||
后续列表、图表、榜单和库存复用完整上下文,版本0保持不可用,不偷偷补入新版本。
|
||||
上下文最多30分钟且不超过旧销量版superseded_at_utc+7天;queryAsOf不得未来或早于所选版本发布时间。
|
||||
过期/范围不符明确要求刷新整页,不能静默切版;各请求在同一REPEATABLE_READ快照内校验和读取。
|
||||
五周期包含今日,CUSTOM两端包含且endDate不晚于anchorDate;只有CUSTOM接受startDate/endDate。
|
||||
默认maxQueryDays366,粒度DAY。正式outboundQuantity与observedQuantity独立,全部未知仍为空。
|
||||
每日COMPLETE仅证明全天覆盖及有效日行或可靠SKU存在;今日/部分日正式量空,观察量可用,未知日期保持空。
|
||||
SKU区间正式量仅全部日完整才输出;observedQuantity为可靠点合计,完整/部分/未知日数独立。
|
||||
切换图表不改变完整7/30日榜单及30日日均分母;不触发领星请求。
|
||||
运行接口不受经营context限制。动态库存时效、重建和修订待核对独立返回。
|
||||
阶段进度区分ACCOUNT_SHARED/WAREHOUSE及TASK_CUMULATIVE/ATTEMPT_ONLY,不伪造总百分比。
|
||||
total未知为空、计数不能跨PAGE/ORDER/INVENTORY_ROW/BUSINESS_KEY/SKU/BATCH单位求和,NONE为非计数阶段且completed/total为空、totalKnown=false;阶段检查点与心跳分开。
|
||||
任务号稳定,内部诊断ID不作为业务编号回退。SKU订单数不可相加为仓总单数。
|
||||
重试沿既有POST sync-tasks,action=RETRY/requestKey/warehouseCode/taskNo/reason,使用独立sync权限并最终复核资格。
|
||||
security: [{bearerAuth: []}]
|
||||
paths:
|
||||
/api/platform/v1/last-leg/self-operated-analytics/sku-sales-summary:
|
||||
get:
|
||||
summary: SKU五周期或历史累计清单
|
||||
description: '候选为两版profile并集,SQL按选定日期聚合后按observedQuantity降序空值末尾、SKU及货主升序,再分页。未知日不填零。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {$ref: '#/components/parameters/customerCode'}
|
||||
- {$ref: '#/components/parameters/sku'}
|
||||
- {$ref: '#/components/parameters/salesRunId'}
|
||||
- {$ref: '#/components/parameters/inventoryRunId'}
|
||||
- {$ref: '#/components/parameters/salesScopeHash'}
|
||||
- {$ref: '#/components/parameters/inventoryScopeHash'}
|
||||
- {$ref: '#/components/parameters/queryAsOf'}
|
||||
- {$ref: '#/components/parameters/rangePreset'}
|
||||
- {$ref: '#/components/parameters/startDate'}
|
||||
- {$ref: '#/components/parameters/endDate'}
|
||||
- {$ref: '#/components/parameters/bucket'}
|
||||
- {$ref: '#/components/parameters/current'}
|
||||
- {$ref: '#/components/parameters/size'}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/SalesPage'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/sku-daily-sales:
|
||||
get:
|
||||
summary: 精确单SKU日趋势
|
||||
description: 'customerCode和sku必填,精确原始业务键匹配。最多366日且返回完整升序日期轴,不分页。无候选明确业务错误。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {$ref: '#/components/parameters/customerCodeRequired'}
|
||||
- {$ref: '#/components/parameters/skuRequired'}
|
||||
- {$ref: '#/components/parameters/salesRunId'}
|
||||
- {$ref: '#/components/parameters/inventoryRunId'}
|
||||
- {$ref: '#/components/parameters/salesScopeHash'}
|
||||
- {$ref: '#/components/parameters/inventoryScopeHash'}
|
||||
- {$ref: '#/components/parameters/queryAsOf'}
|
||||
- {$ref: '#/components/parameters/rangePreset'}
|
||||
- {$ref: '#/components/parameters/startDate'}
|
||||
- {$ref: '#/components/parameters/endDate'}
|
||||
- {$ref: '#/components/parameters/bucket'}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/Trend'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/hot-skus:
|
||||
get:
|
||||
summary: 完整7/30日热销Top100
|
||||
description: '独立截至queryAsOf昨日的完整窗口,数量大于零,数量降序、SKU单数降序、SKU及货主升序,先Top100再分页;当前缺货仍可入榜。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {$ref: '#/components/parameters/customerCode'}
|
||||
- {$ref: '#/components/parameters/sku'}
|
||||
- {$ref: '#/components/parameters/salesRunId'}
|
||||
- {$ref: '#/components/parameters/inventoryRunId'}
|
||||
- {$ref: '#/components/parameters/salesScopeHash'}
|
||||
- {$ref: '#/components/parameters/inventoryScopeHash'}
|
||||
- {$ref: '#/components/parameters/queryAsOf'}
|
||||
- {$ref: '#/components/parameters/windowDays'}
|
||||
- {$ref: '#/components/parameters/current'}
|
||||
- {$ref: '#/components/parameters/size'}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/MetricPage'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/slow-skus:
|
||||
get:
|
||||
summary: 固定完整30日有库存低出库Top100
|
||||
description: '固定30天,不接受windowDays或rangePreset。正品有效新鲜可售量大于零、完整窗口且起点前可靠存在。数量升序、可售量降序、SKU及货主升序。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {$ref: '#/components/parameters/customerCode'}
|
||||
- {$ref: '#/components/parameters/sku'}
|
||||
- {$ref: '#/components/parameters/salesRunId'}
|
||||
- {$ref: '#/components/parameters/inventoryRunId'}
|
||||
- {$ref: '#/components/parameters/salesScopeHash'}
|
||||
- {$ref: '#/components/parameters/inventoryScopeHash'}
|
||||
- {$ref: '#/components/parameters/queryAsOf'}
|
||||
- {$ref: '#/components/parameters/current'}
|
||||
- {$ref: '#/components/parameters/size'}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/MetricPage'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/inventory-coverage:
|
||||
get:
|
||||
summary: 正品库存与固定30日可售天数
|
||||
description: '固定30天,不接受图表周期。可售仅品质0可用量,不扣冻结或加在途次品。先UNKNOWN/INVALID/STALE,再有效零库存为0,再校验正库存单位、窗口、观察期;零销量天数为空。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/attention'}
|
||||
- {$ref: '#/components/parameters/sortBy'}
|
||||
- {$ref: '#/components/parameters/coverageDaysThreshold'}
|
||||
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {$ref: '#/components/parameters/customerCode'}
|
||||
- {$ref: '#/components/parameters/sku'}
|
||||
- {$ref: '#/components/parameters/salesRunId'}
|
||||
- {$ref: '#/components/parameters/inventoryRunId'}
|
||||
- {$ref: '#/components/parameters/salesScopeHash'}
|
||||
- {$ref: '#/components/parameters/inventoryScopeHash'}
|
||||
- {$ref: '#/components/parameters/queryAsOf'}
|
||||
- {$ref: '#/components/parameters/current'}
|
||||
- {$ref: '#/components/parameters/size'}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/MetricPage'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/sync-overview:
|
||||
get:
|
||||
summary: 各仓任务族运行概览
|
||||
description: 'warehouseCode可选。轻量读取scope/task/run/账号保护。无发布版和OFF仍返回配置任务。首采COMPLETE须正式发布覆盖且无rebuild或未闭合归并。共享上游明确账号共享范围。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCodeOptional'}
|
||||
- {$ref: '#/components/parameters/dataFamily'}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/Overview'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/sync-tasks:
|
||||
get:
|
||||
summary: 本仓逻辑采集任务
|
||||
description: '任务按创建时间及稳定键倒序。首屏返回listUpperCreatedAt/listUpperId,后页完整重传;新插入不挤移页。只读有限检查点,不展开stage或大manifest。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {$ref: '#/components/parameters/dataFamily'}
|
||||
- {$ref: '#/components/parameters/taskType'}
|
||||
- {$ref: '#/components/parameters/status'}
|
||||
- {$ref: '#/components/parameters/taskNo'}
|
||||
- {$ref: '#/components/parameters/dateFrom'}
|
||||
- {$ref: '#/components/parameters/dateUntil'}
|
||||
- {$ref: '#/components/parameters/current'}
|
||||
- {$ref: '#/components/parameters/size'}
|
||||
- {$ref: '#/components/parameters/listUpperCreatedAt'}
|
||||
- {$ref: '#/components/parameters/listUpperId'}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/TaskPage'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/sync-tasks/{taskNo}:
|
||||
get:
|
||||
summary: 本仓业务任务号详情
|
||||
description: '路径taskNo为稳定业务任务号,实际归属与请求账号仓必须一致。不以内部ID回退。详情含最新尝试和关联共享上游。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {name: taskNo, in: path, required: true, schema: {type: string, maxLength: 64}}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/TaskDetail'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/sync-runs:
|
||||
get:
|
||||
summary: 本仓或任务号的尝试历史
|
||||
description: '纯运行元数据分页。当前尝试读同一attemptNo的task进度,终态尝试只读run冻结快照;心跳过期UNCONFIRMED,不自动改判成功失败。 权限platform:self-operated-analytics:list。'
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {$ref: '#/components/parameters/dataFamily'}
|
||||
- {$ref: '#/components/parameters/taskType'}
|
||||
- {$ref: '#/components/parameters/status'}
|
||||
- {$ref: '#/components/parameters/taskNo'}
|
||||
- {$ref: '#/components/parameters/dateFrom'}
|
||||
- {$ref: '#/components/parameters/dateUntil'}
|
||||
- {$ref: '#/components/parameters/current'}
|
||||
- {$ref: '#/components/parameters/size'}
|
||||
- {$ref: '#/components/parameters/listUpperCreatedAt'}
|
||||
- {$ref: '#/components/parameters/listUpperId'}
|
||||
responses:
|
||||
'200':
|
||||
description: '统一ApiResponse,业务失败HTTP200且code非200。'
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/AttemptPage'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/owners:
|
||||
get:
|
||||
summary: 已采集货主编码分页
|
||||
description: 固定同屏版本,只读权限platform:self-operated-analytics:list。不调用外部API。概览不接受SKU/attention/sortBy/分页/图表范围,候选不存在data为空。
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {$ref: '#/components/parameters/salesRunId'}
|
||||
- {$ref: '#/components/parameters/inventoryRunId'}
|
||||
- {$ref: '#/components/parameters/salesScopeHash'}
|
||||
- {$ref: '#/components/parameters/inventoryScopeHash'}
|
||||
- {$ref: '#/components/parameters/queryAsOf'}
|
||||
- {$ref: '#/components/parameters/keyword'}
|
||||
- {$ref: '#/components/parameters/current'}
|
||||
- {$ref: '#/components/parameters/size'}
|
||||
responses:
|
||||
'200':
|
||||
description: 统一ApiResponse
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/OwnerPage'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
/api/platform/v1/last-leg/self-operated-analytics/owner-overview:
|
||||
get:
|
||||
summary: 单货主完整候选30日经营概览
|
||||
description: 固定同屏版本,只读权限platform:self-operated-analytics:list。不调用外部API。概览不接受SKU/attention/sortBy/分页/图表范围,候选不存在data为空。
|
||||
parameters:
|
||||
- {$ref: '#/components/parameters/sourceAccount'}
|
||||
- {$ref: '#/components/parameters/warehouseCode'}
|
||||
- {$ref: '#/components/parameters/salesRunId'}
|
||||
- {$ref: '#/components/parameters/inventoryRunId'}
|
||||
- {$ref: '#/components/parameters/salesScopeHash'}
|
||||
- {$ref: '#/components/parameters/inventoryScopeHash'}
|
||||
- {$ref: '#/components/parameters/queryAsOf'}
|
||||
- {$ref: '#/components/parameters/customerCodeRequired'}
|
||||
- {$ref: '#/components/parameters/coverageDaysThreshold'}
|
||||
responses:
|
||||
'200':
|
||||
description: 统一ApiResponse
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
code: {type: string}
|
||||
message: {type: string}
|
||||
data: {$ref: '#/components/schemas/OwnerOverview'}
|
||||
'401': {description: 缺少可信认证身份}
|
||||
'403': {description: 非平台身份或缺少独立只读权限}
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth: {type: http, scheme: bearer, bearerFormat: JWT}
|
||||
parameters:
|
||||
keyword: {name: keyword, in: query, schema: {type: string, minLength: 1, maxLength: 64}, description: 区分大小写的货主编码字面前缀,先过滤去重再分页}
|
||||
attention: {name: attention, in: query, schema: {type: string, default: ALL, enum: [ALL, NO_OUTBOUND_30D, COVERAGE_GT_THRESHOLD, FROZEN_STOCK, DEFECTIVE_STOCK, UNASSESSABLE]}}
|
||||
sortBy: {name: sortBy, in: query, schema: {type: string, default: AVAILABLE_DESC, enum: [AVAILABLE_DESC, COVERAGE_DAYS_DESC, PHYSICAL_DESC, OUTBOUND_30D_ASC]}, description: 完整候选先筛选后按未舍入值排序分页,未知末尾,同值SKU和货主升序}
|
||||
coverageDaysThreshold: {name: coverageDaysThreshold, in: query, schema: {type: integer, minimum: 1}, description: COVERAGE_GT_THRESHOLD必填,严格大于且未舍入比较,不设置默认经营政策}
|
||||
sourceAccount: {name: sourceAccount, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
warehouseCode: {name: warehouseCode, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
customerCode: {name: customerCode, in: query, required: false, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
sku: {name: sku, in: query, required: false, schema: {type: string, minLength: 1, maxLength: 128}}
|
||||
rangePreset: {name: rangePreset, in: query, required: false, schema: {type: string, enum: [TODAY, LAST_3_DAYS, THIS_WEEK, LAST_15_DAYS, THIS_MONTH, CUSTOM], default: TODAY}}
|
||||
startDate: {name: startDate, in: query, required: false, schema: {type: string, format: date}}
|
||||
endDate: {name: endDate, in: query, required: false, schema: {type: string, format: date}}
|
||||
bucket: {name: bucket, in: query, required: false, schema: {type: string, enum: [DAY], default: DAY}}
|
||||
windowDays: {name: windowDays, in: query, required: false, schema: {type: integer, enum: [7, 30], default: 30}}
|
||||
current: {name: current, in: query, required: false, schema: {type: integer, minimum: 1, default: 1}}
|
||||
size: {name: size, in: query, required: false, schema: {type: integer, minimum: 1, maximum: 100, default: 20}}
|
||||
salesRunId: {name: salesRunId, in: query, required: false, schema: {type: string, pattern: '^[0-9]+$'}}
|
||||
inventoryRunId: {name: inventoryRunId, in: query, required: false, schema: {type: string, pattern: '^[0-9]+$'}}
|
||||
salesScopeHash: {name: salesScopeHash, in: query, required: false, schema: {type: string, pattern: '^[0-9a-f]{64}$'}}
|
||||
inventoryScopeHash: {name: inventoryScopeHash, in: query, required: false, schema: {type: string, pattern: '^[0-9a-f]{64}$'}}
|
||||
queryAsOf: {name: queryAsOf, in: query, required: false, schema: {type: string, format: date-time}}
|
||||
dataFamily: {name: dataFamily, in: query, required: false, schema: {type: string, enum: [OUTBOUND, INVENTORY]}}
|
||||
taskType: {name: taskType, in: query, required: false, schema: {type: string}}
|
||||
status: {name: status, in: query, required: false, schema: {type: string}}
|
||||
taskNo: {name: taskNo, in: query, required: false, schema: {type: string, maxLength: 64}}
|
||||
dateFrom: {name: dateFrom, in: query, required: false, schema: {type: string, format: date}}
|
||||
dateUntil: {name: dateUntil, in: query, required: false, schema: {type: string, format: date}}
|
||||
listUpperCreatedAt: {name: listUpperCreatedAt, in: query, required: false, schema: {type: string, format: date-time}}
|
||||
listUpperId: {name: listUpperId, in: query, required: false, schema: {type: string, pattern: '^[0-9]+$'}}
|
||||
warehouseCodeOptional: {name: warehouseCode, in: query, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
customerCodeRequired: {name: customerCode, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 64}}
|
||||
skuRequired: {name: sku, in: query, required: true, schema: {type: string, minLength: 1, maxLength: 128}}
|
||||
schemas:
|
||||
OwnerOption:
|
||||
type: object
|
||||
properties:
|
||||
customerCode: {type: string}
|
||||
customerName: {type: string, nullable: true}
|
||||
OwnerPage:
|
||||
type: object
|
||||
properties:
|
||||
context: {$ref: '#/components/schemas/Context'}
|
||||
records: {type: array, items: {$ref: '#/components/schemas/OwnerOption'}}
|
||||
current: {type: integer}
|
||||
size: {type: integer}
|
||||
total: {type: string}
|
||||
pages: {type: string}
|
||||
excludedReasons: {type: object, additionalProperties: {type: string}}
|
||||
QuantityTotal:
|
||||
type: object
|
||||
properties:
|
||||
overallTotal: {type: number, nullable: true}
|
||||
knownSubtotal: {type: number, nullable: true}
|
||||
unknownSkuCount: {type: string}
|
||||
dataStatus: {type: string, enum: [COMPLETE, PARTIAL, UNKNOWN]}
|
||||
reasonCodes: {type: array, items: {type: string}}
|
||||
RiskShare:
|
||||
type: object
|
||||
description: 分母为同一OwnerOverview的physicalQuantity。未知时正式命中与比例为空。未设置阈值返回THRESHOLD_NOT_SET。
|
||||
properties:
|
||||
matchedSkuCount: {type: string, nullable: true}
|
||||
matchedPhysicalQuantity: {type: number, nullable: true}
|
||||
physicalQuantityRatio: {type: number, minimum: 0, maximum: 1, nullable: true}
|
||||
knownMatchedSkuCount: {type: string, nullable: true}
|
||||
knownMatchedPhysicalQuantity: {type: number, nullable: true}
|
||||
unassessableSkuCount: {type: string}
|
||||
unassessableKnownPhysicalQuantity: {type: number, nullable: true}
|
||||
reasonCodes: {type: array, items: {type: string}}
|
||||
OwnerOverview:
|
||||
type: object
|
||||
nullable: true
|
||||
properties:
|
||||
context: {$ref: '#/components/schemas/Context'}
|
||||
customerCode: {type: string}
|
||||
customerName: {type: string, nullable: true}
|
||||
skuCount: {type: string, nullable: true}
|
||||
physicalSkuCount: {$ref: '#/components/schemas/QuantityTotal'}
|
||||
physicalQuantity: {$ref: '#/components/schemas/QuantityTotal'}
|
||||
availableQuantity: {$ref: '#/components/schemas/QuantityTotal'}
|
||||
frozenQuantity: {$ref: '#/components/schemas/QuantityTotal'}
|
||||
defectivePhysicalQuantity: {$ref: '#/components/schemas/QuantityTotal'}
|
||||
transitQuantity: {$ref: '#/components/schemas/QuantityTotal'}
|
||||
outboundQuantity30d: {$ref: '#/components/schemas/QuantityTotal'}
|
||||
averageDailyOutboundQuantity: {$ref: '#/components/schemas/QuantityTotal'}
|
||||
noOutbound30d: {$ref: '#/components/schemas/RiskShare'}
|
||||
coverageAboveThreshold: {$ref: '#/components/schemas/RiskShare'}
|
||||
Context:
|
||||
type: object
|
||||
properties:
|
||||
salesRunId: {type: string, nullable: true}
|
||||
inventoryRunId: {type: string, nullable: true}
|
||||
salesScopeHash: {type: string, nullable: true}
|
||||
inventoryScopeHash: {type: string, nullable: true}
|
||||
queryAsOf: {type: string, format: date-time, nullable: true}
|
||||
queryExpiresAt: {type: string, format: date-time, nullable: true}
|
||||
businessTimezone: {type: string, nullable: true}
|
||||
anchorDate: {type: string, format: date, nullable: true}
|
||||
rangeStartDate: {type: string, format: date, nullable: true}
|
||||
rangeEndDateExclusive: {type: string, format: date, nullable: true}
|
||||
calculationWindowDays: {type: integer, nullable: true}
|
||||
completeDayFrom: {type: string, format: date, nullable: true}
|
||||
completeDayUntil: {type: string, format: date, nullable: true}
|
||||
salesCoveredFrom: {type: string, format: date-time, nullable: true}
|
||||
salesCoveredUntil: {type: string, format: date-time, nullable: true}
|
||||
salesPublishedAt: {type: string, format: date-time, nullable: true}
|
||||
inventoryObservedFrom: {type: string, format: date-time, nullable: true}
|
||||
inventoryObservedUntil: {type: string, format: date-time, nullable: true}
|
||||
salesStatus: {type: string, nullable: true}
|
||||
inventoryStatus: {type: string, nullable: true}
|
||||
rebuildRequired: {type: boolean, nullable: true}
|
||||
revisionReviewStatus: {type: string, nullable: true}
|
||||
reasonCodes: {type: array, items: {type: string}}
|
||||
SalesSummary:
|
||||
type: object
|
||||
properties:
|
||||
sourceAccount: {type: string, nullable: true}
|
||||
warehouseCode: {type: string, nullable: true}
|
||||
customerCode: {type: string, nullable: true}
|
||||
sku: {type: string, nullable: true}
|
||||
productName: {type: string, nullable: true}
|
||||
quantityUnit: {type: string, nullable: true}
|
||||
outboundQuantity: {type: number, nullable: true}
|
||||
observedQuantity: {type: number, nullable: true}
|
||||
dataStatus: {type: string, nullable: true}
|
||||
reasonCodes: {type: array, items: {type: string}}
|
||||
completeDayCount: {type: integer, nullable: true}
|
||||
partialDayCount: {type: integer, nullable: true}
|
||||
unknownDayCount: {type: integer, nullable: true}
|
||||
Point:
|
||||
type: object
|
||||
properties:
|
||||
businessDate: {type: string, format: date, nullable: true}
|
||||
outboundQuantity: {type: number, nullable: true}
|
||||
observedQuantity: {type: number, nullable: true}
|
||||
dataStatus: {type: string, nullable: true}
|
||||
reasonCodes: {type: array, items: {type: string}}
|
||||
quantityUnit: {type: string, nullable: true}
|
||||
coveredFrom: {type: string, format: date-time, nullable: true}
|
||||
coveredUntil: {type: string, format: date-time, nullable: true}
|
||||
Trend:
|
||||
type: object
|
||||
properties:
|
||||
context: {$ref: '#/components/schemas/Context'}
|
||||
summary: {$ref: '#/components/schemas/SalesSummary'}
|
||||
points: {type: array, items: {$ref: '#/components/schemas/Point'}}
|
||||
Metric:
|
||||
type: object
|
||||
properties:
|
||||
customerName: {type: string, nullable: true}
|
||||
defectivePhysicalQuantity: {type: number, nullable: true}
|
||||
outboundQuantity30d: {type: number, nullable: true}
|
||||
lastObservedOutboundDate: {type: string, format: date, nullable: true}
|
||||
observedHistoryStartDate: {type: string, format: date, nullable: true}
|
||||
attentionReasons: {type: array, items: {type: string}}
|
||||
quantityStatuses: {type: object, additionalProperties: {type: string, enum: [VALID, UNKNOWN, STALE]}}
|
||||
sourceAccount: {type: string, nullable: true}
|
||||
customerCode: {type: string, nullable: true}
|
||||
warehouseCode: {type: string, nullable: true}
|
||||
sku: {type: string, nullable: true}
|
||||
productName: {type: string, nullable: true}
|
||||
quantityUnit: {type: string, nullable: true}
|
||||
outboundQuantity: {type: number, nullable: true}
|
||||
skuOutboundOrderCount: {type: string, nullable: true}
|
||||
todayObservedQuantity: {type: number, nullable: true}
|
||||
physicalQuantity: {type: number, nullable: true}
|
||||
availableQuantity: {type: number, nullable: true}
|
||||
frozenQuantity: {type: number, nullable: true}
|
||||
transitQuantity: {type: number, nullable: true}
|
||||
inventoryObservedAt: {type: string, format: date-time, nullable: true}
|
||||
averageDailyOutboundQuantity: {type: number, nullable: true}
|
||||
inventoryCoverageDays: {type: number, nullable: true}
|
||||
inventoryQuality: {type: string, nullable: true}
|
||||
salesCoverage: {type: string, nullable: true}
|
||||
observationEligible: {type: boolean, nullable: true}
|
||||
earliestReliableEvidenceAt: {type: string, format: date-time, nullable: true}
|
||||
status: {type: string, nullable: true}
|
||||
reasonCodes: {type: array, items: {type: string}}
|
||||
Protection:
|
||||
type: object
|
||||
properties:
|
||||
accountCooldownUntil: {type: string, format: date-time, nullable: true}
|
||||
accountPauseReason: {type: string, nullable: true}
|
||||
dailyRequestBudget: {type: integer, nullable: true}
|
||||
reservedHttpRequests: {type: string, nullable: true}
|
||||
confirmedHttpRequests: {type: string, nullable: true}
|
||||
budgetDate: {type: string, format: date, nullable: true}
|
||||
Validation:
|
||||
type: object
|
||||
properties:
|
||||
validationSessionNo: {type: string, nullable: true}
|
||||
budgetLimits: {type: object, additionalProperties: {type: string, nullable: true}}
|
||||
budgetConsumed: {type: object, additionalProperties: {type: string, nullable: true}}
|
||||
deadlineAt: {type: string, format: date-time, nullable: true}
|
||||
stopReason: {type: string, nullable: true}
|
||||
Attempt:
|
||||
type: object
|
||||
properties:
|
||||
runId: {type: string, nullable: true}
|
||||
taskNo: {type: string, nullable: true}
|
||||
attemptNo: {type: integer, nullable: true}
|
||||
status: {type: string, nullable: true}
|
||||
phase: {type: string, nullable: true}
|
||||
executionPurpose: {type: string, nullable: true}
|
||||
startedAt: {type: string, format: date-time, nullable: true}
|
||||
finishedAt: {type: string, format: date-time, nullable: true}
|
||||
phaseStartedAt: {type: string, format: date-time, nullable: true}
|
||||
progressUpdatedAt: {type: string, format: date-time, nullable: true}
|
||||
heartbeatAt: {type: string, format: date-time, nullable: true}
|
||||
executionHealth: {type: string, nullable: true}
|
||||
elapsedSeconds: {type: string, nullable: true}
|
||||
errorCode: {type: string, nullable: true}
|
||||
failureSummary: {type: string, nullable: true}
|
||||
retryable: {type: boolean, nullable: true}
|
||||
coverageStatus: {type: string, nullable: true}
|
||||
coveredFrom: {type: string, format: date-time, nullable: true}
|
||||
coveredUntil: {type: string, format: date-time, nullable: true}
|
||||
publishedAt: {type: string, format: date-time, nullable: true}
|
||||
progress: {$ref: '#/components/schemas/Progress'}
|
||||
Task:
|
||||
type: object
|
||||
properties:
|
||||
taskNo: {type: string, nullable: true}
|
||||
taskType: {type: string, nullable: true}
|
||||
dataFamily: {type: string, nullable: true}
|
||||
warehouseCode: {type: string, nullable: true}
|
||||
taskRole: {type: string, nullable: true}
|
||||
executionPurpose: {type: string, nullable: true}
|
||||
queryFrom: {type: string, format: date-time, nullable: true}
|
||||
queryUntil: {type: string, format: date-time, nullable: true}
|
||||
taskStatus: {type: string, nullable: true}
|
||||
applyState: {type: string, nullable: true}
|
||||
attemptCount: {type: integer, nullable: true}
|
||||
latestAttemptNo: {type: integer, nullable: true}
|
||||
resultPublicationState: {type: string, nullable: true}
|
||||
resultPublishedRunId: {type: string, nullable: true}
|
||||
nextRetryAt: {type: string, format: date-time, nullable: true}
|
||||
allowedActions: {type: array, items: {type: string}}
|
||||
actionBlockReason: {type: string, nullable: true}
|
||||
progressUpdatedAt: {type: string, format: date-time, nullable: true}
|
||||
progress: {$ref: '#/components/schemas/Progress'}
|
||||
validation: {$ref: '#/components/schemas/Validation'}
|
||||
latestAttempt: {$ref: '#/components/schemas/Attempt'}
|
||||
TaskDetail:
|
||||
type: object
|
||||
properties:
|
||||
task: {$ref: '#/components/schemas/Task'}
|
||||
sharedUpstream: {$ref: '#/components/schemas/Task'}
|
||||
protection: {$ref: '#/components/schemas/Protection'}
|
||||
observedAt: {type: string, format: date-time, nullable: true}
|
||||
InventoryDailySamples:
|
||||
type: object
|
||||
nullable: true
|
||||
description: 仅库存任务族提供。北京时间近30个完整日的正式日代表积累;缺日不补零或沿用旧批次,不是周转率。
|
||||
required: [windowFrom, windowUntil, expectedDays, sampleCount, missingDates]
|
||||
properties:
|
||||
windowFrom: {type: string, format: date, description: 包含起日}
|
||||
windowUntil: {type: string, format: date, description: 排他上界,即北京时间今日}
|
||||
expectedDays: {type: integer, enum: [30]}
|
||||
sampleCount: {type: integer, minimum: 0, maximum: 30}
|
||||
missingDates: {type: array, items: {type: string, format: date}}
|
||||
accumulationStartedOn: {type: string, format: date, nullable: true, description: 本仓最早正式日代表日期,无样本时为空}
|
||||
Warehouse:
|
||||
type: object
|
||||
properties:
|
||||
warehouseCode: {type: string, nullable: true}
|
||||
warehouseName: {type: string, nullable: true}
|
||||
dataFamily: {type: string, nullable: true}
|
||||
executionEnabled: {type: boolean, nullable: true}
|
||||
publicationEnabled: {type: boolean, nullable: true}
|
||||
disabledReason: {type: string, nullable: true}
|
||||
nextScheduledAt: {type: string, format: date-time, nullable: true}
|
||||
observedAt: {type: string, format: date-time, nullable: true}
|
||||
initialFrom: {type: string, format: date-time, nullable: true}
|
||||
initialUntil: {type: string, format: date-time, nullable: true}
|
||||
initialCoverageStatus: {type: string, nullable: true}
|
||||
salesCoveredFrom: {type: string, format: date-time, nullable: true}
|
||||
salesCoveredUntil: {type: string, format: date-time, nullable: true}
|
||||
lastSuccessfulTaskNo: {type: string, nullable: true}
|
||||
lastSucceededAt: {type: string, format: date-time, nullable: true}
|
||||
lastPublishedAt: {type: string, format: date-time, nullable: true}
|
||||
inventoryObservedFrom: {type: string, format: date-time, nullable: true}
|
||||
inventoryObservedUntil: {type: string, format: date-time, nullable: true}
|
||||
dataFreshness: {type: string, nullable: true}
|
||||
rebuildRequired: {type: boolean, nullable: true}
|
||||
revisionReviewStatus: {type: string, nullable: true}
|
||||
inventoryDailySamples: {$ref: '#/components/schemas/InventoryDailySamples'}
|
||||
currentTask: {$ref: '#/components/schemas/Task'}
|
||||
sharedUpstream: {$ref: '#/components/schemas/Task'}
|
||||
protection: {$ref: '#/components/schemas/Protection'}
|
||||
Overview:
|
||||
type: object
|
||||
properties:
|
||||
sourceAccount: {type: string, nullable: true}
|
||||
environmentLabel: {type: string, nullable: true}
|
||||
collectionMode: {type: string, nullable: true}
|
||||
observedAt: {type: string, format: date-time, nullable: true}
|
||||
warehouses: {type: array, items: {$ref: '#/components/schemas/Warehouse'}}
|
||||
Progress:
|
||||
type: object
|
||||
properties:
|
||||
progressScope: {type: string, nullable: true}
|
||||
countBasis: {type: string, nullable: true}
|
||||
attemptNo: {type: string, nullable: true}
|
||||
scanRound: {type: string, nullable: true}
|
||||
phase: {type: string, nullable: true}
|
||||
completed: {type: string, nullable: true}
|
||||
total: {type: string, nullable: true}
|
||||
totalKnown: {type: boolean, nullable: true}
|
||||
unit: {type: string, nullable: true}
|
||||
sliceFrom: {type: string, format: date-time, nullable: true}
|
||||
sliceUntil: {type: string, format: date-time, nullable: true}
|
||||
stageStartedAt: {type: string, format: date-time, nullable: true}
|
||||
stageFinishedAt: {type: string, format: date-time, nullable: true}
|
||||
validationState: {type: string, nullable: true}
|
||||
invalidCount: {type: string, nullable: true}
|
||||
unknownCount: {type: string, nullable: true}
|
||||
pendingReviewCount: {type: string, nullable: true}
|
||||
countUnit: {type: string, nullable: true}
|
||||
summaryAsOf: {type: string, format: date-time, nullable: true}
|
||||
directoryComplete: {type: boolean, nullable: true}
|
||||
stages: {type: array, items: {$ref: '#/components/schemas/Progress'}}
|
||||
SalesPage:
|
||||
type: object
|
||||
properties:
|
||||
context: {$ref: '#/components/schemas/Context'}
|
||||
records: {type: array, items: {$ref: '#/components/schemas/SalesSummary'}}
|
||||
current: {type: integer, nullable: true}
|
||||
size: {type: integer, nullable: true}
|
||||
total: {type: string, nullable: true}
|
||||
pages: {type: string, nullable: true}
|
||||
excludedReasons: {type: object, additionalProperties: {type: string, nullable: true}}
|
||||
MetricPage:
|
||||
type: object
|
||||
properties:
|
||||
context: {$ref: '#/components/schemas/Context'}
|
||||
records: {type: array, items: {$ref: '#/components/schemas/Metric'}}
|
||||
current: {type: integer, nullable: true}
|
||||
size: {type: integer, nullable: true}
|
||||
total: {type: string, nullable: true}
|
||||
pages: {type: string, nullable: true}
|
||||
excludedReasons: {type: object, additionalProperties: {type: string, nullable: true}}
|
||||
TaskPage:
|
||||
type: object
|
||||
properties:
|
||||
records: {type: array, items: {$ref: '#/components/schemas/Task'}}
|
||||
current: {type: integer, nullable: true}
|
||||
size: {type: integer, nullable: true}
|
||||
total: {type: string, nullable: true}
|
||||
listUpperCreatedAt: {type: string, format: date-time, nullable: true}
|
||||
listUpperId: {type: string, nullable: true}
|
||||
observedAt: {type: string, format: date-time, nullable: true}
|
||||
AttemptPage:
|
||||
type: object
|
||||
properties:
|
||||
records: {type: array, items: {$ref: '#/components/schemas/Attempt'}}
|
||||
current: {type: integer, nullable: true}
|
||||
size: {type: integer, nullable: true}
|
||||
total: {type: string, nullable: true}
|
||||
listUpperCreatedAt: {type: string, format: date-time, nullable: true}
|
||||
listUpperId: {type: string, nullable: true}
|
||||
observedAt: {type: string, format: date-time, nullable: true}
|
||||
Reference in New Issue
Block a user