7.9 KiB
7.9 KiB
Supply-Intelligence 生产上线 P0/P1/P2 收敛板(2026-05-08)
状态:当前有效
仓库:/home/long/project/立交桥/projects/supply-intelligence
目标:把当前已完成的 B2/B3/B4 实现闭环,继续推进到“可生产上线判定”所需的最小生产门禁。
0. 当前结论
当前结论:REQUEST_CHANGES
已完成事实:
- publish 已不再只是 event append;已驱动 candidate
test_passed -> published、packagedraft -> active - admission-state 已能反映 publish 后组合态以及 ack 后 gateway_sync_status 变化
- 相关 targeted tests 已通过:
go test ./internal/publish ./internal/httpapi ./internal/app ./internal/repository
仍不能宣称可生产上线的原因:
- PostgreSQL 持久化路径与内存仓储语义未收敛,当前 publish 主链路缺少数据库事务/并发保护证据
- 发布幂等、重复发布、冲突发布、ack 重放/乱序等生产失败路径证据不足
- 缺少基于 PostgreSQL 的真实端到端链路验证与上线证据包
1. 已复核事实基线
1.1 代码级事实
internal/publish/service.go已存在PublishDraft(ctx, PublishDraftInput)主入口internal/httpapi/server.go的/internal/supply-intelligence/publish/package-event已切到真实发布语义internal/httpapi/admission_state_api_test.go已验证 publish 后published + active + pending以及 ack 后appliedinternal/gatewayconsumer/service.go已具备最小consume-once -> ack -> snapshot路径
1.2 当前生产差距(实测/读码得出)
internal/repository/postgres.goAppendPackageEventContext()仍是ON CONFLICT (event_id) DO NOTHING,但上层未把冲突解释为幂等成功/重复请求拒绝的明确产品语义UpdateCandidateStatus()、UpsertSupplyPackage()、AppendPackageEventContext()彼此独立执行,未处于同一数据库事务- 全文件未见
Begin/Commit/Rollback/FOR UPDATE,说明 publish 主链路当前没有 PostgreSQL 事务级一致性保护
- 目前通过的测试主要基于内存仓储;尚未看到 PostgreSQL 集成测试证明:
- 并发双发布只会成功一次
- 重复 event_id 的幂等语义稳定
- package/candidate/event 在异常中不会出现部分提交
- 仓库虽已有
docker-compose.yml、migrations/、internal/repository/postgres.go,但未形成 production gate 所需的真实 E2E 证据链
2. 分级任务板
P0. 生产阻塞项(不上这些,不能判定可上线)
P0-1. PostgreSQL 发布事务原子化
- Owner:Engineer
- 目标:把 publish 主链路收敛为单事务提交,而不是多次独立写入
- 代码落点:
internal/repository/interfaces.gointernal/repository/postgres.gointernal/publish/service.go- 可能新增
internal/repository/postgres_publish_tx_test.go
- 必须达成:
- candidate 状态更新、package 状态更新、event append 在同一 DB 事务中完成
- 任一步失败时整体回滚
- 明确重复 publish 的返回语义(幂等成功或冲突失败,必须固定)
- 验证:
go test ./internal/publish ./internal/repository- 至少一条 PostgreSQL 集成测试证明回滚语义
- 当前状态:completed —
PostgresRepository.PublishPackageAtomically已实现BEGIN/UPDATE/UPSERT/INSERT/COMMIT,TestPostgresPublishPackageAtomicallyRollsBackOnDuplicateEvent通过
P0-2. 重复发布/并发发布保护
- Owner:Engineer
- 目标:防止同一
platform+model或同一 draft package 被重复发布 - 代码落点:
internal/publish/service.gointernal/repository/postgres.gointernal/repository/memory.go- 相关
*_test.go
- 必须达成:
- candidate 已
published或 package 已active时再次发布,有明确拒绝/幂等语义 - 并发双发布测试下,最终只能有一个成功结果
- event 不可重复污染 downstream queue
- candidate 已
- 验证:
- 并发测试 / 重复调用测试通过
- 当前状态:completed — 已补充
TestPostgresPublishPackageAtomicallyConcurrentDoublePublish,验证并发双发布时仅一个成功、无脏数据
P0-3. PostgreSQL 真实链路 E2E
- Owner:QA
- 目标:在 PostgreSQL 环境下验证最小生产主链路
- 链路:candidate -> admission(test_passed) -> publish -> package-changes -> consume-once -> ack -> admission-state
- 代码/资产落点:
- 现有
docker-compose.yml migrations/- 新增
internal/...PostgreSQL 集成测试或scripts/验证脚本
- 现有
- 必须达成:
- 不是仅
go test ./...,而是真实 PostgreSQL 状态可读回 - admission-state 能反映 pending/applied/failed
- gateway snapshot 与 event ack 状态一致
- 不是仅
- 验证:
- 可复现命令 + 实际输出
- 当前状态:completed —
TestPostgresE2EPublishConsumeAckAdmissionState已覆盖完整链路,TestPostgresE2EPublishConsumeAckAdmissionStateRequiresAuthorizedConsumer验证未授权消费过滤
P1. 上线前必须补齐项(P0 完成后,仍建议上线前补齐)
P1-1. 失败补偿与错误语义收敛
- Owner:TechLead -> Engineer
- 目标:补明确的失败模型,而不是只靠 internal_error
- 范围:
- 发布冲突
- event 已存在
- ack 重放
- ack 目标不存在
- consumer apply failed 的重试/终态语义
- 交付:错误码/状态机/handler 响应语义收敛
- 验证:针对失败路径的 HTTP/API 测试
- 当前状态:completed — 已有明确错误码(
ErrInvalidPublishInput/ErrCandidateNotPublishable/ErrPackageNotPublishable/ErrDuplicatePublishRequest/ErrPackageAlreadyPublished)、重试策略(1m/5m/15m,最多2次)、终态定义(applied/pending/failed),consumer 测试覆盖所有失败路径
P1-2. gateway consumer 生产约束验证
- Owner:QA
- 目标:验证 gateway 侧不是“最小骨架可跑”,而是生产语义可解释
- 必查:
- 未授权 account 过滤
- pending-only 消费
- apply failed 后状态可见
- snapshot 与 event ack 不漂移
- 验证:definition -> assembly -> call -> entry 四层核查 + targeted tests
- 当前状态:completed —
TestServiceConsumeOnceSkipsUnauthorizedEvents、TestPostgresE2EPublishConsumeAckAdmissionStateRequiresAuthorizedConsumer、TestServiceConsumeOnceFailedDoesNotDriftSnapshot等已覆盖
P1-3. 上线证据包
- Owner:XL
- 目标:形成真正可用于上线判定的证据包
- 必须包含:
- 通过命令
- 覆盖的关键链路
- 明确未覆盖项
- 可宣称项 / 不可宣称项
- 回滚方式
- 当前状态:completed — 已归档
reports/production/SHARED_ENV_EVIDENCE_RUN_2026-05-09.md及 tksea 版本,含 G1-G3 证据
P2. 可上线后补项(不阻塞首版上线判定)
P2-1. actor / 审批链 / 审计增强
- Owner:PM -> TechLead -> Engineer
- 说明:当前 publish 语义可先无完整审批产品化,但上线后应补 actor、审批来源、审计追踪
- 当前状态:pending
P2-2. 真实远端 gateway 集成
- Owner:DevOps/Engineer
- 说明:当前
consume-once仍偏本地 apply/ack 语义,后续应补真实下游系统契约 - 当前状态:conditional_debt — 首版上线允许携带,必须在第一个迭代周期内补清(建议 2 周内)
P2-3. 观测与运行基线
- Owner:DevOps
- 说明:补指标、告警、日志字段、发布/ack 异常观测面
- 当前状态:pending
3. 推荐执行顺序
- P0-1 PostgreSQL 发布事务原子化
- P0-2 重复发布/并发发布保护
- P0-3 PostgreSQL 真实链路 E2E
- P1-1 / P1-2
- P1-3 上线证据包
4. 明确禁止的错误结论
- 不得把内存仓储测试通过等同于 PostgreSQL 生产可用
- 不得把
published等同于gateway applied - 不得把
ON CONFLICT DO NOTHING视为已完成幂等设计 - 不得把缺少事务保护的多次独立写入视为“发布事务已完成”
- 不得在缺少 PostgreSQL E2E 证据时宣称可上线