fix(management): 期聚合active_friends按(uid,peer)去重——多账号共享客户不再双计;reply计数并入Python/单一METRIC_VERSION
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
- 宽表 SUM 按 (day∈窗, metric_version='v1', channel) 过滤;
|
||||
active_rooms_avg 摊到全窗天数(含无数据日);
|
||||
- 期末生命周期存量=每 (user, channel) 最新 ≤end 行,跨渠道相加;
|
||||
- distinct 活跃客户=窗内 (owner, peer) 去重(peer_kind='friend');
|
||||
- distinct 活跃客户=窗内 (uid, peer) 去重(peer_kind='friend')——
|
||||
同一员工多账号的共享客户只计 1(与宽表日值口径一致);
|
||||
- 窗口工具:闭区间 day_range/等长前窗/28 天个人基线窗;
|
||||
- 幽灵员工(不在 staff)过滤;user_ids 交集;通话恒全渠道。
|
||||
"""
|
||||
@@ -159,6 +160,22 @@ async def test_distinct_active_cross_day(make_session):
|
||||
assert m["u1"].active_friends == 2
|
||||
|
||||
|
||||
async def test_active_friends_shared_peer_across_accounts(make_session):
|
||||
"""多账号共享客户去重:u1 的 wx1/wx3 都会话 p1 → active_friends=1
|
||||
(账号归并到员工后按 peer 去重,非 (owner, peer) 双计)。"""
|
||||
s = make_session
|
||||
await _seed_org(s)
|
||||
s.add(WechatAccount(wx_id="wx3", user_id="u1"))
|
||||
await s.commit()
|
||||
for owner in ("wx1", "wx3"):
|
||||
s.add(MsgDailyStats(channel="wechat", owner_account_id=owner,
|
||||
peer_kind="friend", peer_id="p1", day=20260901))
|
||||
await s.commit()
|
||||
m = await period_metrics(s, 20260901, 20260905, "wechat")
|
||||
assert m["u1"].active_friends == 1
|
||||
assert m["u2"].active_friends == 0
|
||||
|
||||
|
||||
def test_window_helpers():
|
||||
# day_range 闭区间 + 月末边界
|
||||
assert day_range(20260901, 20260903) == [20260901, 20260902, 20260903]
|
||||
@@ -193,6 +210,7 @@ async def test_ghost_and_channel_none(make_session):
|
||||
assert set(m) == {"u1", "u2"} # ghost 不在;零数据 u2 在
|
||||
u1 = m["u1"]
|
||||
assert u1.msg_sent == 7 # 两渠道行都归 u1
|
||||
assert u1.days_with_data == 1 # 双渠道同日只计 1 天(DISTINCT day)
|
||||
assert u1.fr_p50_ms == 100_000 # [100s,300s] 合并后 ceil(0.5*2)=1
|
||||
assert u1.fr_p90_ms == 300_000 # ceil(0.9*2)=2
|
||||
assert u1.reply_2h_count == 2
|
||||
|
||||
Reference in New Issue
Block a user