161 lines
7.9 KiB
Markdown
161 lines
7.9 KiB
Markdown
|
|
# 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`、package `draft -> 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 后 `applied`
|
|||
|
|
- `internal/gatewayconsumer/service.go` 已具备最小 `consume-once -> ack -> snapshot` 路径
|
|||
|
|
|
|||
|
|
### 1.2 当前生产差距(实测/读码得出)
|
|||
|
|
1. `internal/repository/postgres.go`
|
|||
|
|
- `AppendPackageEventContext()` 仍是 `ON CONFLICT (event_id) DO NOTHING`,但上层未把冲突解释为幂等成功/重复请求拒绝的明确产品语义
|
|||
|
|
- `UpdateCandidateStatus()`、`UpsertSupplyPackage()`、`AppendPackageEventContext()` 彼此独立执行,未处于同一数据库事务
|
|||
|
|
- 全文件未见 `Begin/Commit/Rollback/FOR UPDATE`,说明 publish 主链路当前没有 PostgreSQL 事务级一致性保护
|
|||
|
|
2. 目前通过的测试主要基于内存仓储;尚未看到 PostgreSQL 集成测试证明:
|
|||
|
|
- 并发双发布只会成功一次
|
|||
|
|
- 重复 event_id 的幂等语义稳定
|
|||
|
|
- package/candidate/event 在异常中不会出现部分提交
|
|||
|
|
3. 仓库虽已有 `docker-compose.yml`、`migrations/`、`internal/repository/postgres.go`,但未形成 production gate 所需的真实 E2E 证据链
|
|||
|
|
|
|||
|
|
## 2. 分级任务板
|
|||
|
|
|
|||
|
|
## P0. 生产阻塞项(不上这些,不能判定可上线)
|
|||
|
|
|
|||
|
|
### P0-1. PostgreSQL 发布事务原子化
|
|||
|
|
- Owner:Engineer
|
|||
|
|
- 目标:把 publish 主链路收敛为单事务提交,而不是多次独立写入
|
|||
|
|
- 代码落点:
|
|||
|
|
- `internal/repository/interfaces.go`
|
|||
|
|
- `internal/repository/postgres.go`
|
|||
|
|
- `internal/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.go`
|
|||
|
|
- `internal/repository/postgres.go`
|
|||
|
|
- `internal/repository/memory.go`
|
|||
|
|
- 相关 `*_test.go`
|
|||
|
|
- 必须达成:
|
|||
|
|
- candidate 已 `published` 或 package 已 `active` 时再次发布,有明确拒绝/幂等语义
|
|||
|
|
- 并发双发布测试下,最终只能有一个成功结果
|
|||
|
|
- event 不可重复污染 downstream queue
|
|||
|
|
- 验证:
|
|||
|
|
- 并发测试 / 重复调用测试通过
|
|||
|
|
- 当前状态:**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. 推荐执行顺序
|
|||
|
|
1. P0-1 PostgreSQL 发布事务原子化
|
|||
|
|
2. P0-2 重复发布/并发发布保护
|
|||
|
|
3. P0-3 PostgreSQL 真实链路 E2E
|
|||
|
|
4. P1-1 / P1-2
|
|||
|
|
5. P1-3 上线证据包
|
|||
|
|
|
|||
|
|
## 4. 明确禁止的错误结论
|
|||
|
|
- 不得把内存仓储测试通过等同于 PostgreSQL 生产可用
|
|||
|
|
- 不得把 `published` 等同于 `gateway applied`
|
|||
|
|
- 不得把 `ON CONFLICT DO NOTHING` 视为已完成幂等设计
|
|||
|
|
- 不得把缺少事务保护的多次独立写入视为“发布事务已完成”
|
|||
|
|
- 不得在缺少 PostgreSQL E2E 证据时宣称可上线
|