feat(groups): chat_group 补 6 群主/建群列 + 复合PK迁移修复 + 存量回填

对齐云客员工聊天窗口·微信群 tab(2026-08-25 真机验证 raw_json 键):
- ChatGroup 加列 owner_name/owner_wxid/owner_alias/owner_avatar/
  friend_count/create_time(全 nullable)
- scraper _normalize_chat_group 同名提取;createTime 兼容 ms-int 与
  'YYYY-MM-DD HH:mm:ss'(smoke.db 实测 1105 行全为后者),复用
  _parse_add_time 归一 ms-epoch
- 迁移 099ac2097fa2:加 6 列 + 修复 Task1 评审遗留 drift——PK 由单列
  room_id 变更为复合 (room_id, channel, owner_account_id) 且
  owner_account_id NOT NULL(对齐模型 8a99940;smoke.db 1105 行无 NULL,
  未兜底编造数据);SQLite 走 batch 重建(copy_from 显式旧结构),
  MySQL 渲染为直接 ALTER(离线 --sql 已验证)
- 回填脚本 scripts/backfill_chat_group_fields.py(幂等,逐列只补空);
  smoke.db 实跑 backfilled 1105/1105,重跑 0/1105
- GroupOut 加 6 字段(model_validate 自动输出,路由无改)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
浅念
2026-08-25 14:32:12 +08:00
parent 90c28f4c7b
commit 6ff288f1d3
7 changed files with 342 additions and 1 deletions
+48
View File
@@ -255,3 +255,51 @@ async def test_room_id_filter_returns_single_group(make_client):
body = r.json()
assert body["total"] == 1
assert body["items"][0]["room_name"] == "群二"
# ---------------------------------------------------------------------------
# 群主/建群补充列(2026-08-25 对齐云客员工聊天窗口·微信群 tab)
# raw_json 键 ownerName/ownerWchatId/ownerAlias/ownerImage/friendCount/createTime
# 由 scraper(_normalize_chat_group) 与 scripts/backfill_chat_group_fields.py
# 提取进同名列;API 直接输出列值。
# ---------------------------------------------------------------------------
async def test_groups_owner_fields(make_client):
async def seed(session):
session.add(ChatGroup(room_id="123@chatroom", channel="wechat", room_name="测试群",
owner_account_id="wxid_x", member_count=10,
owner_name="Q**e", owner_wxid="RL3*****108", owner_alias="Fr******er",
owner_avatar="https://wx.qlogo.cn/o/0", friend_count=22,
create_time=1740000000000,
raw_json={"ownerName": "Q**e", "ownerWchatId": "RL3*****108", "ownerAlias": "Fr******er",
"ownerImage": "https://wx.qlogo.cn/o/0", "friendCount": 22,
"createTime": 1740000000000}))
await session.commit()
client = await make_client(seed)
r = await client.get("/api/groups", params={"room_id": "123@chatroom"})
assert r.status_code == 200
item = r.json()["items"][0]
assert item["owner_name"] == "Q**e"
assert item["owner_wxid"] == "RL3*****108"
assert item["owner_alias"] == "Fr******er"
assert item["owner_avatar"] == "https://wx.qlogo.cn/o/0"
assert item["friend_count"] == 22
assert item["create_time"] == 1740000000000
async def test_groups_owner_fields_default_null(make_client):
"""未回填/上游缺失的行走 schema 默认值 null(不报错、不缺 key)。"""
async def seed(session):
session.add(ChatGroup(room_id="old@chatroom", channel="wechat",
owner_account_id="wxid_y"))
await session.commit()
client = await make_client(seed)
r = await client.get("/api/groups", params={"room_id": "old@chatroom"})
assert r.status_code == 200
item = r.json()["items"][0]
for key in ("owner_name", "owner_wxid", "owner_alias",
"owner_avatar", "friend_count", "create_time"):
assert item[key] is None