基线:a74efa11
当前:7d98dc79
跨度:约 4 小时 · 20 个提交 · 33 个源文件
把A 端「运营找不到配置」和后端「一个慢请求就全线卡死」这两个问题解决了,
顺手把下单链路的幂等补上、测试数据清干净、埋点补上 IP/UA/session。
https://doc.kailashi.cn/console/)| 项 | 说明 |
|---|---|
| 改动 | 新增 DashboardPage.tsx +菜单「首页 → 看板」放在第一位 |
| 内容 | 6 张指标卡 · 时间范围切换(今日/7天/30 天)· 待办卡 · 埋点事件分类 |
| 数据源 | /api/admin/stats/overview(已有端点,未新增接口) |
🔴 动因:实测发现 menu.ts 里「首页」组下只有「主视觉」一个子项
⇒ 运营打开 A 端看到的是改图文的表单,看不到任何「今天怎么样」的信息。
| 项 | 说明 |
|---|---|
| 改动 | 新增 TrendCharts.tsx(纯 SVG)+ 后端新增 /api/admin/stats/trend |
| 体积 | 8.7 KB(引入 echarts 约 +300KB gzip,没引) |
| 设计 | 三序列独立缩放 —— cs_click 峰值195 / phone 7 / orders 0,差 200 倍,共用 Y 轴会把小的压成直线 |
| 项 | 说明 |
|---|---|
| 改动 | DataTablePage 加重试按钮 + 骨架屏;EmptyState 组件 |
| 空态覆盖 | 19/19(改前 16/20) |
🔴 口径:我第一版给底座加了 3 个新 props,隔一轮才发现项目早有 emptyHint ⇒ 已撤回,避免在既有设计上叠一层。
10 个一级分组改成客人的词(「商品与交易」→「买什么」等)+ 悬停显示 C 端对照。
⚠️ 刻意没动叶子项:语音/知识库/场景卡对应 C 端哪里我并不确定,
归错类比不重排更糟(运营按新分类找、东西不在那儿更迷惑)。
rev=3d721c9d)| 改动 | 内容 |
|---|---|
| 多 worker | --workers 4(原单进程)· --timeout-keep-alive 90 · --limit-concurrency 200 |
| 连接池 | PG_POOL_MIN/MAX + PG_COMMAND_TIMEOUT=15(原硬编码且无超时) |
| 慢请求日志 | 新增 SlowRequestMiddleware(>500ms 记,带 request_id) |
连接预算公式(写进代码注释防将来扩容踩坑):
实例数 × worker 数 × POOL_MAX ≤ max_connections × 0.8 ⇒ 当前 1×4×10=40 ≤ 80 ✅
🔴 为什么先做多 worker:单进程单事件循环下,一个慢请求/一个死循环就全线卡死
—— 这不是"扛不住流量",是"一个点的问题扩散成全站不可用"。
| 层 | 改动 |
|---|---|
| C 端 | 新增 utils/idempotency.ts,四处下单全部带上幂等键 |
| 后端 | 新增 order_idempotency_guard.py,撞唯一约束时返回已建订单而非 500 |
🔴 查出的大问题:后端早就支持 idempotencyKey,但 C 端从未传过
⇒ 弱网重复点「立即预订」会创建两笔订单。
⚠️ 关键设计:键必须在意图产生时生成(onLoad 重置 +惰性生成),不是每次点击现生成。
| 列 | 改前 | 改后 |
|---|---|---|
ip_addr | 308 条全空 | ✅ 采集(实测 101.249.218.212) |
user_agent | 308 条全空 | ✅ 采集 |
session_id | 308 条全空 | ✅ C 端已补(待上传生效) |
🔴 关键:request.client.host 在 nginx 反代下拿到的是 nginx 自己的地址
⇒ 必须读 X-Real-IP,其次取 XFF 第一段(不是整段)。
| 表 | 清理前 | 清理后 |
|---|---|---|
orders | 13 | 0 |
order_items | 40 | 0 |
redemption_codes | 58 | 0 |
fulfillment_items | 32 | 0 |
备份:/srv/kailash/backups/orders-clean-20261009/(3 份 pg_dump)
⚠️ 你说是 12 笔,实际 13 笔(is_test=true 仅 3 笔,另 10 笔是 cancelled)。
###① 退款分摊「重复实现」不能合并(a0ad1ba6)
我原以为该抽成共用函数,实测发现两处 pending_fen 兜底刻意不同:
| 申请退款 | 执行退款 | |
|---|---|---|
| 无履约项时 | pending=total ⇒ 仍可申请 | pending=0 ⇒ 直接 422 |
⇒ 「申请宽、执行严」的有意设计。合并会抹平差异,
而下一个人很可能误当成 bug 去"修成一致" ⇒ 已加警示注释,仅注释改动 0 行逻辑。
cde94815)它是一次性历史迁移:搬数据段要读的 12 个列,
正是它自己第 4 部分删掉的,而建表迁移 106 也不产生它们
⇒ 全新库必然跑不了。处理:文件头加警示 + staging 补台账记录。
⇒ deploy staging 从此不再失败(跳过 134 个迁移、health 200)。
from .services.order_idempotency_guard import ... ❌ 应为 ..services
ModuleNotFoundError: No module named 'app.routers.services'
⇒ 8 个 worker 全部启动即崩 · health 000
根因:py_compile 只做语法分析、不解析导入路径 ⇒ 它当时报 OK。
教训:加/改 import 后,必须真 import 一次才算验证过。
⚠️ 今晚同类错误犯了两次,另一次(from .db import)只会让定时任务全部 ImportError,
同样是 py_compile 放过的。
miniprogram-v3/utils/idempotency.ts ← 下单幂等(防重复下单)
miniprogram-v3/utils/track-session.ts ← 埋点会话
miniprogram-v3/utils/concierge.ts
miniprogram-v3/pages/product-detail/product-detail.ts
miniprogram-v3/pages/item-detail/item-detail.ts
我不碰上传(你的红线)。
.gitignore 只排了 dist/,但我今晚构建用的目录叫
dist-1009-2306 / dist-old-231749 ⇒ 不匹配 ⇒ 733 个构建产物被跟踪。
影响:仓库膨胀(单个 dist 目录 2.2MB),且每次构建都会再进来一份。
修复:git rm -r --cached + .gitignore 加 dist-* / dist-old-*。
要我做吗?
| 想撤什么 | 怎么做 |
|---|---|
| 后端全部 | git revert 或部署旧指纹(a74efa11) |
| 只撤 A 端 | bash scripts/deploy_frontend.sh(部署上一个 dist) |
| 只撤后端 | bash scripts/deploy.sh(会重建容器到当前 commit) |
⚠️ 数据库无回滚:
119_app_messages_dedup_key.sql 只加列+索引(可空、不影响存量),
dedup_key 只在 D7 站内信用,删掉索引即可回到旧行为。