docs(management): 批次A计划评审修正——通话幽灵过滤+alembic head对齐
评审发现2真问题+5条cosmetic全修:
- recompute_call_days 补 known_user_ids 幽灵过滤(否则自家测试就挂)
- down_revision e6f7a8b9c0d1→f7a8b9c0d1e2(d428953 customer_account_link
已推head,照抄会双head报错)
- 测试计数9/文件数4/新增30/import声明/删占位SQL
This commit is contained in:
@@ -33,7 +33,7 @@
|
||||
| `yunke-server/app/storage/employee_metrics.py` | 宽表 + 通话小表生成 | 新建 |
|
||||
| `yunke-server/app/sync/cli.py` | 两条回填命令 | 修改 |
|
||||
| `yunke-server/tests/conftest.py` | `make_session` fixture | 修改 |
|
||||
| `yunke-server/tests/test_management_models.py` 等 5 个测试文件 | 判别性测试 | 新建 |
|
||||
| `yunke-server/tests/` 下 4 个新测试文件(test_management_models / test_first_reply_facts / test_lifecycle / test_employee_metrics) | 判别性测试 | 新建 |
|
||||
| `docs/superpowers/plans/2026-09-08-management-batch-a-verification.md` | Task 0 核实记录 | 新建 |
|
||||
| `docs/DEPLOY.md` | 两条回填命令部署注记 | 修改 |
|
||||
|
||||
@@ -110,15 +110,6 @@ WHERE p.channel='voice_call' AND p.call_number IS NOT NULL
|
||||
|
||||
- [ ] **Step 7: 选定 3-5 名回测员工**
|
||||
|
||||
```sql
|
||||
-- 消息量 top(高负载)
|
||||
SELECT s.user_id, s.name, SUM(m.msg_sent+m.msg_recv) AS msgs
|
||||
FROM stat_daily_staff s JOIN staff st ON s.user_id=st.user_id
|
||||
JOIN staff st2 ON st2.user_id=s.user_id, stat_daily_staff m -- (示意;实际写法见下)
|
||||
```
|
||||
|
||||
实际用(更直接):
|
||||
|
||||
```sql
|
||||
SELECT user_id, SUM(msg_sent+msg_recv) AS msgs FROM stat_daily_staff GROUP BY user_id ORDER BY msgs DESC LIMIT 5;
|
||||
SELECT user_id, SUM(msg_sent+msg_recv) AS msgs FROM stat_daily_staff WHERE channel='whatsapp' GROUP BY user_id ORDER BY msgs DESC LIMIT 3;
|
||||
@@ -292,7 +283,7 @@ cd yunke-server && .venv/Scripts/python.exe -m pytest tests/test_management_mode
|
||||
|
||||
- [ ] **Step 4: models.py 追加 6 个类**
|
||||
|
||||
在 `SensitiveScanState` 类之后、`__all__` 之前追加(文件头部已有所需 import:`String/Integer/BigInteger/Boolean/JSON/Text/Index/UniqueConstraint/mapped_column/Mapped/sa/dt/_updated_at`——若缺 `Text` 则补):
|
||||
在 `SensitiveScanState` 类之后、`__all__` 之前追加(文件头部已有所需 import:`String/Integer/BigInteger/Boolean/JSON/Text/Index/mapped_column/Mapped/sa/dt/_updated_at`;唯一约束与 Text 列走 `sa.UniqueConstraint`/`sa.Text`,无需新增顶层 import):
|
||||
|
||||
```python
|
||||
# ==========================================================================
|
||||
@@ -559,7 +550,7 @@ git commit -m "feat(management): 批次A六表模型——fact/宽表/通话小
|
||||
cd yunke-server && .venv/Scripts/python.exe -m alembic heads
|
||||
```
|
||||
|
||||
期望 `e6f7a8b9c0d1`(若不同,把迁移文件的 `down_revision` 改成实际 head)。
|
||||
期望 `f7a8b9c0d1e2`(customer_account_link 是当前链尾;若执行时又有新迁移合入,把迁移文件的 `down_revision` 改成实际 head)。
|
||||
|
||||
- [ ] **Step 2: 写迁移文件**
|
||||
|
||||
@@ -569,7 +560,7 @@ cd yunke-server && .venv/Scripts/python.exe -m alembic heads
|
||||
"""经营管理后台批次A:6 张新表(fact/宽表/通话小表/评分配置/快照/辅导)
|
||||
|
||||
Revision ID: b7c8d9e0f1a2
|
||||
Revises: e6f7a8b9c0d1
|
||||
Revises: f7a8b9c0d1e2
|
||||
Create Date: 2026-09-08
|
||||
|
||||
spec: docs/superpowers/plans/2026-09-08-yunke-management-console-implementation-v2.md §3。
|
||||
@@ -582,7 +573,7 @@ import sqlalchemy as sa
|
||||
from alembic import op
|
||||
|
||||
revision: str = "b7c8d9e0f1a2"
|
||||
down_revision: str | Sequence[str] | None = "e6f7a8b9c0d1"
|
||||
down_revision: str | Sequence[str] | None = "f7a8b9c0d1e2"
|
||||
branch_labels: str | Sequence[str] | None = None
|
||||
depends_on: str | Sequence[str] | None = None
|
||||
|
||||
@@ -737,7 +728,7 @@ def downgrade() -> None:
|
||||
cd yunke-server && .venv/Scripts/python.exe -m alembic upgrade head
|
||||
```
|
||||
|
||||
期望:输出包含 `Running upgrade ... -> b7c8d9e0f1a2`。再跑一次(幂等)应无操作。
|
||||
期望:输出包含 `Running upgrade f7a8b9c0d1e2 -> b7c8d9e0f1a2`。再跑一次(幂等)应无操作。
|
||||
|
||||
- [ ] **Step 4: 验证表存在 + downgrade 冒烟**
|
||||
|
||||
@@ -1096,7 +1087,7 @@ cd yunke-server && .venv/Scripts/python.exe -m pytest tests/test_first_reply_fac
|
||||
cd yunke-server && .venv/Scripts/python.exe -m pytest tests/ -q
|
||||
```
|
||||
|
||||
期望:10 passed;全量绿。
|
||||
期望:9 passed;全量绿。
|
||||
|
||||
- [ ] **Step 5: 提交**
|
||||
|
||||
@@ -1427,6 +1418,7 @@ async def recompute_call_days(session: AsyncSession, days) -> int:
|
||||
rev.setdefault(uid, []).append(owner)
|
||||
|
||||
written = 0
|
||||
staff_ids = await known_user_ids(session) # 幽灵过滤(v2 §1.3 #11)
|
||||
for day in sorted(set(days)):
|
||||
lo, hi = day_bounds_ms(day)
|
||||
calls = (
|
||||
@@ -1449,7 +1441,7 @@ async def recompute_call_days(session: AsyncSession, days) -> int:
|
||||
# duration 单位按 Task0 核实结论调整(默认秒;若毫秒在此换算)
|
||||
agg: dict[str, dict] = {}
|
||||
for uid, number, ts, dur in calls:
|
||||
if not uid:
|
||||
if not uid or uid not in staff_ids:
|
||||
continue
|
||||
a = agg.setdefault(
|
||||
uid, {"cnt": 0, "sec": 0, "answered": 0, "followup": 0}
|
||||
@@ -2057,7 +2049,7 @@ git commit -m "docs(management): 批次A回填实测+对账记录+DEPLOY部署
|
||||
- [ ] 同源判别测试通过(threads_answered ≡ fact 行数;多日未回串分母不膨胀);
|
||||
- [ ] 幽灵员工过滤测试通过;
|
||||
- [ ] 对账抽查:消息计数列与 msg_daily_stats friend 聚合一致;串类列差异全部可用跨夜串解释;
|
||||
- [ ] 全量测试套件绿(现有 ~575 + 新增 ~25);
|
||||
- [ ] 全量测试套件绿(现有 ~575 + 新增 30:模型 8 + fact 9 + lifecycle 7 + 通话/宽表 6);
|
||||
- [ ] 核实文档完整(五项核实 + 回测名单 + 回填耗时 + 对账记录);
|
||||
- [ ] 写钩子零改动(`git diff` 确认 summary.py/repos.py 未动)。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user