Files
platforms/audit/CODE_AUDIT_REPORT.md

27 KiB
Raw Blame History

全项目代码审计报告

审计日期2026-07-31

审计对象:apps/*backend/*frontend/*

审计方式:只读代码审计、静态检查、单元测试和本地构建

审计基线:仅以实际代码、路由、数据模型、客户端调用和测试为依据,未将 docs/* 作为需求或验收依据

1. 结论

当前代码不具备生产发布条件

本次确认:

  • P02 项
  • P17 项
  • P28 项
  • P33 项

最先需要阻断发布的事项是:

  1. 仓库历史中存在明文的外部数据库、Redis 等敏感配置;固定验证码又可直接进入注册、登录和重置密码流程。
  2. 钱包的 balancewithdrawal_balance 记账口径不闭合,可产生重复支出、拒绝提现后余额凭空增加、提现完成后总余额不减少等资金错误。
  3. Worker、IoT 和上传存储仍明确是 Mock实际异步与设备链路不存在。
  4. 工作人员“作业前置检查”仅用于展示,业务接口没有服务端强制执行。

因此,测试和构建全部通过并不能推导出业务可上线;现有测试主要验证路由、模型和少量纯函数,没有覆盖上述关键资金、鉴权、幂等和跨端流程。

等级定义

等级 含义
P0 可直接造成账户接管、资金损失、核心数据破坏或必须立即处置的密钥泄露
P1 核心流程不可用、可绕过关键业务控制或上线即产生严重错误
P2 在异常、并发、重试或特定数据下产生错误,或形成明显维护/兼容风险
P3 低风险冗余、局部质量或性能问题

置信度“高”表示从当前代码可以完整证明;“中”表示代码证据明确,但删除字段或迁移前仍需核对线上数据及外部消费者。

2. P0发布阻断

P0-01 仓库内存在敏感连接配置,固定验证码可形成账户接管链路

置信度:高

证据

  • backend/api/etc/platform_dev.yaml:7 包含公网 PostgreSQL 连接地址、账号和明文密码。
  • backend/api/etc/platform_dev.yaml:10 包含公网 Redis 地址和明文凭据。
  • backend/api/etc/platform_dev.yaml:12,18,24 分别包含固定 JWT 密钥/固定验证码/字段加密密钥性质的配置。
  • 该文件由 Git 跟踪,且至少出现在多个历史提交中,单纯修改当前文件不能消除历史泄露。
  • backend/api/internal/logic/common/client_auth.go:60-67 将全局固定验证码写入 Redis。
  • backend/api/internal/logic/common/client_auth.go:73-85 使用该固定值完成验证和消费。
  • 用户与工作人员的注册、验证码登录、重置密码、支付密码设置均复用该验证能力。

影响

  • 外部数据库和 Redis 可能被直接访问、篡改或拖库。
  • 已知固定验证码的人可为目标手机号申请新的 request_identity,随后尝试注册、验证码登录或重置密码。
  • 字段加密密钥一旦与密文数据同时泄露,敏感字段的静态加密失去保护。

根因

  • 开发配置被当作可提交配置管理。
  • Mock 验证码能力直接复用了真实身份流程,没有环境级硬隔离。

最小整改

  1. 立即轮换数据库、Redis、JWT、字段加密等所有已提交凭据先吊销旧值再更新部署。
  2. 核查相关服务的访问日志、异常登录、密码重置和数据导出记录。
  3. 将敏感值迁移到环境变量或密钥管理系统,仓库只保留无效示例。
  4. 清理 Git 历史中的敏感内容,并要求所有已有克隆重新同步。
  5. Mock 验证码只允许在不可访问生产数据的本地环境启动;生产启动时发现 Mock 开关或固定码应直接失败。

迁移风险

  • 字段加密密钥轮换需要双密钥读取或批量重加密方案,不能直接替换后让历史数据失效。

复测

  • 对仓库当前树和完整 Git 历史执行密钥扫描。
  • 在非本地环境验证 Mock 验证码无法启动。
  • 使用旧密钥、旧数据库凭据和旧 Redis 凭据验证均已失效。
  • 覆盖目标手机号的验证码登录和重置密码攻击用例。

P0-02 钱包双余额账本不闭合,可重复支出并制造余额

置信度:高

证据

  1. 平台可提现充值同时增加两列:
    • backend/api/internal/logic/platform/wallet/wallet.go:232-239
  2. 商城支付只扣 balance,不扣 withdrawal_balance
    • backend/api/internal/logic/client/user/shop.go:167-189
  3. 用户提现申请只扣 withdrawal_balance,不扣 balance
    • backend/api/internal/logic/common/client_wallet.go:372-398
  4. 提现完成只更新申请状态和外部交易号,不扣 balance
    • backend/api/internal/logic/platform/wallet/wallet.go:336-366
  5. 配送后台创建提现申请时不预扣 withdrawal_balance,仅在查询时减去待处理申请:
    • backend/api/internal/logic/delivery/finance.go:145-188
  6. 平台驳回任何提现申请都会把申请金额加回 withdrawal_balance
    • backend/api/internal/logic/platform/wallet/wallet.go:313-323

可复现场景

  • 钱包充值 100 元且标记可提现后:balance=100withdrawal_balance=100
  • 商城消费 80 元后:balance=20withdrawal_balance=100
  • 再申请提现 100 元会通过,形成 80 元消费加 100 元提现。
  • 配送后台申请提现时未预扣;若平台驳回,现有代码仍加回金额,可将 100 元可提现余额变成 200 元。
  • 提现最终完成也不会减少总余额,余额和实际资金继续背离。

影响

  • 直接资金损失。
  • 钱包余额、可提现余额、提现申请和流水无法对账。
  • 客户可在正常 API 流程内触发,不需要数据库权限。

根因

  • withdrawal_balancebalance 的可提现子集,但各交易没有在同一事务内维护该不变量。
  • 用户提现和配送后台提现采用了两套互不兼容的预扣策略。
  • 提现没有完整的冻结额、解冻、出账和不可变流水模型。

最小整改

  1. 立即关闭充值、余额支付和提现写入口,先冻结风险窗口。
  2. 明确统一不变量,例如 0 <= available_withdrawable <= available_balance,并增加“冻结余额/冻结可提现余额”。
  3. 支付、提现申请、驳回、完成必须在事务和行锁内同时更新余额、冻结额、流水。
  4. 合并用户与配送后台提现逻辑,禁止各自实现不同扣减策略。
  5. 对历史钱包、流水、提现、商城订单做全量对账和差异修复。

迁移风险

  • 不能只改代码;历史余额已经可能不可信。
  • 修复前需以外部支付记录、订单、提现回执和不可变流水重建余额,避免把现有错误余额作为初始事实。

复测

  • 覆盖充值→支付→提现、提现→驳回、提现→完成、重复请求、并发支付/提现。
  • 对每一步断言余额、可提现余额、冻结额和流水守恒。
  • 增加基于随机交易序列的账本不变量测试。

3. P1核心流程和安全控制

P1-01 Worker 与 IoT 仅为阻塞式 Mock 进程

置信度:高

证据

  • backend/worker/cmd/main/main.go:14-20 只初始化后等待退出信号,并明确输出 Redis Streams consumer 未启用。
  • backend/iot/cmd/main/main.go:14-20 只初始化后等待退出信号,并明确输出 MQTT Broker 未连接。
  • 两模块合计约 150 行 Go 代码没有消费者、重试、Outbox 投递、MQTT 会话、命令回执或业务测试。

影响

  • 异步通知、对账、超时处理等依赖 Worker 的流程不会执行。
  • 设备遥测、远程命令和回执链路不存在。
  • 进程可以成功构建和启动,但只会制造“服务在线”的假象。

最小整改

  • 发布清单中明确排除这两个能力,或在发布前实现真实适配、健康检查、失败重试、幂等和可观测性。
  • 健康检查必须区分“进程存活”和“已连接 Redis Streams/MQTT”。

P1-02 关闭 Mock 后验证码功能全部失效,代码中没有真实发送适配器

置信度:高

证据

  • backend/api/internal/logic/common/client_auth.go:60-63 无条件保存 MockVerificationCode,没有生成随机码或调用短信渠道。
  • backend/api/internal/logic/common/client_auth.go:73-76MockVerificationEnabled=false 时直接拒绝所有验证码。
  • 未发现短信发送接口、供应商适配器或发送结果处理。

影响

  • 为安全而关闭 Mock 后,验证码登录、注册、密码重置和支付密码相关流程全部不可用。

最小整改

  • 建立真实验证码生成、散列保存、发送、频率限制、失败处理和审计链路。
  • Mock 与真实实现应通过依赖注入隔离,禁止在业务函数内用全局开关混用。

P1-03 工作人员作业预检可以绕过

置信度:高

证据

  • backend/api/internal/logic/client/staff/auth.go:67-108 计算机构归属、资质有效性、在岗状态和 can_work
  • backend/api/internal/logic/client/staff/auth.go:20-52 的登录实现只校验账户状态、角色和密码,注释所称“资质有效”未被执行。
  • backend/api/internal/logic/client/staff/work.go:72-85backend/api/internal/logic/client/staff/delivery.go:55-230 的开始、轨迹、到达、异常、恢复、签收等接口没有校验同一套预检条件。
  • apps/service_app/lib/app/router.dart:12-98 只按是否有 Token 路由;可直接进入 /work/tasks/:identity,没有强制 can_work

影响

  • 离岗、资质过期或缺少机构归属的人员仍可绕过页面直接调用作业 API。

最小整改

  • 将作业资格校验提取为服务端中间件/领域守卫,挂载在所有会改变工单、配送、轨迹、证据的接口上。
  • 客户端预检仅负责展示,不作为可信控制。

P1-04 三套支付事实互相割裂,真实支付不会进入看板支付统计

置信度:高

证据

  • 重叠模型:
    • backend/api/internal/models/fin_payment.go:8-16
    • backend/api/internal/models/wallet_payment.go:5-20
    • backend/api/internal/models/gasorder_payment.go:5-12
  • 除 Mock seed 外,未发现业务代码创建 FinPaymentWalletPaymentGasorderPayment
  • 商城实际支付只更新 EcOrder 并创建 WalletRecord
    • backend/api/internal/logic/client/user/shop.go:180-191
  • 平台支付金额和渠道统计读取 WalletPayment
    • backend/api/internal/logic/platform/dashboard/statistics.go:106-132
  • 气体订单的金额调整又以 GasorderPayment 是否存在作为“已支付”判断:
    • backend/api/internal/logic/delivery/order.go:369-375

影响

  • 真实商城支付成功后,看板支付金额仍可能为零。
  • 支付页面、财务支付、钱包支付、气体订单支付显示不同事实。
  • 气体订单代码具备“已支付后禁止改价”判断,但当前流程没有形成对应支付记录。

最小整改

  • 选定唯一支付主事实和订单支付关联模型。
  • 所有支付渠道在同一事务/事件链路写入统一支付事实和钱包流水。
  • 看板、财务、气站、配送后台统一读取同一事实或受控聚合。

迁移风险

  • 三张表不能直接删;需先核对线上数据和外部消费者,建立字段映射与去重规则。

P1-05 用户 App 的商城流程在“请前往订单页支付”后中断

置信度:高

证据

  • 下单成功明确提示前往订单页支付:
    • apps/user_app/lib/ui/features/shop/shop_page.dart:59-70
  • ClientRepository 只有创建和列表方法,没有调用后端已有的支付、取消、确认收货接口:
    • apps/user_app/lib/data/repositories/client_repository.dart:43-117
  • 订单页只是三个只读列表:
    • apps/user_app/lib/ui/features/orders/orders_page.dart:7-47
  • 后端实际提供 /shop/orders/:identity/paycancelconfirm-receipt
    • backend/api/internal/routers/client.go:47-51

影响

  • 用户可以下单并占用库存,但不能在客户端完成支付、取消或确认收货。

最小整改

  • 增加订单详情及基于服务端状态的支付/取消/确认动作。
  • 支付请求必须持久化并复用幂等号,不能每次点击生成新值。

P1-06 冻结或停用的钱包仍可在客户端执行资金操作

置信度:高

证据

  • 平台允许把钱包改为启用、停用或冻结:
    • backend/api/internal/logic/platform/wallet/wallet.go:191-200
  • 客户端 ensureWallet 对已存在钱包直接返回,不检查状态:
    • backend/api/internal/logic/common/client_wallet.go:41-57
  • 商城支付和用户提现查询钱包时也未限制 status
    • backend/api/internal/logic/client/user/shop.go:167-177
    • backend/api/internal/logic/common/client_wallet.go:366-398

影响

  • 风控冻结不能阻止支付和提现。

最小整改

  • 所有资金写操作在事务内按 status=enable 锁定钱包;冻结后禁止新交易,仅允许受控冲正/退款。

P1-07 上传能力仍是本地 Mock且只按扩展名判定文件类型

置信度:高

证据

  • backend/api/internal/logic/upload/upload.go:36-37,90-95 明确为本地 Mock 存储。
  • backend/api/internal/logic/upload/upload.go:45-49 只检查文件名扩展名和大小。
  • backend/api/internal/logic/upload/upload.go:79-83 将客户端声明的 Content-Type 原样返回,没有校验文件签名或实际 MIME。

影响

  • 伪装成图片/PDF/视频的任意内容可进入存储。
  • 单机本地目录无法支持多实例、一致备份、受控下载或恶意文件隔离。

最小整改

  • 校验魔数和解码结果,重编码图片,对视频/PDF进行独立扫描。
  • 使用私有对象存储、短期授权访问、病毒扫描、审计和生命周期策略。

4. P2一致性、重试与维护风险

P2-01 多处“幂等”只处理唯一键冲突,没有验证请求归属和载荷

置信度:高

证据

  • 签收回执按全局 request_no 返回任意既有确认记录,没有校验订单和当前工作人员:
    • backend/api/internal/logic/client/staff/delivery.go:226-231
  • 商城支付成功后使用相同 request_no 重试,会先因订单状态不再是待支付而失败,无法返回原结果:
    • backend/api/internal/logic/client/user/shop.go:161-195
  • 创建工单遇到重复 request_no 直接返回数据库错误:
    • backend/api/internal/logic/client/user/address_ticket.go:98-109
  • 打卡重复请求返回时,响应中的 work_status 根据本次请求重新计算,而不是根据既有记录:
    • backend/api/internal/logic/client/staff/work.go:46-69

影响

  • 网络超时后的安全重试可能变成失败、误报成功,甚至返回另一订单的结果。

最小整改

  • 幂等记录至少绑定:主体、资源、动作、请求载荷摘要和最终响应。
  • 相同幂等键但载荷不同必须返回稳定冲突错误;相同载荷返回已保存结果。

P2-02 服务 App 保存了签收幂等号,但提交时重新生成

置信度:高

证据

  • 草稿保存 request_no
    • apps/service_app/lib/ui/features/work/work_detail_page.dart:114-123
  • 页面没有把该值传给仓库:
    • apps/service_app/lib/ui/features/work/work_detail_page.dart:124-136
  • 仓库在每次提交时重新生成 UUID
    • apps/service_app/lib/data/repositories/service_repository.dart:92-108

影响

  • 上传或请求响应丢失后,用户重试会使用新幂等键,可能重复形成签收动作。

最小整改

  • submitDeliveryReceipt 必须接收并复用草稿中的 requestNo;删除草稿前保留服务端最终结果。

P2-03 商城订单的组织字段在真实创建流程中永远为零

置信度:高

证据

  • EcOrder 声明 gas_station_iddelivery_point_id
    • backend/api/internal/models/ec_order.go:15-16
  • 真实下单创建 EcOrder 时未赋值:
    • backend/api/internal/logic/client/user/shop.go:54-59
  • 仅 Mock seed 为这两个字段赋值。

影响

  • 按气站/配送点统计、权限范围、履约分派或结算会得到空组织。

最小整改

  • 若商城订单必须归属机构,应在服务端从服务关系或商品归属中确定并写入快照。
  • 若业务确实为平台统一商城,应迁移后移除这两个误导字段及相关索引/展示。

P2-04 三个 Web 管理端以复制方式维护,且配送端包含整段不可达配置

置信度:高

证据

  • 三个 src + scripts 各约 1.9 万行。
  • 平台端与气站端有 80 个逐字节相同文件,约 18,280 行;平台端与配送端有 79 个相同文件,约 18,199 行。
  • 三端的 CrudListPage.vue 均为 1,175 行且内容相同。
  • frontend/delivery_admin/src/api/resources.ts:287-384 复制了完整平台资源定义。
  • frontend/delivery_admin/src/api/resources.ts:386-426 定义 gasOverrides,但导出只使用 deliveryOverrides
    • frontend/delivery_admin/src/api/resources.ts:428-470

影响

  • 一个通用缺陷需要在三处同步修复,极易发生漂移。
  • 配送包携带与本端无关的大量资源、字段和动作配置。

最小整改

  • 将 API 客户端、会话、通用 CRUD、字段渲染、权限和契约检查提取到工作区共享包。
  • 各管理端只维护入口、主题和本端资源覆盖。
  • 直接删除前先用引用检查确认不可达;当前 gasOverrides 已可由导出链证明不可达。

P2-05 数据库自增 id 被作为公共 API 字段并在三端展示

置信度:高

证据

  • 公共实体把内部主键序列化为 id
    • backend/api/internal/models/entity.go:10-16
  • 公共资源响应显式保留记录自身 id
    • backend/api/internal/logic/common/resource.go:450-486
  • 三端通用列表固定显示 ID 列:
    • frontend/platform_admin/src/views/shared/CrudListPage.vue:23-26

影响

  • ididentity 成为两个公开身份字段,增加前端误用和外部耦合。
  • 连续主键还会泄露记录规模和创建顺序。

最小整改

  • 数据库 id 本身不是冗余字段,不应删除;应从 HTTP 响应和前端移除。
  • 迁移前检查外部调用方是否仍使用 id,提供兼容窗口。

P2-06 两个 Flutter API 客户端缺少超时和统一的 401 会话失效处理

置信度:高

证据

  • apps/user_app/lib/data/services/api_client.dart:47-76
  • apps/service_app/lib/data/services/api_client.dart:41-80
  • 请求直接等待 _client.send/上传结果,没有连接、读取或总超时。
  • 401 只抛异常,没有清理安全存储中的 Token。
  • 两个路由都仅以“Token 字符串非空”判断已登录:
    • apps/user_app/lib/app/router.dart:14-21
    • apps/service_app/lib/app/router.dart:12-19

影响

  • 弱网下页面可能长期挂起。
  • Token 过期或被撤销后,用户会停留在已登录路由并持续收到请求错误。

最小整改

  • 建立共享客户端层统一超时、有限重试、取消、401 清会话和重新登录。
  • 资金写操作只能依赖幂等键重试,不能盲目重放。

P2-07 前后端契约检查只比较资源名、模式和路由字符串

置信度:高

证据

  • frontend/platform_admin/scripts/check-backend-contract.mjs:12-37 通过正则读取 define(name, mode),再检查资源路径和路由源码是否包含字符串。
  • 未校验 HTTP 方法、动作路径、请求字段、必填项、枚举、响应字段和错误码。
  • 气站、配送端脚本采用同类实现。

影响

  • contract:check 通过不能发现支付动作缺失、字段漂移或错误 HTTP 方法。

最小整改

  • 使用结构化 OpenAPI/Schema 生成客户端与字段类型。
  • 至少对每个动作校验方法、路径、请求/响应结构,并增加真实路由契约测试。

P2-08 钱包创建存在并发竞态,银行卡敏感字段加密错误被忽略

置信度:高

证据

  • ensureWallet 采用先查后创建,唯一键冲突时不回查已有钱包:
    • backend/api/internal/logic/common/client_wallet.go:41-57
  • 首次并发请求时,一个请求可能收到数据库唯一约束错误。
  • 绑卡时只处理卡号加密错误,身份证和手机号加密错误被丢弃:
    • backend/api/internal/logic/common/client_wallet.go:287-300

影响

  • 新用户并发访问钱包时出现偶发失败。
  • 加密异常可能生成空密文但仍写入银行卡记录,造成不可恢复的数据缺失。

最小整改

  • 使用 ON CONFLICT DO NOTHING 后回查,或在事务中锁定所有者。
  • 每个敏感字段的加密错误都必须中止事务。

5. P3已证实或疑似冗余

P3-01 钱包第三方账号字段只有 Mock 数据写入

置信度:中

证据

  • backend/api/internal/models/wallet_basic.go:11-14 定义支付宝、微信账号及姓名四个字段。
  • 生产业务中未发现写入入口;仅 seed 使用。
  • Web 资源仍展示这些字段。

判断

  • 当前属于“疑似冗余/未完成字段”,不能仅凭静态引用直接删除。

建议

  • 核对线上非空率、导出消费者和未来渠道设计;确认不用后再做带回滚方案的迁移。

P3-02 Web 与状态 Store 保留多组本端不可达能力和模板字段

置信度:中

证据

  • 气站/配送端的通用平台 API 保留角色创建、角色菜单、平台账号等调用,但本端路由和资源未暴露这些页面。
  • 三端用户 Store 保留 joborganizationlocationemailintroductionpersonalWebsite 等模板字段,实际登录资料只填充账号、名称、头像、角色和菜单。

建议

  • 先用 TypeScript 引用分析和运行时埋点确认不可达,再删除本端无关方法和状态字段。
  • 共享 Store 只保留跨端最小会话模型,本端扩展单独声明。

P3-03 离线草稿读取重复解析同一加密文件

置信度:高

证据

  • apps/service_app/lib/data/offline/encrypted_draft_store.dart:69-77 先读取并 jsonDecode 外层载荷,随后再次读取文件并在 _decrypt 内再次解析。

影响

  • 每次读草稿多一次文件读取和 JSON 解析,且前后两次读取理论上可能看到不同内容。

最小整改

  • 读取一次字符串,完成结构校验后把同一值传给解密函数。

6. 字段与表冗余结论

对象 结论 依据 处理方式
数据库 id 数据库内部必需,公共 API/UI 冗余 API 同时提供 identityUI仍显示 id 保留数据库列;移除公开序列化和 UI 展示
FinPayment / WalletPayment / GasorderPayment 已证实事实重叠,但不能直接删表 实际支付不写三表,看板却读其中一表 先确定唯一支付事实并迁移、对账
EcOrder.GasStationID/DeliveryPointID 当前生产流程未填充 仅 seed 写入 明确归属规则后补写,或迁移删除
WalletBasic 支付宝/微信四字段 疑似冗余 仅 seed 写入 查线上非空率及外部消费者后决定
配送端 gasOverrides 已证实代码冗余 定义后未进入导出链 可删除,并用静态检查防回归
Web 会话模板字段 疑似冗余 未进入实际资料映射 引用和运行时确认后删除

没有将“只在响应、展示或 seed 中出现”的字段直接判定为可删。数据库删字段、删表前必须补充:

  1. 线上非空率和取值分布;
  2. API 网关/访问日志中的字段消费者;
  3. 报表、导出、脚本和第三方集成引用;
  4. 双写/回填/回滚方案。

7. 测试、静态检查与构建结果

已实际执行:

backend/api:
  go test ./...                         通过
  go vet ./...                          通过
  go build ./cmd/main/main.go           通过

backend/worker:
  go test ./...                         通过(无测试文件)
  go build ./cmd/main/main.go           通过

backend/iot:
  go test ./...                         通过(无测试文件)
  go build ./cmd/main/main.go           通过

apps/user_app:
  flutter analyze                       通过
  flutter test                          通过2 个测试)

apps/service_app:
  flutter analyze                       通过
  flutter test                          通过3 个测试)

frontend/platform_admin:
  pnpm type:check                       通过
  pnpm lint                             退出码 0112 warnings / 12 infos
  pnpm contract:check                   通过47 个资源)
  pnpm build                            通过

frontend/gas_admin:
  pnpm type:check                       通过
  pnpm lint                             退出码 0105 warnings / 12 infos
  pnpm contract:check                   通过20 个资源)
  pnpm build                            通过

frontend/delivery_admin:
  pnpm type:check                       通过
  pnpm lint                             退出码 0106 warnings / 12 infos
  pnpm contract:check                   通过18 个资源)
  pnpm build                            通过

说明:

  • Web lint 的相当一部分告警来自工具无法识别 Vue 模板对 script setup 变量的使用,不能全部视为真实死代码;本报告仅列出能够从导出/调用链证明的冗余。
  • 后端虽有若干测试文件,但没有覆盖用户钱包支付、用户提现、配送提现、验证码完整流程、工作人员预检强制执行等高风险路径。
  • 两个 Flutter App 的测试主要覆盖模型和登录页面不覆盖商城支付、离线签收重试、401 会话失效或完整作业流程。

8. 建议整改顺序

立即处置

  1. 关闭相关公网凭据并轮换全部已泄露密钥。
  2. 关闭生产资金写入口,审计历史余额和提现。
  3. 禁止生产环境启用固定验证码和 Mock 支付。

第一阶段:资金与身份

  1. 重建钱包不变量、冻结额、统一流水和提现状态机。
  2. 合并支付事实,完成历史数据对账。
  3. 接入真实验证码并增加限流、审计和攻击测试。
  4. 强制服务端工作人员作业资格守卫。

第二阶段:闭环与可靠性

  1. 完成用户 App 支付/取消/收货闭环。
  2. 修复所有幂等键的归属和载荷校验。
  3. 修复服务 App 草稿幂等号传递、401 会话和网络超时。
  4. 上线真实 Worker、IoT、对象存储及健康检查。

第三阶段:去重与契约

  1. 抽取三个 Web 端共享包,删除不可达配置。
  2. 用结构化契约替换正则和源码字符串检查。
  3. 在确认线上数据和消费者后迁移疑似冗余字段/表。

9. 审计限制

  • 未连接公网数据库、Redis、短信、支付、MQTT 或对象存储,未验证仓库中凭据是否仍有效。
  • 未启动依赖外部数据库的完整 E2E 流程,结论来自当前代码可证明的控制流、数据写入和客户端调用链。
  • 未使用 docs/* 推导功能缺口或业务要求。
  • 未修改任何业务源代码;只新增本报告。