docs(plan): 补续作入口与 P0 踩坑留档(外部表结构核实、uv.lock、容器验证姿势)

This commit is contained in:
yml2213
2026-10-02 22:54:36 +08:00
parent d669552be8
commit 5995f16c39
+39 -8
View File
@@ -1,7 +1,16 @@
# 自动化与资料收集规划
更新时间:2026-10-02
状态:**P1a(CK 自动巡检)已落地**,P0/P2/P3/P4/P1b 待排期。产品决策已确认(见 §4),施工单见附录 C。
状态:**P1a(CK 巡检)+ P1b(CK 自动重登)已上线**;**P0 适配层已完成并真机验证(无接口/页面、开关仍关、生产未跑迁移)**;下一步 P2。产品决策已确认(见 §4),施工单见附录 C。
> ### 🔜 续作入口(下一个会话先看这里)
>
> 1. **当前该做 P2(资料收集链接 + OSS 上传)**,施工顺序见 **§C.5**,下一个迁移编号 **`20261002_0040`**;
> 2. P0 的适配层已就绪(`services/external_order_source.py`,`lookup_order()` 直接可用),
> P2 做「用户填订单号后回显商品」时**直接调它**,不要重写跨库 SQL;
> 3. P0 遗留三件事(要真正启用时才做):生产跑迁移 0039 建表、`.env` 开 `ORDER_SITE_LOOKUP_ENABLED`、补查询接口/页面(见 §C.4-bis);
> 4. 上手前必读 **§C.2 通用约定**(方言、时区、环境变量三处同步、迁移编号取号规则、
> 「动手前先核实外部库真实表结构」)与 **§C.3 已核实的环境事实**。
---
@@ -1095,6 +1104,10 @@ pending_material(待用户补资料) ← 模板有必填字段时的
**建议顺序:P1a → P1b → P0 → P2 → P3 → P4。**
- **P1a 已上线**(2026-10-02),只做「帮你把失效 CK 找出来」,零风险;
- **P1b 已上线**(2026-10-02):20 个失效账号实测 20/20 重登成功、零极验;当前 30 条/轮、约 97% 成功率,待重登积压约 3.6k 正在消化;
- **P0 已过半**(2026-10-02):适配层 + 迁移 0039 已完成并真机验证(三桶判定全对、3.3ms、540 个重复订单号正确拦下),
**但只有底层适配层:无接口、无页面,且生产开关仍是 `false`、迁移未在生产跑**。
接口与页面按 §6.4 的调用点(用户填订单号时)随 P2 一起上;
- **P1b 提到 P1a 之后**:原计划等一到两周观察期,但线上数据已把三个前提验证完了 —— 检测结果与人工/直连逐条一致、误判路径已封(三类判定 + 自动暂停)、失效性质查清(会话过期而非凭证问题)。不联动的话,巡检每天翻出失效清单却没人兑现修复,1,356 个账号只会越积越多;
- **P0 随时可做**:只动本系统,order_site 侧代码改动量为 0;
- **P1b 开关仍默认关闭**,按 §7.4.7 三段上线:小规模实测 → 限量开 → 全量;
@@ -1298,8 +1311,9 @@ OSS_PREFIX=collect
| 阶段 | revision | 说明 |
| --- | --- | --- |
| P1a(已落地) | `20261002_0037` | `automation_jobs` / `automation_runs` / `login_tasks` +3 / `accounts.auto_managed` |
| P0 | 落地时取下一个 | `external_order_cache` |
| P2 / P3 / P4 | 各自落地时依次取号 | 见附录 A 的表清单 |
| P1b(已落地) | `20261002_0038` | `login_tasks` + `relogin_failure_kind` |
| P0(已落地) | `20261002_0039` | `external_order_cache` |
| P2 / P3 / P4 | 各自落地时依次取号(**下一个是 `20261002_0040`**) | 见附录 A 的表清单 |
> **为什么不能预留编号**:Alembic 的 `down_revision` 必须形成单链。若先给 P1 占 0038、
> 把 0037 留给 P0,等 P0 真落地时它的 `down_revision` 只能指向 0038(否则与 0038 平级,
@@ -1340,7 +1354,24 @@ OSS_PREFIX=collect
`TypeError: can't compare offset-naive and offset-aware`(P1a 踩过一次)。比较前一律用
`_as_utc()`(`services/yyb_service.py` 与 `services/automation/scheduler.py` 各有一份)补时区。
SQL 里用绑定参数比较不受影响,只有 Python 侧比较需要注意 —— P0 判缓存过期时会再遇到;
- **每个阶段独立可发布**,新作业/新功能一律**开关默认关闭**。
- **每个阶段独立可发布**,新作业/新功能一律**开关默认关闭**;
- **⚠️ 动手前先核实外部库的真实表结构,别信文档和早期分析**(P0 踩过一次,差点白干):
规划 §6.2 写的 `orders.order_no`(PK) 在真实库里**根本不存在**,实际是
`platform_order_id`(且**非唯一**,541 组重复)。同一订单号下还有「发货方内部行 +
真实店铺行」的成对结构,**按单行判 route 会放行 540 个已发货订单**。
做法:先用只读账号 `SELECT column_name FROM information_schema.columns` 核对一遍,
再把结论写进文档(§6.5.1 就是这么留档的)。**跨系统的字段假设一律当作待验证**;
- **加依赖后必须重锁 `uv.lock`**:Dockerfile 用的是 `uv sync --frozen`(见 §C.3),
只改 `pyproject.toml` 不重锁,生产构建会直接失败。P0 加 `psycopg[binary]` 时走过一遍:
本地 `uv lock` + `uv sync`,提交时带上 `uv.lock`;
- **验证容器里的代码要 `docker cp`,挂载只有 logs/data**:compose 只 bind 了
`/root/live-hub-py/logs` 与 `/data`,**代码在镜像里**。改完宿主机文件不会自动生效;
临时验证用 `docker cp` 进 `/app`,之后**记得删掉**,别污染生产工作区(会让 `git pull` 起冲突);
- **容器里装包要用 `uv pip` 且指定 `VIRTUAL_ENV`**:容器的 `/app/.venv` 里**没有 pip**,
系统 `pip` 装的东西 venv 里的 python 看不见(P0 验证时白装过一次)。正确姿势:
`docker exec -w /app <容器> env VIRTUAL_ENV=/app/.venv uv pip install <包>`;
另:`docker exec -e` 覆盖不了 compose 已注入的同名变量,验证时改用容器自带的 env
或在脚本里 `os.environ[...] = ...`。
### C.3 已核实的环境事实
@@ -1349,10 +1380,10 @@ OSS_PREFIX=collect
| uvicorn worker 数 | **`--workers 1`**(单容器单进程) | 进程内调度线程安全,**不需要分布式锁**;调度器在 lifespan 里启停 |
| 生产路径 | `/root/live-hub-py`,容器 `live-hub-py-douyu-login-1` | 部署 = `git pull` + `./deploy.sh` |
| 鉴权 | **无全局中间件**,逐路由 `Depends(get_current_user)` | 公开路由只要不挂依赖;新路由要在 `main.py` 注册 |
| PG 驱动 | 容器内**没有**,需新增 `psycopg[binary]`(已定) | P0 第一步就是加依赖 + 重建镜像 |
| 只读 PG | `livehub_ro` @ `order_site-postgres-1:5432`,`.env` 已配 | 适配层直接用 `ORDER_SITE_DATABASE_URL` |
| OSS | 桶 `live-hub-assets`(私有+版本控制)、RAM `live-hub-oss`、`.env` 已配 | `oss2`;**不要用 HeadBucket** |
| 迁移 head / 测试基线 | `20261001_0036` / 235 条 | 见 C.1 |
| PG 驱动 | `psycopg[binary]` 已加入 `pyproject.toml` + `uv.lock`(2026-10-02);**生产镜像尚未重建** | 部署 P0 时会随镜像重建装上;临时验证已在容器里手工装过 |
| 只读 PG | `livehub_ro` @ `order_site-postgres-1:5432`,`.env` 已配(容器内 3 个 `ORDER_SITE_*` 均可见) | 适配层直接用 `ORDER_SITE_DATABASE_URL`;**`LOOKUP_ENABLED` 仍是 `false`** |
| OSS | 桶 `live-hub-assets`(私有+版本控制)、RAM `live-hub-oss`、`.env` 已配 | P2 用 `oss2`;**不要用 HeadBucket** |
| 迁移 head / 测试基线 | `20261002_0039` / 328 条(2026-10-02) | 见 C.1;生产库**尚未**跑 0039 |
### C.4 P1a 施工单(✅ 已按此完成,8 步)