#321 · prod 测试数据清理方案(精确删除清单 + 回滚方案)

依据义父 2026-09-30 口令:prod 的商品/订单按测试数据处理,只要已上线 C 端不受损即可清理;
但执行须先经本清单审批。本文件只列方案与精确 SQL,未在任何环境执行 prod 删除或下线。

>

纪律:未经义父确认清单,不执行 prod 删除或零售 C 端域下线。prod 冻结中。

一、备份与回滚锚点(已生成)

项值
全量备份文件/tmp/kailash_prod_full_20260930-143030.dump(宿主机 /tmp,非容器内)
大小1,291,133 字节(约 1.23 MB)
格式pg_dump -Fc(自定义压缩格式,可 pg_restore 单表恢复)
校验文件头 PGDMP 有效
生成方式docker exec kailash-pg pg_dump -U yos -d kailash -Fc(只读,不改 prod 数据)
恢复命令docker exec -i kailash-pg pg_restore -U yos -d kailash --clean --if-exists /tmp/kailash_prod_full_20260930-143030.dump

回滚策略(两层):

  1. 手术级(推荐):执行删除前,先对受影响表做单表 dump:

docker exec kailash-pg pg_dump -U yos -d kailash -Fc -t orders -t order_items -t commission_entries -t redemption_events -t distribution_records -t guest_bindings -t settlement_records -t refund_records -f /tmp/prod_affected_pre.dump

若删除后需回滚,用 --clean --if-exists 仅恢复这 8 张表,不动其余数据。

  1. 全量级:上述全量 dump 作终极兜底(恢复会覆盖删除后所有新数据,仅在手术级不足时使用)。

二、已查清的测试行与关联关系(prod 实测)

2.1 四表行数与 is_test 分布

表总行数is_test=tis_test=f说明
orders2952914291 笔明确测试;4 笔 is_test=f 见 §2.3
order_items2062024级联随 orders 删除
goods22022全部 is_test=f;C 端风物契约,保留
retail_products15015全部 is_test=f;A 端 admin 目录,见 §4 候选

2.2 orders.order_type 分布(291 笔测试单)

room 65 / package 195 / ticket 24 / retail 7(均为 is_test=t);另有 4 笔 is_test=f 全为 retail。

2.3 4 笔「未打 is_test 标记的测试单」(需义父拍板,见 §3 Tier-2)

订单 idorder_notypesourcestatus金额创建时间
6280KL00006280retailminiprogrampending_payment¥288.002026-09-30 10:47
6281KL00006281retailminiprogrampending_payment¥288.002026-09-30 10:48
6282KL00006282retailminiprogrampending_payment¥288.002026-09-30 10:48
6283KL00006283retailminiprogrampending_payment¥288.002026-09-30 10:51

2.4 外键约束(决定删除顺序,关键安全点)

指向 orders 的外键共 12 张表,分两类:

⚠️ staging 验证实测教训:staging 的 guest_bindings 有 1 行引用 is_test 订单,若不先清会撞 FK。prod 当前为 0 但方案仍纳入,防未来漂移。

三、精确删除清单(待审批)

Tier-1 · 明确测试数据(建议直接删,无业务价值)

-- 在 prod 单事务内执行(BEGIN ... COMMIT),ON_ERROR_STOP=1
DELETE FROM commission_entries  WHERE order_id IN (SELECT id FROM orders WHERE is_test=true);  -- 50
DELETE FROM redemption_events  WHERE order_id IN (SELECT id FROM orders WHERE is_test=true);  -- 148
DELETE FROM distribution_records WHERE order_id IN (SELECT id FROM orders WHERE is_test=true); -- 50
DELETE FROM guest_bindings     WHERE anchor_order_id IN (SELECT id FROM orders WHERE is_test=true); -- 0(安全)
DELETE FROM settlement_records WHERE order_id IN (SELECT id FROM orders WHERE is_test=true);  -- 0(安全)
DELETE FROM refund_records     WHERE order_id IN (SELECT id FROM orders WHERE is_test=true);  -- 0(安全)
DELETE FROM orders WHERE is_test=true;  -- 291,级联带走 order_items(202)/reviews/order_events/room_bookings 等

预期结果:orders 295→4,order_items 206→4,goods/retail_products 不变。

Tier-2 · 4 笔未标记测试单(需义父确认)

-- 仅当义父批准时追加(同样在事务内)
DELETE FROM order_events WHERE order_id IN (6280,6281,6282,6283);  -- 4(CASCADE 已含,冗余保险)
DELETE FROM orders WHERE id IN (6280,6281,6282,6283);             -- 4

预期结果:orders 4→0,order_items 4→0。这 4 笔无 RESTRICT 子行,删除干净。

Tier-3 · 商品目录(判断项,默认保留)

表行数建议理由
goods22保留C 端风物交易锁价表(#320 契约),22 行均为真实风物目录
retail_products15候选删(待确认)仅 A 端 admin 展示用、零订单引用、C 端零调用;但 A 端仍在列,删后 A 端该目录清空
Tier-3 删除 retail_products 不影响 C 端(C 端从不调用),仅清空 A 端零售商品目录。是否删由义父决定;本方案默认保留。

四、/api/miniapp/retail/* C 端域核查结果

核查项结论
已发布包(前端调用)三套前端(含 miniprogram-v3)全仓 grep retail 零匹配;/api/miniapp/retail/* 无任何前端接线
定时任务(cron)7 个 cron(road/weather/order_housekeeping/ai_confirm/expire_demands/bills/message)无一调用 retail 端点
内部调用(后端互调)miniapp_retail 仅被 main.py:184 挂载,无后端模块 import 其函数;retail.py 的 console_router(A端) 与 miniapp_router(C端只读) 分离
结论C 端零售购买域 miniapp_retail.router(main.py:184)+ retail.miniapp_router 的 /api/miniapp/retail/products(main.py:195)均为死代码,可候选下线

保留项:A 端 retail.console_router(/api/miniapp/merchant-console/retail,main.py:194)独立、继续保留。

候选下线动作(需单独审批,未执行):


五、staging 验证记录(已做,未污染 staging)

在 staging PG16 库用完整删除顺序跑事务(含 guest_bindings 清理),结果:


六、prod 执行 SOP(仅义父批准后)

  1. 先取手术级单表 dump(§一)兜底。
  2. 单事务执行 Tier-1(及义父批准的 Tier-2);ON_ERROR_STOP=1,删前核对计数、删后核对 orders_t 与 goods/rp 不变。
  3. 回归 C 端:/health + GET /api/miniapp/products + GET /api/miniapp/orders(该用户应空) + 风物下单 _create_goods_order 路径。
  4. 若义父批准 Tier-3 删 retail_products,单独批次执行并回归 A 端 /api/admin/retail-products。
  5. 零售 C 端代码下线(§四)另走独立审批与 staging 复验。

七、待义父确认的事项(决策点)

  1. Tier-2:4 笔 is_test=f 测试单(6280–6283)是否一并删除?
  2. Tier-3:retail_products 15 行是否删除(默认保留)?
  3. 代码下线:/api/miniapp/retail/* C 端域是否进入下线实施(默认仅标记候选)?
  4. 确认后由波波按 §六 SOP 在 prod 执行,执行前再冻结复核。
本方案所有删除/下线动作均未执行,仅 staging 事务内验证(已回滚)。prod 全程冻结。