docs: 更新系统通知相关接口文档及问题修复记录
This commit is contained in:
+3
-2
@@ -1073,8 +1073,9 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
||||
**状态:需改造。**
|
||||
|
||||
- `GET /v1/im/system-notifications?cursor=` 返回 `id,event_type,title,summary,created_at,read_at,action`;实时刷新以 0.5.4.6 的 WS `{info what:"im|group"}` 业务事件为准,系统通知列表记录不等同于每一条实时事件。
|
||||
- `summary` 为服务端生成的可直接展示文案(如「对方已同意你的好友申请」「对方已婉拒你的好友申请」),前端直接渲染,无需再做状态码到文案的映射;`action` 读路径统一归一为 `{type,target_id,payload,...原始键}`。
|
||||
- 新设备登录事件内容为 `device_name,platform,ip_masked,login_at,security_action`;IP 只下发必要脱敏值。
|
||||
- 已读:`POST /v1/im/system-notifications/{id}/read`,带幂等键;跳转目标只接受服务端白名单 `action.type` 和内部参数。
|
||||
- 已读:`POST /v1/im/system-notifications/{id}/read`,带幂等键;重复已读返回首次持久化的 `read_at`,不回显本次提交值。跳转目标只接受服务端白名单 `action.type` 和内部参数。
|
||||
- 当前普通认证用户可向 `sys` Topic 发布的路径必须封禁。客户端不得渲染普通用户伪造的系统卡片为可信通知。
|
||||
|
||||
### 2.6 接口示例
|
||||
@@ -1093,7 +1094,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
||||
| --- | --- | --- |
|
||||
| `GET /v1/im/bootstrap` | Query only | `{"features":{"create_group":true,"user_search":true,"scan_qr":true,"system_notifications":true,"message_recall":true,"message_edit":true,"audio_call":true,"video_call":true},"permissions":{"create_group":true,"user_search":true,"scan_qr":true,"audio_call":true,"video_call":true},"entries":{"new_friends":{"enabled":true,"route":"/contacts/new-friends","unread_count":0},"groups":{"enabled":true,"route":"/contacts/groups","unread_count":0},"file_assistant":{"enabled":true,"route":"/chat/file-assistant","topic":"slf","unread_count":0},"system_messages":{"enabled":true,"route":"/chat/system","topic":"sys","unread_count":0}},"entry_badges":{"new_friends_pending_count":0,"groups_unread_count":0,"file_assistant_unread_count":0,"system_unread_count":0,"workbench_total_unread":0},"system_topic":{"topic":"sys","type":"system"},"message_policy":{"recall_window_seconds":120,"edit_window_seconds":300,"supported_actions":["copy","quote","delete","recall","edit"]},"security":{"realname":{"status":"unverified","required":false,"allow_skip":true,"remind_after":"24h"}}}` |
|
||||
| `GET /v1/im/search/conversations?q=&cursor=` | Query only | `{"items":[{"topic":"grp...","public":{"name":"项目群"},"private":{"pinned":false,"mute_notifications":false},"seq":12,"read":10,"recv":12,"unread":2,"updated_at":"2026-08-20T09:00:00Z"}],"next_cursor":""}` |
|
||||
| `GET /v1/im/system-notifications?cursor=&limit=20` | Query only | `{"items":[{"id":"evt_1","event_type":"friend.request.created","title":"新的好友申请","summary":"张三请求添加你为好友","action":{"type":"friend_request","request_id":"frq_1"},"read_at":null,"created_at":"2026-08-20T09:00:00Z"}],"next_cursor":""}` |
|
||||
| `GET /v1/im/system-notifications?cursor=&limit=20` | Query only | `{"items":[{"id":"evt_1","event_type":"friend.request.created","title":"新的好友申请","summary":"张三请求添加你为好友","action":{"type":"friend_request","target_id":"usr...","payload":{"request_id":"frq_1"},"request_id":"frq_1"},"read_at":null,"created_at":"2026-08-20T09:00:00Z"}],"next_cursor":""}` |
|
||||
| `POST /v1/im/system-notifications/{id}/read` | `{"read_at":"2026-08-20T09:00:00Z"}` | `{"status":"ok","id":"evt_1","read_at":"2026-08-20T09:00:00Z"}` |
|
||||
|
||||
## 3. 单聊会话、会话建立与消息状态
|
||||
|
||||
@@ -22,7 +22,6 @@ _2026-09-14 全面复核:本次对现有33条逐条重新核实(能实测的
|
||||
|---|---|---|
|
||||
| [问题25](#问题25) | `POST /messages/forward`、`/favorites/forward` | 带附言转发时 `head` 声明类型与 `content` 实际结构对不上 |
|
||||
| [问题27](#问题27) | `GET /reports/daily` | `status` 参数不做取值校验,传任何值都返回200+空列表 |
|
||||
| [问题30](#问题30) | `GET /system-notifications` | `summary`/`action`结构不一致,且会议响应事件被写成两条重复通知 |
|
||||
| [问题33](#问题33) | `GET /reports/daily` | `permissions` 四个字段恒为同一组硬编码值,与用户/参数无关 |
|
||||
| [问题35](#问题35) | `GET /users/{id}/profile` | 设了备注之后拿不到对方的原昵称(`GET /friends`一侧已修复) |
|
||||
| [新增3](#新增3) | `PATCH /conversations/{topic}/settings` | 单聊置顶没有批量查询接口,会话列表永远看不出置顶效果 |
|
||||
@@ -32,7 +31,6 @@ _2026-09-14 全面复核:本次对现有33条逐条重新核实(能实测的
|
||||
| [新增25](#新增25) | 原生WS `{pub}` | link类型消息协议层可构造,但没有真实用户可从UI触达的发送路径 |
|
||||
| [新增30](#新增30) | `GET /settings/youth-mode` | 开启后不对任何功能做实际限制,`enforced` 恒为硬编码false(前端已移除此功能,仅保留记录完整性) |
|
||||
| [新增31](#新增31) | `POST /reports/abuse` | 不校验 `requires_description`,可对必填原因提交空描述 |
|
||||
| [新增32](#新增32) | `POST /system-notifications/{id}/read` | 对已读通知重复标记,响应回显请求值但真实存储值不变 |
|
||||
| [新增34](#新增34) | `POST /tenant-applications` | 统一社会信用代码无去重机制,可无限重复提交 |
|
||||
| [新增41](#新增41) | `POST /groups/{topic}/mutes` | 无角色层级保护,管理员可禁言群主、任何角色可自我禁言 |
|
||||
| [新增47](#新增47) | `POST /v0/file/u/` | 真实文件上传上限是32MB而非声明的100MB,且从未用于前端预校验 |
|
||||
@@ -68,6 +66,8 @@ _2026-09-14 全面复核:本次对现有33条逐条重新核实(能实测的
|
||||
- **新增42**(群公告按id查询恒定返回最新公告):**已修复**。代码确认现在正确解析路径里的`announcement_id`并调用`GetAnnouncement`按id查询,不再无视这个参数。
|
||||
- **新增43**(群文件登记接口无长度/存在性校验):**已修复**。代码确认现在对`file_name`(255)/`mime_type`(128)做长度校验,对`file_size`做负数校验,且会调用`store.Files.Get`验证`file_id`真实存在。
|
||||
- **新增45**(收藏/搜索/宫格分页off-by-one永久丢失边界记录):**已修复**。实测:24条真实收藏,用limit=10分3页拉取(10+10+4),合并后24条一条不少、无重复。
|
||||
- **问题30**(系统通知`summary`/`action`结构不一致 + 会议响应事件双写):**已修复/已失效**(2026-10-09复核)。①会议响应双写随上游`0e2f4e7`(2026-09-17把整个workbench/会议模块从im_server移除)消失,现仅剩Kafka单路径写入且按固定event_id幂等upsert,不再适用;②`action`由读路径`normalizeSystemNotificationAction`统一归一为`{type,target_id,payload,...}`;③空`summary`读路径回退`title`;④机器码`summary`(`accepted`/`rejected`/`continue`/`cancel`)已在4处写入点改为人类可读文案(`serveIMFriendRequestAction`/`serveIMRiskChallengeConfirm`/`TenantFriendRequestAccept`/`TenantFriendRequestResolve`)。实测:A对B发好友申请、B拒绝后,A的通知列表返回`summary:"对方已婉拒你的好友申请"`、`action`为归一化结构。
|
||||
- **新增32**(系统通知重复已读,响应回显请求值但存储不变):**已修复**(2026-10-09复核)。存储层`TenantSystemNotificationMarkRead`在`COALESCE`更新后回读真实行返回,handler用返回值构造响应(单测`TestServeIMSystemNotificationsListAndRead`覆盖)。实测:同一通知先以`read_at=T1`标记已读、再以`T2`重复标记,两次响应均返回持久化的`T1`,不再回显本次提交值。
|
||||
|
||||
## 本次复核确认仍是历史误判(从未是真正的后端bug,不应再作为后端问题提出)
|
||||
|
||||
@@ -163,21 +163,6 @@ _2026-09-14 全面复核:本次对现有33条逐条重新核实(能实测的
|
||||
|
||||
---
|
||||
|
||||
<a id="问题30"></a>
|
||||
## 问题 30(P2):系统通知的 `summary` 要么是空串、要么是机器码,`action` 的结构因来源而异,且会议响应事件会被写成两条重复通知
|
||||
|
||||
**证据强度**:✅ 实测确认(三种summary情况+两条重复通知具体案例)+代码确认(重复通知根因)
|
||||
|
||||
**现象**:`summary`有时空串、有时机器码(如`accepted`/`rejected`)、有时真实数据;`action`是自由结构,不同来源放的键完全不同;会议响应更新会被两条独立代码路径各写一条内容几乎相同、结构不同的重复通知。
|
||||
|
||||
**根因(重复通知)**:`serveIMMeetingRespond`同时调用受开关`imReliableHTTPEventsEnabled`控制的`publishIMMeetingEvent`(生成`{meeting_id}`形态)和无条件执行的`publishIMWorkbenchAndAudit`(经Kafka产生`{module,resource_id}`形态),该开关对标准请求头调用恒为true。
|
||||
|
||||
**接口**:`GET /v1/im/system-notifications`
|
||||
|
||||
**前端现状**:`summary`能在已知事件码表里查到就替换成中文,查不到就原样显示;跳转按钮按action里出现的键分派;重复通知没有做任何去重(不能安全启发式判断"内容相同就是重复")。
|
||||
|
||||
---
|
||||
|
||||
<a id="问题33"></a>
|
||||
## 问题 33(P2):`permissions` 的四个字段在不同参数下恒为同一组值
|
||||
|
||||
@@ -285,19 +270,6 @@ _2026-09-14 全面复核:本次对现有33条逐条重新核实(能实测的
|
||||
|
||||
---
|
||||
|
||||
<a id="新增32"></a>
|
||||
## 新增 32(P2):系统通知已读接口对已有 `read_at` 的通知,响应会原样回显客户端提交的值,但真实存储值不变
|
||||
|
||||
**证据强度**:✅ 实测确认+代码确认(2026-09-14重读源码确认未变)
|
||||
|
||||
**现象**:对已有read_at的通知重复调用已读接口,响应200并原样回显本次提交的read_at(哪怕故意传明显不同值),但真实存储的read_at纹丝不动。
|
||||
|
||||
**根因**:`TenantSystemNotificationMarkRead`执行`UPDATE...SET read_at=COALESCE(read_at,?)`,已非空时保留原值;`serveIMSystemNotificationRead`(`server/im_http.go:3576`)直接回显请求体局部变量`readAt`,从未回读真实值。
|
||||
|
||||
**接口**:`POST /v1/im/system-notifications/{id}/read`
|
||||
|
||||
---
|
||||
|
||||
<a id="新增34"></a>
|
||||
## 新增 34(P2):企业注册申请接口对同一个统一社会信用代码没有任何去重/防重复提交机制
|
||||
|
||||
|
||||
@@ -1038,8 +1038,9 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
||||
**状态:需改造。**
|
||||
|
||||
- `GET /v1/im/system-notifications?cursor=` 返回 `id,event_type,title,summary,created_at,read_at,action`;实时刷新以 0.5.4.6 的 WS `{info what:"im|group"}` 业务事件为准,系统通知列表记录不等同于每一条实时事件。
|
||||
- `summary` 为服务端生成的可直接展示文案(如「对方已同意你的好友申请」「对方已婉拒你的好友申请」),前端直接渲染,无需再做状态码到文案的映射;`action` 读路径统一归一为 `{type,target_id,payload,...原始键}`。
|
||||
- 新设备登录事件内容为 `device_name,platform,ip_masked,login_at,security_action`;IP 只下发必要脱敏值。
|
||||
- 已读:`POST /v1/im/system-notifications/{id}/read`,带幂等键;跳转目标只接受服务端白名单 `action.type` 和内部参数。
|
||||
- 已读:`POST /v1/im/system-notifications/{id}/read`,带幂等键;重复已读返回首次持久化的 `read_at`,不回显本次提交值。跳转目标只接受服务端白名单 `action.type` 和内部参数。
|
||||
- 当前普通认证用户可向 `sys` Topic 发布的路径必须封禁。客户端不得渲染普通用户伪造的系统卡片为可信通知。
|
||||
|
||||
### 2.6 接口示例
|
||||
@@ -1058,7 +1059,7 @@ X-MeetingIM-APIKey: <预置的普通 API Key>
|
||||
| --- | --- | --- |
|
||||
| `GET /v1/im/bootstrap` | Query only | `{"features":{"create_group":true,"user_search":true,"scan_qr":true,"system_notifications":true,"message_recall":true,"message_edit":true,"audio_call":true,"video_call":true},"permissions":{"create_group":true,"user_search":true,"scan_qr":true,"audio_call":true,"video_call":true},"entries":{"new_friends":{"enabled":true,"route":"/contacts/new-friends","unread_count":0},"groups":{"enabled":true,"route":"/contacts/groups","unread_count":0},"file_assistant":{"enabled":true,"route":"/chat/file-assistant","topic":"slf","unread_count":0},"system_messages":{"enabled":true,"route":"/chat/system","topic":"sys","unread_count":0}},"entry_badges":{"new_friends_pending_count":0,"groups_unread_count":0,"file_assistant_unread_count":0,"system_unread_count":0,"workbench_total_unread":0},"system_topic":{"topic":"sys","type":"system"},"message_policy":{"recall_window_seconds":120,"edit_window_seconds":300,"supported_actions":["copy","quote","delete","recall","edit"]},"security":{"realname":{"status":"unverified","required":false,"allow_skip":true,"remind_after":"24h"}}}` |
|
||||
| `GET /v1/im/search/conversations?q=&cursor=` | Query only | `{"items":[{"topic":"grp...","public":{"name":"项目群"},"private":{"pinned":false,"mute_notifications":false},"seq":12,"read":10,"recv":12,"unread":2,"updated_at":"2026-08-20T09:00:00Z"}],"next_cursor":""}` |
|
||||
| `GET /v1/im/system-notifications?cursor=&limit=20` | Query only | `{"items":[{"id":"evt_1","event_type":"friend.request.created","title":"新的好友申请","summary":"张三请求添加你为好友","action":{"type":"friend_request","request_id":"frq_1"},"read_at":null,"created_at":"2026-08-20T09:00:00Z"}],"next_cursor":""}` |
|
||||
| `GET /v1/im/system-notifications?cursor=&limit=20` | Query only | `{"items":[{"id":"evt_1","event_type":"friend.request.created","title":"新的好友申请","summary":"张三请求添加你为好友","action":{"type":"friend_request","target_id":"usr...","payload":{"request_id":"frq_1"},"request_id":"frq_1"},"read_at":null,"created_at":"2026-08-20T09:00:00Z"}],"next_cursor":""}` |
|
||||
| `POST /v1/im/system-notifications/{id}/read` | `{"read_at":"2026-08-20T09:00:00Z"}` | `{"status":"ok","id":"evt_1","read_at":"2026-08-20T09:00:00Z"}` |
|
||||
|
||||
## 3. 单聊会话、会话建立与消息状态
|
||||
|
||||
Reference in New Issue
Block a user