docs(plan): 吸收评审4条(groups路由实为model_validate免改/客户搜索需加q参数/moments调度+图片本地化补step/行号校正)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
浅念
2026-08-25 12:35:41 +08:00
parent 05a31022db
commit 2f73d79a6d
@@ -220,6 +220,12 @@ Run: `.venv/Scripts/python.exe -m pytest tests/test_scrape_moments.py -v` → PA
- [ ] **Step 7: full_sync_all.sh 加步**(media 步前):`echo "== moments ==" && python scripts/scrape_via_page.py --entity moments || true`(沿用脚本内既有步骤格式)
- [ ] **Step 7b: 调度接入 + 图片本地化**(spec §4.2 两项)
- 调度:`app/sync/scheduler.py` 的 4h job 是子进程跑 `--entity messages`——在该 job 的子进程序列**追加一次** `--entity moments --max-pages 3`(浅扫第一页有新才继续,朋友圈更新频率低);镜像现有 `_page_subprocess` 调用模式,勿新增 job
- 图片:`moments_post.image_urls` 是 OSS 直链(`wx.oss.yunkecn.com/friendstr/...`)。在 `scrape_media` 的媒体发现段加一个 moments 源(SELECT 未处理的 moments 行,image_urls 灌入 media 表,复用 message 图片的 URL 型下载路径);若 media 表按 `(kind, source_id)` 去重,kind 用 `moments_image`。执行时先读 `scrape_via_page.py:1838` 的 scrape_media 结构再动笔
- [ ] **Step 7c: 上面两处各加最小测试**(scheduler 若为纯配置列表则断言 moments 在序列;media 源加一行 fixtures 用例断言 URL 入 media 表)
- [ ] **Step 8: Commit**
```bash
@@ -279,7 +285,7 @@ async def test_groups_owner_fields(make_client):
- [ ] **Step 5: 回填脚本** `scripts/backfill_chat_group_fields.py`——镜像 `backfill_customer_add_time.py` 模式:SELECT 全部群,`raw_json` 缺列则提取 UPDATE;幂等;末尾打印 `backfilled N/M rows`
- [ ] **Step 6: schemas.py `GroupOut` 加 6 字段 + groups.py 路由输出**(该路由是显式构建 dict 的模式——找到构建处加键即可)
- [ ] **Step 6: schemas.py `GroupOut` 加 6 字段**——groups.py 用的是 `GroupOut.model_validate(row, from_attributes=True)`(groups.py:75 模式),**只需在 schema 加字段即可自动输出**,路由无需改
- [ ] **Step 7: 跑测试 + 回填存量**
@@ -887,7 +893,9 @@ async function runSearch() {
- [ ] **Step 1: 实现**
顶部:`微信客户|微信群` el-tabs + 搜索框(客户 tab placeholder 对齐云客「支持微信昵称、微信号、备注名、手机号搜索」→ 调 `/api/customers?q=` 检查现有参数名,若无 q 用 `keyword`——**查 customer.py 现有过滤参数后对齐**;群 tab placeholder「请输入群名称」→ `/api/groups` 的 room_name 过滤,无则前端过滤当前页)+ 按钮 `查询/导出(CSV复用 csvExport.ts 模式)/导出聊天记录(勾选后启用,串行 downloadBlob /export/chat-html)`。
顶部:`微信客户|微信群` el-tabs + 搜索框 + 按钮 `查询/导出(CSV复用 csvExport.ts 模式)/导出聊天记录(勾选后启用,串行 downloadBlob /export/chat-html)`。
**搜索实现前置**:`/api/customers`(customer.py)现状**没有**任何文本搜索参数(只有 channel/department_id/owner_account_id/friend_id/user_id/add_time_since/last_chat_since)。本任务先给 customer.py 加 `q: str | None`(`sa.or_(friend_nickname.like, friend_remark.like, friend_id.like, phone.like)`,几行+1 测试),客户 tab 搜索走它(placeholder 对齐云客「支持微信昵称、微信号、备注名、手机号搜索」);群 tab placeholder「请输入群名称」→ `/api/groups` 无 room_name 参数则前端过滤当前页。
客户表列(对齐云客 7+1):复选框(el-table selection)/客户微信(头像+昵称+friend_id 复用 StaffList 富单元格手法)/数据来源(固定「工作手机」)/客户备注名(friend_remark)/最近沟通时间(last_chat_time)/发送条数(send_num)/接收条数(receive_num)/操作(查看聊天记录→emit 跳 single+talkerId;导出HTML聊天记录→downloadBlob)。
@@ -960,7 +968,7 @@ async function viewChat(row: Account) {
// openCustomerChat 同理 wechat 分支 → { name: 'staff-chat', params: { ownerId, tab: 'single', talkerId } } + query 保留 start/end/msgid
```
- [ ] **Step 2: CustomerList.vue** 微信 tab「查看聊天记录」同样 wechat 分支切 staff-chat(找到现有跳转处,约 line 301 操作列)
- [ ] **Step 2: CustomerList.vue** 微信 tab「查看聊天记录」同样 wechat 分支切 staff-chat(现有跳转在 ~line 252-267 的 viewChat 及其 drawer 包装处,以「查看聊天记录」grep 定位为准)
- [ ] **Step 3: 全链路手动/Playwright 走查**(对照云客真机,逐项勾):
- 员工列表昵称→新页;资料卡四要素;5 导航切换 URL/内容
- 单聊:置顶区/已删除 tab/双模式搜索/默认窗/类型过滤/导出/msgid 定位