# 私聊日历纳入群聊互动：后端能力需求

## 问题与现状

私聊窗口包含直接聊天消息和双方在群内产生的互动卡片，但 `/api/v1/chats/session/statistics` 的 `daily_data` 目前只被用于直接消息统计。桌面已复用时间轴现有互动结果按天合并，不新增群历史扫描，也不把整群消息计入私聊。

现有互动来源优先为 world `/api/v1/interwoven-moments/inline-bootstrap`，兼容 chats `/api/v1/chats/interwoven/inline-bootstrap`。前者返回同一构建版本的已物化分组，但采集源仍可能 partial；后者目前请求 limit=100。分组预览也不天然等于完整历史明细。因此桌面当前只能承诺“私聊统计＋当前已加载、去重后的群聊互动卡片”，明确标示历史可能不完整，不能当作权威全历史总数。

## 目标口径（桌面和 Flutter 共用）

- 当前用户与指定联系人的私聊时间轴实际可见内容：直接消息 + 有权限查看的群聊互动卡片。
- 每张互动卡片计 1 条；按稳定 interaction/moment occurrence ID 去重，不能相加 group_count 与 preview_items，也不统计该群全部聊天消息。
- 转发到私聊的消息与群互动卡片是两条独立时间轴内容，按实际展示口径分别计数。若将来产品改为合并展示，两端和服务统计必须一起改。
- 直接消息按加入该私聊的时间分桶；互动按其 occurred_at 分桶，使用同一客户端时区参数。未来 IANA 时区能力须明确历史夏令时处理，不能静默改变当前固定偏移契约。
- 删除、撤回、退出群、成员权限变化、互动不可访问、功能关闭必须同步影响计数与可定位性。

## P0：日统计能力

优先扩展已有 session statistics，增加可选 `include_interwoven`（默认 false 保持旧客户端契约）；或提供独立互动日统计，由客户端合并。具体路由由后端确定，不要求重复维护一份未经版本关联的数据。

返回建议：

| 字段 | 含义 |
| --- | --- |
| bucket_date | YYYY-MM-DD |
| private_message_count | 当天可见直接消息数 |
| group_interaction_count | 当天去重互动卡片数 |
| total_count | 两类可见内容合计 |
| first_entry | 当天首项：kind=message/interaction，稳定定位 ID、发生时间；message 保留 owner/record ID |
| complete / source_status | 完整、构建中、部分失败、不可用，不能将失败当零条 |
| coverage_start / coverage_end | 当前统计覆盖的时间范围，明确是否含边界 |
| version / prepared_at | 统计快照版本和生成时间，与互动时间轴版本可对应 |

支持日期范围查询，按需返回所需月份；如已有全量稀疏日索引成本低，也可继续保留全量模式。不要要求客户端遍历每个群或下载消息正文后统计。

## P0：统一定位

已有 `/api/v1/chat/timeline/around` 以当前私聊 record owner/UID 定位。互动源记录属于群聊，不能把其 record ID 直接作为私聊消息锚点。

需要支持在原私聊上下文按 interaction ID 或 occurred_at 定位，返回对应私聊消息窗口、互动锚点、前后分页游标、权限与不存在状态。纯互动日期、两条私聊消息之间长时间间隔、早于第一条私聊的互动都必须可定位，不跳转到群、不从最新消息逐页扫描。

桌面当前兼容策略：已渲染互动直接定位；较早互动使用现有私聊日索引中的相邻私聊锚点读取有界上下文，再把目标互动纳入时间轴。没有私聊锚点但存在已授权互动时直接定位卡片。此策略不等于服务端提供了精确完整的混合时间轴窗口。

## P1：缓存及增量

- 支持 `since_version` 或等价条件请求；返回发生变化的日期桶，包括归零/删除的桶，避免客户端累计相加造成重复。
- 统计增量与互动列表增量使用相同构建版本；明确游标过期时的全量回退规则。
- 消息与互动新增、编辑导致日期变化、删除、撤回、权限变化时通知相关会话失效。
- 每次打开优先缓存；后台摘要刷新不触发全量群扫描，旧请求不得覆盖新版本。
- 按登录账号、对方身份、会话、时区隔离；账号切换清理，不能向无权限用户返回计数或锚点。

## 验收案例

1. 某天只有 2 张群互动卡片：日期可见，显示 2 条，点击在原私聊定位第一张卡片。
2. 同一天 3 条私聊 + 2 张互动：总计 5，首项按实际时间选取；重复 bootstrap 不重复累计。
3. 跨时区零点、同一原记录出现在不同关系、前后端返回乱序：分桶与时间轴一致。
4. 超过 100 条互动、多年历史、采集 partial：已知范围和完整性明确，未覆盖日期不能伪装为零。
5. 删除/撤回/失去权限后，日统计和锚点同步更新；清空某天也能通过增量反映。
6. 点击期间换会话、取消、重试、新旧响应倒序：不串会话、不跳回旧目标。

本文为待后端确认的接口需求，不表示这些扩展已部署。
