docs: 记录 P2 处理结果并补充 TZ 环境变量说明
- 项目分析补充第三轮(P2)处理结果与验证方式,含时区改动的风险说明 - README 环境变量表补充 TZ:业务时间按北京时间处理,且 pgx 会把 timestamptz 解码到进程时区,要求显式设为 Asia/Shanghai - 遗留项收敛为:前端公共 chunk 体积、裸 time.Time 字段的 JSON 精度未对齐秒级约定
This commit is contained in:
@@ -109,6 +109,7 @@ make docker-down # 停止并移除
|
||||
| `COMPOSE_PROJECT_NAME` | Docker Compose 项目名 | `affiliate_dash` |
|
||||
| `POSTGRES_DATA_VOLUME` | PostgreSQL 数据卷名 | `affiliate_dash_postgres_data` |
|
||||
| `GIN_MODE` | Gin 运行模式 | `debug` |
|
||||
| `TZ` | 进程时区。**必须为 `Asia/Shanghai`**:业务时间统一按北京时间处理,且 pgx 会把 `timestamptz` 解码到进程时区。不一致时启动日志会打印 `[CONFIG] 时区提示` | `Asia/Shanghai` |
|
||||
| `OPEN_API_KEY` | 开放接口 ApiKey | 需修改 |
|
||||
| `OPEN_API_SECRET` | 开放接口签名密钥 | 需修改 |
|
||||
| `OPEN_SIGN_SKEW` | 签名时间戳偏差(秒) | `300` |
|
||||
|
||||
+31
-6
@@ -313,15 +313,40 @@ DB 里的值被静默忽略,且没有任何日志提示。
|
||||
| `fulfillment.go` 640 行 | `service/fulfillment.go` | 本次未拆;如需可继续按「下单 / 状态机 / 查询 / 超时」拆分 |
|
||||
| `provider_dlc.go` 598 行、`provider_lewan.go` 565 行 | `service/` | 同上,可各拆为「接口适配」与「协议映射」两部分 |
|
||||
|
||||
### P2
|
||||
### P2 处理结果(2026-10-06 第三轮)
|
||||
|
||||
| 项 | 状态 | 说明 |
|
||||
|----|------|------|
|
||||
| SQLite 时代残留 | ✅ 已删除 | `backend/data/affiliate.db`(0 字节)、`app.db`(90 KB)。删除前已确认无代码引用,并保留 `data/uploads/` 下 16 个在用商品图 |
|
||||
| 告警渠道密钥外泄面 | ✅ 已脱敏 | 响应层只保留密钥末 4 位;webhook 保留域名与路径以便辨认机器人(钉钉/企微在查询串、飞书在路径末段)。脱敏值原样回传时沿用库中真实密钥,填新值则替换。**脱敏刻意放在响应层**:`CheckLowBalanceAndNotify` 复用 `ListAlertChannels` 的结果真正去发消息,在 service 层脱敏会直接打断告警 |
|
||||
| 三套 HMAC 签名实现重复 | ✅ 已收敛原语 | 新增 `internal/pkg/signutil`,只统一语义完全一致的四类:HMAC-SHA256→hex、body 摘要、时间戳偏差、常数时间比较。**签名串构造刻意不统一**——三者是对外契约且方式不同,合并会直接改变握手结果 |
|
||||
| 全局改写 `time.Local` | ✅ 已移除 | 见下方说明 |
|
||||
| 前端公共 chunk 479.7 kB | ⏸ 未处理 | React + AntD 运行时,需评估 antd 按需引入策略,收益与风险需单独评估 |
|
||||
|
||||
**关于时区改动**(这是本轮唯一有行为风险的一项):
|
||||
|
||||
`main.go` 原本用 `time.Local = timeutil.Location()` 隐式改写进程全局状态把时间钉在 +08:00。
|
||||
|
||||
- 唯一真实依赖是 `rock_snapshot.parseRockTime`:上游返回**不带偏移的北京时间墙面时间**,
|
||||
用 `time.Local` 解析等于假设进程时区就是北京时间。实测确认 **pgx 会把 `timestamptz` 解码到
|
||||
`time.Local`**,因此该值一旦不是 +08:00,解析结果会整体偏移 8 小时,进而把「本次新绑定」
|
||||
误判为「历史残留」放回库存 → **造成重复发货**。已改为显式 `timeutil.Location()` 并补回归测试。
|
||||
- 有一点无法绕开:pgx 的解码行为使接口 JSON 的时间偏移仍由进程时区决定。因此新增
|
||||
`timeutil.LocalZoneNotice()`,启动时把不一致显式告警,由运维用 `TZ=Asia/Shanghai` 声明
|
||||
(Docker 部署已内置该变量),而不是靠代码偷偷改全局状态。
|
||||
- 验证:全量测试在**默认时区 / TZ=UTC / TZ=America/New_York** 三种环境下均通过;
|
||||
实测 `TZ=UTC` 启动会打印时区提示,业务时区下静默。
|
||||
|
||||
> 若要做到「完全不受进程时区影响」的下一个台阶,需要把模型里的 `time.Time` 字段换成
|
||||
> 自带 JSON 序列化的自定义时间类型(读写两侧都显式指定时区)。这是一次 API 可见的改动
|
||||
> (当前裸字段输出纳秒精度,文档约定的是秒级),建议作为独立迭代并先补接口回归测试。
|
||||
|
||||
### 仍遗留
|
||||
|
||||
| 问题 | 位置 | 说明 |
|
||||
|------|------|------|
|
||||
| SQLite 时代残留 | `backend/data/affiliate.db`(0 字节)、`app.db`(90 KB) | 已无用途,可删除 |
|
||||
| 三套 HMAC 签名实现独立 | `middleware/open_auth.go`、`source_open_auth.go`、`pkg/lewan/signer.go` | 重复度高易漂移,可抽出公共签名工具 |
|
||||
| 告警渠道配置外泄面 | `AlertNotifyChannel.Config` 带 `json:"config"`,内含 webhook token | 对具备 `recharge:manage` 的商户成员可见;建议按需脱敏 |
|
||||
| 全局改写时区 | `cmd/server/main.go` 中 `time.Local = timeutil.Location()` | 影响进程内所有时间逻辑,建议改用显式 loc |
|
||||
| 前端仍有较大公共 chunk | `jsx-runtime` 479.7 kB(gzip 157.8 kB) | React + AntD 公共运行时,如需进一步优化可评估 antd 按需引入策略 |
|
||||
| 前端公共 chunk 479.7 kB(gzip 157.8 kB) | `dist/assets/jsx-runtime-*` | React + AntD 公共运行时;如需进一步压缩需评估 antd 按需引入与手动分包策略 |
|
||||
| 裸 `time.Time` 字段的 JSON 精度 | 各 model | 输出纳秒精度,而 `docs/API对接关系.md` 约定秒级;契约字段走 `timeutil.FormatAPITime` 是秒级,裸字段未对齐 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user