Files
junhong_cmp_fiber/.scratch/tech-global-audit/审计覆盖基线.md
break 5c4d17e9fc
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
收口七月卡状态回调与系列授权兼容契约
完成运营商实名回调、业务事件观测序列与受控配置装配,同时恢复 UR43 已交付的 packages[].remove 字段及旧响应兼容,统一更新 OpenSpec、OpenAPI 和交付文档。

Constraint: 七月测试环境里程碑不新增或运行自动化测试

Rejected: 以必填 operation_type 替换 packages[].remove | 会破坏已交付前端契约

Confidence: high

Scope-risk: broad

Directive: 后续修改系列套餐管理接口必须保持 packages[].remove 和 ShopSeriesGrantResponse 兼容

Tested: go run ./cmd/gendocs;go build -buildvcs=false ./...;openspec validate complete-july-iteration-test-release --strict;git diff --check

Not-tested: 按本 Change 约定未运行 go test,真实运营商与 Gateway 联调延期
2026-07-24 19:59:24 +08:00

80 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 全系统审计覆盖基线
状态:源码扫描与自动分类已完成,待业务、研发和安全三方评审确认
## 可复核制品
- 显式逐入口清单:[`审计覆盖清单.json`](审计覆盖清单.json),当前共 490 项。
- 扫描范围270 个 HTTP RouteSpec、24 个 Asynq Worker、4 个定时任务、3 个 Application 公共写入口、189 个旧 Service 公共写入口。
- 生成入口:`go run ./cmd/audit-coverage`
- 发布门禁:`go test ./internal/governance/auditcoverage`。源码新增、删除或修改入口后,若未同步更新显式清单,测试必定失败。
- 每项均固定代码入口、业务所有者、中文摘要以及待评审的 Audit Event / Domain Ledger / Integration Log / Outbox 分类候选,并预留动作、风险、资源、操作者来源、事务边界、失败策略、前后数据、敏感策略和确认测试接缝。
- 当前 `Audit Event=N/A` 候选均填写逐入口理由;评审前不能据此宣称全系统分类已经确认。
生成器只负责产生待评审候选,不能自行代表评审通过。更新清单时必须核对业务语义,不能仅运行生成命令后直接提交。
## 分类边界
| 入口类型 | Audit Event | Domain Ledger | Integration Log | Outbox |
|---|---|---|---|---|
| 状态变更、资金、权限、关键配置 | 必须;关键成功与业务事实同事务 | 既有业务表仍是权威 | 存在外部调用时必须 | 存在提交后可靠副作用时必须 |
| 失败、拒绝 | 业务回滚后独立短事务 | 不伪造领域事实 | 外部尝试仍记录真实结果 | 不为已回滚事实制造事件 |
| 普通读取 | N/A逐项记录理由 | 只读投影 | N/A | N/A |
| 敏感读取、下载和导出 | 返回敏感结果前必须,自审计失败则不返回 | 业务数据仍是权威 | N/A | 异步导出按任务契约决定 |
| 外部回调、轮询和 Gateway 调用 | 状态变化、人工触发、连续失败或高风险异常时必须 | 业务状态仍在领域表 | 每次实际或未发送尝试都必须 | 需要可靠后续处理时必须 |
| Domain 方法 | 不直接依赖审计基础设施,由 Application 写入 | 维护业务不变量 | 由 Application/Adapter 负责 | 只记录领域事件,由 Application 持久化 |
## 七月测试环境冻结期增量登记
`complete-july-iteration-test-release` 已明确把 Audit Event Writer 与发布门禁延期到任务 6.5。以下登记仅说明测试环境阶段的临时分类不代表生产评审通过也不得删除通知事实、Access Log 或公共 Outbox
| 入口 | Audit Event | Domain Ledger | Integration Log | Outbox |
|---|---|---|---|---|
| 明确后台账号通知事件消费与幂等写入 | N/A测试环境冻结生产前由 6.5 重新评审通知失败与系统告警治理) | `tb_notification` 是通知投递与接收人已读状态的权威事实 | N/A无外部系统调用 | 消费公共 Outbox 的稳定事件,不复制 Outbox |
| 当前后台账号单条通知已读 | N/A低风险个人阅读状态普通已读操作只进入 Access Log | `tb_notification.is_read/read_at` 是权威状态 | N/A | N/A |
| 当前后台账号未读数与基础列表 | N/A普通读取不返回其他接收人数据或敏感业务正文 | 只读 `tb_notification` 投影 | N/A | N/A |
| 代理主钱包订单统一扣款 | 延期(测试环境冻结;生产前由 6.5 为资金变更补齐同事务 Audit Event | `tb_order``tb_agent_wallet``tb_agent_wallet_transaction``tb_payment` 与套餐使用记录在同一事务形成权威事实 | N/A不调用外部系统 | 同事务写入 `wallet.agent_main.debited`,为余额预警等后续消费者提供稳定事实 |
| 代理主钱包订单资金预占、释放与完成扣除 | 延期(测试环境冻结;生产前由 6.5 为冻结及终态变更补齐同事务 Audit Event | `tb_agent_wallet_reservation` 是预占金额、付款钱包与唯一终态的权威事实;钱包与完成扣除流水同事务更新 | N/A不调用外部系统 | 同事务写入 `wallet.agent_main.reservation.changed`;完成扣除同时写入 `wallet.agent_main.debited`,消费者按权威事实幂等确认 |
| 代理主钱包充值与人工调整正向入账 | 延期(测试环境冻结;生产前由 6.5 为入账补齐同事务 Audit Event | 充值/人工调整业务事实、`tb_agent_wallet` 与唯一成功流水在同一事务形成权威事实 | N/A本接缝不调用支付或审批外部系统 | 同事务写入 `wallet.agent_main.credited`,消费者按成功流水复核;支付/审批 Integration Log 由 UR#34 外部流程负责 |
| 代理订单主钱包退款回充 | 延期(测试环境冻结;生产前由 6.5 为退款资金变更补齐同事务 Audit Event | 原成功扣款流水定位付款钱包并限定金额;退款审批、`tb_agent_wallet` 与唯一成功退款流水同事务形成权威事实 | N/A本资金接缝不调用渠道或审批外部系统 | 同事务写入 `wallet.agent_main.refunded`,消费者复核退款流水、原扣款事实、金额上限和资产快照 |
| 代理商资金概况信用投影 | N/A普通受权读取不返回其他数据范围的资金事实不执行资金或配置变更 | 只读投影 `tb_shop`、主/佣金钱包、提现汇总和主账号;派生金额不另建事实表 | N/A无外部系统调用 | N/A纯 Query 不产生可靠副作用) |
| 受控系统配置更新 | N/A用户已明确取消全局 Audit Event仅超级管理员可更新代码注册 Key未知 Key、非法类型和值域均拒绝 | `tb_system_config` 是配置值、类型、模块及更新人的 PostgreSQL 权威事实,更新后失效 Redis 缓存 | N/A配置更新不调用外部系统不得写 Integration Log 冒充配置审计) | N/A配置更新不产生可靠异步副作用 |
| 电信实名结果回调 | N/AAudit Event 已移出本 Change运营商来源真实性验证也不在本票边界 | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实 | 每次入站先写 `tb_integration_log`,仅保存正文摘要;覆盖 `invalid_payload/ignored/not_found/conflict/success/failed` 终态 | 实名事实首次变化时由公共 `ApplyCardObservation` 同事务写入实名状态变化 Outbox重复成功不重复写事件 |
| 移动实名成功回调 | N/AAudit Event 已移出本 Change不接入旧平台登录、MSISDN 补查或来源真实性验证) | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实 | 每次入站先写 `tb_integration_log`,仅保存正文摘要;覆盖 `invalid_payload/not_found/conflict/success/failed` 终态,并通过 pending 租约恢复中断处理 | 仅合法成功报文进入公共 `ApplyCardObservation`;实名事实首次变化时同事务写入 Outbox重复成功不重复写事件 |
| 联通实名成功回调 | N/AAudit Event 已移出本 Change不复制旧 `inner_callback`、第三方推送或 Gateway 二次确认) | `tb_iot_card` 是实名状态、首次实名时间和逆转窗口的权威事实;上游 `dateChanged` 只用于幂等和留痕 | 每次入站先写 `tb_integration_log` 正文摘要;覆盖 `invalid_payload/not_found/conflict/success/failed`,关闭时记录 `ignored` | 仅合法成功报文进入公共 `ApplyCardObservation`;实名事实首次变化时同事务写入 Outbox重复成功不重复写事件 |
| 联通解除实名回调 | N/A只识别并留痕外部解除通知不把单次回调作为本地实名逆转事实 | `tb_iot_card` 保持原实名状态、首次实名时间、检查时间及逆转计数,回调不写领域事实 | 每次入站先写 `tb_integration_log` 正文摘要;覆盖 `invalid_payload/not_found/conflict/ignored/failed` 终态并支持 pending 租约恢复 | N/A不调用公共实名观测不产生状态变化、停机或套餐事件 |
## 旧 Writer 与旧表写入口清单
### 旧账号审计
- Writer 与 Store`internal/service/account_audit/service.go``internal/store/postgres/account_operation_log_store.go`
- 生产装配:`internal/bootstrap/services.go``internal/bootstrap/stores.go`
- 调用模块:`internal/service/account/service.go``internal/service/agent_recharge/service.go``internal/service/shop_package_batch_allocation/service.go``internal/service/wechat_config/service.go`
- 已确认裸 goroutine 调用:`internal/service/agent_recharge/service.go` 1 处,`internal/service/wechat_config/service.go` 5 处Writer 自身另启 goroutine。
- 迁移责任04、07、0819 号票验证生产装配和直接旧表写入归零。
### 旧资产审计
- Writer、Builder 与 Store`internal/service/asset_audit/``internal/store/postgres/asset_operation_log_store.go`
- API/Worker 装配:`internal/bootstrap/services.go``internal/bootstrap/worker_services.go``internal/bootstrap/stores.go``internal/bootstrap/worker_stores.go`
- 调用模块:`internal/service/asset/``internal/service/device/``internal/service/device_import/``internal/service/iot_card/``internal/service/iot_card_import/``internal/service/polling/asset_polling_service.go`
- 兼容读取:`internal/handler/admin/asset.go``internal/routes/asset.go``internal/model/dto/asset_operation_log_dto.go`;由 10 号票保留读取契约。
- 迁移责任05、06、0919 号票验证生产装配和直接旧表写入归零。
### 旧手动轮询日志
- 状态与写入:`internal/service/polling/manual_trigger_service.go``internal/store/postgres/polling_manual_trigger_store.go``internal/model/polling.go`
- 装配与接口:`internal/bootstrap/services.go``internal/bootstrap/stores.go``internal/handler/admin/polling_manual_trigger.go`
- 当前仍同时承担运行状态和历史查询不能提前停写09 号票先切到公共异步任务与 Integration Log10 号票提供历史投影19 号票再启用旧写护栏。
## 评审门禁
以下确认尚未由本地代码执行替代00 号票在三方评审前不得标记完成:
- 业务评审逐入口业务所有者、资源、Domain Ledger 与 N/A 理由准确,没有改变已评审业务范围。
- 研发评审:事务边界、失败策略、旧 Writer 清单、动作编码和测试接缝能由对应迁移票落地。
- 安全评审:风险等级、敏感字段策略、拒绝/失败覆盖和外部正文摘要策略完整。
评审发现错误时应修改对应显式条目和生成分类规则,并重新运行覆盖门禁;禁止仅手改统计数字。