Files
supply-intelligence/tech/B2_B3_B4_IMPLEMENTATION_SPEC_2026-05-07.md
2026-05-12 18:49:52 +08:00

5.2 KiB
Raw Blame History

B2/B3/B4 实施规格2026-05-07

状态:当前有效 范围candidate 状态收敛、publish 事务闭环、admission-state API 真正接线 真源:

  • tech/CURRENT_SOURCE_OF_TRUTH_2026-05.md
  • tech/BASELINE_TECHLEAD_V2.md
  • tech/GATEWAY_CONSUMER_DECISION_2026-05.md

1. 目标

把 supply-intelligence 从“各子模块最小骨架存在”推进到“candidate -> admission -> draft package -> publish -> gateway sync state -> admission-state 查询”这一条真实生产闭环更接近可验状态。

本轮不扩范围到独立平台化、重基础设施、自动注册,只做当前收口板 B2/B3/B4。

2. 当前已验证现状

  1. go test ./... 当前通过。
  2. internal/domain/types.go 中 candidate 状态枚举已不包含 pending_admission / admitted
  3. internal/httpapi/server.goparseDiscoveryCandidateStatus() 已只接受:
    • discovered
    • testing
    • test_passed
    • test_failed
    • retry_pending
    • ignored
    • published
    • deprecated
    • closed
  4. internal/httpapi/server.go 已存在 /internal/supply-intelligence/models/{platform}/{model}/admission-state 路由与 handler。
  5. internal/publish/service.go 目前只支持“追加 package published event”还不是“运营确认上架事务”。
  6. internal/admission/service.go 在测试通过后会创建/更新 draft package并把 candidate 置为 test_passed
  7. internal/httpapi/admission_state_api_test.go 目前只验证 candidate/package/event 聚合读取,不验证真实 publish 事务。

3. 本轮必须收敛的缺口

B2. candidate 状态与 admission 流转

必须满足:

  • admission 只允许 discovered / retry_pending 进入执行。
  • admission 执行开始后置为 testing
  • admission 失败后置为 test_failedretry_pending(本轮沿用现状失败归 test_failed)。
  • admission 成功后置为 test_passed
  • publish 成功后 candidate 必须从 test_passed -> published
  • 不允许重新引入旧状态口径。

B3. publish 事务闭环

必须新增真实语义:

  • 输入不再只是 event append 所需字段。
  • platform + model(必要时 package/candidate为主键读取当前真实状态。
  • 仅当 candidate 最新状态为 test_passed 且 package 当前为 draft 时允许发布。
  • 发布动作要同时完成:
    1. package draft -> active
    2. candidate test_passed -> published
    3. 追加 supply_package_published event默认 gateway_sync_status=pending
  • 明确 published != appliedgateway applied 仍由 ack 驱动。

B4. admission-state API

必须返回当前组合真相:

  • latest candidate truth
  • current package truth
  • latest matching package event truth
  • gateway sync status

并在 publish 事务跑完后能够体现:

  • candidate_status = published
  • package_status = active
  • gateway_sync_status = pending直到 ack

4. 最小改动设计

4.1 repository / app 适配层

尽量不改 repository 主接口的大结构,只补 publish service 所需最小能力,优先复用已有:

  • GetLatestDiscoveryCandidateContext()
  • GetSupplyPackage()
  • UpsertSupplyPackage()
  • UpdateCandidateStatus()
  • AppendPackageEventContext()

如 publish 包直接依赖 domain/repository 成本更低,可在 publish 内定义更完整 repo interface再由现有 repository.Repository 满足。

4.2 publish service 新增主入口

建议新增:

  • PublishDraft(ctx, PublishDraftInput) (PublishDraftOutput, error)

输入最小字段:

  • event_id
  • platform
  • model
  • actor/source可选本轮如无真实审计先留空
  • occurred_at可选

输出最小字段:

  • candidate
  • package
  • event
  • gateway_sync_status

保留 RecordPackagePublished() 兼容测试/已有接口,但 HTTP 主入口要逐步切换为真正发布语义,而不是“外部直接塞 event”。

4.3 HTTP API

当前 /internal/supply-intelligence/publish/package-event 若继续存在,本轮将其语义提升为“确认发布 draft package”不再允许脱离 candidate/package 真相直接伪造 event。

请求体建议最小化为:

  • event_id
  • platform
  • model
  • occurred_at

如果保留 package_id/version 也应以服务端真相为准,不信任调用方覆盖 package 当前状态。

5. 验证标准

必须新增/更新测试覆盖:

  1. publish 成功:
  • candidate test_passed -> published
  • package draft -> active
  • event appended with pending sync
  1. publish 拒绝:
  • candidate 不是 test_passed 时拒绝
  • package 不是 draft 时拒绝
  • candidate/package 不存在时拒绝
  1. admission-state
  • publish 后查询可看到 published + active + pending
  • ack 后查询可看到 applied/failed
  1. 全量验证:
  • go test ./...

6. 不做项

本轮明确不做:

  • 审计表完整补齐
  • actor/审批链完整产品化
  • DB 事务级锁语义重构
  • gateway 实际远端集成
  • auto-supply / deep registration

7. 完成定义

仅当以下同时成立B2/B3/B4 才能算完成:

  • 代码不再只有“event append 记录器”语义
  • publish 真正驱动 candidate/package 状态变化
  • admission-state 能反映 publish 后组合真相
  • 新增测试通过
  • go test ./... 通过