Files
im_manager/docs/admin-adfahi-research/IM-Server改造文档.md
T

391 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# IM Server 改造文档:支撑鸽达达管理后台复刻
本文面向 `/Users/youshunlai/go_workspace/im_server` 的现状改造,目标是为 Admin Server 复刻鸽达达后台提供准确、稳定、可审计的数据与治理能力。当前 IM Server 已有 Tinode 风格实时链路、产品 HTTP API、独立租户库、Kafka 命令消费、配置事件消费、内部 Admin Query,但鸽达达 20 个后台页面仍需要补充若干查询资源、审计日志、风控策略与消息处置能力。
## 1. 当前实现现状
核心架构:
| 能力 | 现状 |
| --- | --- |
| 实时链路 | `Session -> Hub -> Topic -> Store`。 |
| 客户端入口 | WebSocket `/v0/channels`,产品 HTTP `/v1/im/...`。 |
| 后台只读入口 | `/internal/admin-query/tenants/{tenant_code}/...`,要求内部签名与 capability。 |
| 后台写操作 | Kafka Admin Command 消费器 `startKafkaAdminCommandConsumer`。 |
| 配置同步 | Kafka config event、cache invalidate consumer 已存在。 |
| 消息转发 | `/v1/im/messages/forward` 已存在。 |
| 音视频入会 | `/v1/im/calls/rtc-join` 已存在。 |
本地 `tinode` 库观察:`im_users` 有数据、`im_topics` 有群/会话、`im_subscriptions` 有订阅、`im_messages` 有大量单聊或通用消息、`im_group_messages` 有群消息、`im_feedback_submissions`、`im_abuse_reports`、`im_kafka_dead_letters` 等表已存在;`im_audit_logs` 本地为空,`im_devices` 和 `im_group_files` 数据不足,不能直接满足后台登录历史、设备历史和群文件验收。
已有内部查询资源:
| 资源 | 已支持字段/场景 |
| --- | --- |
| `users` | 用户 ID、账号、手机号、状态、资料、凭证摘要、最后在线。 |
| `user_devices` | 用户设备列表。 |
| `groups` | Topic、群名、群主、群状态、治理开关、成员数。 |
| `groups/{topic}/members` | 群成员。 |
| `group_join-requests`、`group_invitations`、`group_announcements`、`group_mutes`、`group_admin-logs`、`group_files` | 群治理专题资源。 |
| `messages/{topic}/{seq}` | 单条消息详情。 |
| `files`、`files/{id}`、`files/{id}/links` | 文件列表、详情、链接关系。 |
| `feedback-submissions`、`abuse-reports`、`realname-verifications`、`audit-logs` | 用户反馈、举报、实名、审计。 |
| `dashboard/summary` | 当前只返回待办类指标,不足以覆盖鸽达达首页统计。 |
已有 Kafka Admin Command:
| 命令 | 用途 |
| --- | --- |
| `user.ban`、`user.unban` | 用户封禁/解封。 |
| `user.freeze`、`user.unfreeze` | 用户冻结/解冻。 |
| `user.device.kick`、`user.logout_all` | 设备踢下线、全端登出。 |
| `user.account.cancel`、`user.account.delete`、`user.password.reset` | 注销、删除、重置密码。 |
| `group.profile.update` | 群资料更新。 |
| `group.governance.update` | 群治理开关更新。 |
| `group.admin.set`、`group.admin.remove`、`group.owner.transfer` | 群角色管理。 |
| `group.member.mute`、`group.member.unmute`、`group.member.remove` | 群成员治理。 |
| `kafka.dead_letter.replay`、`ignore`、`resolve` | 死信处理。 |
## 2. 改造原则
IM Server 只负责租户业务库的数据查询、业务状态变更、实时生效与审计事件产生,不直接依赖 HotGo 后台表。Admin Server 下发的配置、策略和治理命令必须具备幂等性,并通过事件结果回传 Admin。所有 internal query 必须保持只读、分页、最大 `per_page=200`、内部签名鉴权、字段脱敏。
响应协议继续沿用现有 `imHTTPResponse`:`code`、`data`、`reason`、`message`、`details`、`request_id`、`server_time`。写请求继续要求 `Idempotency-Key`,避免后台重复点击导致重复处置。
## 3. 支撑 20 个后台页面的 IM 改造
### 3.1 数据概览
现有 `dashboard/summary` 只覆盖死信、待处理 outbox、待实名、待举报、待反馈、活跃群、封禁用户等运营待办。需要新增统计字段以匹配鸽达达首页。
新增 internal query:
| 路径 | 方法 | 说明 |
| --- | --- | --- |
| `/internal/admin-query/tenants/{tenant}/dashboard/overview` | GET | 返回总用户、活跃用户、总群组、总会话、总消息、今日消息。 |
| `/internal/admin-query/tenants/{tenant}/dashboard/trends` | GET | 返回最近 N 天用户增长与消息增长。 |
字段口径:
| 字段 | 计算建议 |
| --- | --- |
| `total_users` | `im_users` 有效用户数。 |
| `active_users` | `last_seen` 在指定窗口内或当天有消息/登录行为的用户数。 |
| `total_groups` | `im_group_settings.group_status='active'` 或有效群 topic 数。 |
| `total_conversations` | 有效 P2P topic + group topic 数。 |
| `total_messages` | `im_messages` + `im_group_messages`,按最终存储口径去重。 |
| `today_messages` | 当天创建的消息数,按租户时区对齐。 |
| `date`、`user_count`、`message_count` | 趋势表行字段。 |
### 3.2 用户管理
现有 `users`、`users/{id}`、`users/{id}/devices` 基本可支撑。需要补足鸽达达页面要求的筛选和字段脱敏。
改造点:
| 项 | 内容 |
| --- | --- |
| 查询筛选 | 增加 `phone`、`public_account`、`state`、`created_at_start/end`、`last_seen_start/end`。 |
| 字段补充 | 返回 `nickname`、头像文件 ID、性别、地区、签名、认证方式摘要、设备数、最近登录 IP。 |
| 状态映射 | 将 Tinode `state` 转换为 Admin 字典所需状态;保留原始值 `raw_state` 便于排错。 |
| 治理命令 | 继续使用已有 `user.ban/unban/freeze/unfreeze/device.kick/logout_all/account.cancel/account.delete/password.reset`。 |
| 审计 | 每次状态变更、重置密码、踢设备必须写 `im_audit_logs` 并产出 Kafka command result。 |
枚举建议:`user_state` 包含正常、封禁、冻结、注销、删除;`device_platform` 包含 `ios`、`android`、`web`、`desktop`、`unknown`。
### 3.3 用户分组
当前 IM Server 没有看到独立的后台用户策略分组执行层。Admin 将新增策略分组后,IM Server 需要消费配置事件并在运行时执行。
新增能力:
| 能力 | 说明 |
| --- | --- |
| 策略缓存 | 按租户缓存 `policy_group`、成员关系、优先级与规则。 |
| 匹配入口 | 登录、注册、加好友、建群、入群、发消息、上传文件、发起音视频前匹配策略。 |
| 配置事件 | 消费 `user_policy_group.updated`、`user_policy_group.deleted`,刷新缓存。 |
| 命中审计 | 命中 `deny`、`challenge` 或高风险规则时写审计与风控日志。 |
策略动作枚举:`allow` 放行、`deny` 拦截、`challenge` 二次验证、`audit_only` 仅记录。
好友策略需要在后端覆盖所有移动端入口。禁止加好友时,IM Server 不能只让客户端隐藏按钮,而要在搜索用户、查看个人名片、群成员资料、二维码解析、好友申请、邀请注册自动加好友、推荐联系人等入口统一拦截或返回脱敏数据。策略字段建议包含 `allow_add_friend`、`direct_add_friend`、`max_friend_count`、`allow_qrcode_add_friend`、`allow_group_member_profile`、`hide_profile_when_friend_disabled`。
### 3.4 群组管理
已有 `groups` 查询与群治理命令可复用。需要补鸽达达群状态语义和可能的群封停动作。
改造点:
| 项 | 内容 |
| --- | --- |
| 字段 | 确保 `topic`、`group_name`、`owner_id`、`group_status`、`business_member_count`、`join_approval`、`mute_all`、`created_at` 可稳定返回。 |
| 状态 | 明确 `group_status` 值:`active`、`muted`、`suspended`、`dissolved`。 |
| 命令 | 已有资料更新、治理设置、角色与成员治理;若需求要求群封停/解封,新增 `group.suspend`、`group.unsuspend`。 |
| 审计 | 群资料、治理开关、解散、禁言、成员操作均写 `im_group_admin_logs` 与 `im_audit_logs`。 |
### 3.5 群成员管理
现有 `groups/{topic}/members` 与成员命令可支撑。需要确保成员列表返回群角色、禁言状态与入群时间。
字段建议:`topic`、`user_id`、`nickname`、`display_name`、`role`、`status`、`muted_until`、`joined_at`、`last_seen`。`role` 枚举为 `owner`、`admin`、`member`;`status` 枚举为 `active`、`muted`、`removed`。
按钮对应命令:设管理员 `group.admin.set`、取消管理员 `group.admin.remove`、转让群主 `group.owner.transfer`、成员禁言 `group.member.mute`、解除禁言 `group.member.unmute`、移除成员 `group.member.remove`。
### 3.6 邀请码管理
IM Server 注册链路已在 `user.go` 中记录邀请码使用,`RecordUse` 已存在。需要解决邀请码格式冲突:鸽达达需求为 6 位数字,既有 IM 文档曾要求 5 位 ASCII 字母。若严格复刻鸽达达,应将 IM 注册校验、错误提示、唯一性检查、大小写处理统一改为 6 位数字。
改造点:
| 项 | 内容 |
| --- | --- |
| 校验 | 仅允许 `^[0-9]{6}$`,不做大小写转换。 |
| 使用记录 | 注册成功后写 `im_registration_invite_uses`,包含 `code`、`user_id`、`request_id`、`used_at`。 |
| 并发 | 使用事务或唯一约束防止超发。 |
| 状态 | `unused`、`used`、`expired`、`revoked`。 |
### 3.7 单聊消息
当前只有单条消息 detail 查询,不足以支撑后台列表。需要新增 internal message list resource。
新增 internal query:
| 路径 | 方法 | 查询参数 |
| --- | --- | --- |
| `/internal/admin-query/tenants/{tenant}/private-messages` | GET | `topic`、`from_user_id`、`to_user_id`、`content_type`、`status`、`keyword`、`created_at_start/end`、`page`、`per_page`。 |
| `/internal/admin-query/tenants/{tenant}/messages/{topic}/{seq}` | GET | 已有,继续作为详情。 |
返回字段:`topic`、`seq_id`、`from_user_id`、`to_user_id`、`head`、`content_type`、`content_excerpt`、`status`、`created_at`、`updated_at`。全文内容只在详情返回,并根据 Admin 权限决定是否脱敏。
新增 Kafka 命令建议:`message.hide`、`message.unhide`、`message.delete`、`message.restore`。如果只允许软删除,命令语义必须明确为后台不可见还是客户端不可见。
### 3.8 群聊消息
新增 internal group message list resource。可读取 `im_group_messages` 或统一消息表,但需要确保与客户端可见状态一致。
路径:`/internal/admin-query/tenants/{tenant}/group-messages`。
筛选:`topic`、`sender_user_id`、`content_type`、`status`、`keyword`、`created_at_start/end`。返回字段在单聊基础上增加 `group_name`、`reply_to_seq`、`at_users`。
处置命令复用消息命令,审计动作记录为 `message.hidden`、`message.deleted`、`message.restored`。
### 3.9 敏感词库
IM Server 需要新增敏感词运行时,而词库主数据由 Admin 控制库维护。IM Server 只消费配置事件和执行匹配。
改造点:
| 项 | 内容 |
| --- | --- |
| 缓存 | 按租户加载敏感词,支持分组、场景、优先级、状态。 |
| 匹配场景 | 消息发送、编辑消息、用户昵称/签名、群名/公告、反馈/举报内容。 |
| 动作 | `block` 拦截、`replace` 替换、`review` 进入审核、`audit_only` 仅审计。 |
| 审计 | 命中记录写 `im_sensitive_word_hits` 或统一 `im_audit_logs`。 |
| 性能 | 正常词库用 AC 自动机或等价高效结构;正则词单独限量执行。 |
### 3.10 文件管理
已有 internal `files`、`files/{id}`、`files/{id}/links` 与文件生命周期 Kafka 基础。需要补后台预览、下载和处置一致性。
改造点:
| 项 | 内容 |
| --- | --- |
| 文件状态 | `normal`、`quarantined`、`deleted`、`orphan`。 |
| 审核状态 | 复用 `pending`、`running`、`clean`、`risky`、`failed`。 |
| 预览下载 | 提供短期签名 URL 或代理下载,禁止返回永久存储地址。 |
| 隔离删除 | 后台命令应更新文件状态、断开消息/群文件链接、写审计。 |
| 安全审核 | 接入内容安全/恶意文件检测结果,并可重试审核。 |
### 3.11 用户反馈
已有 `feedback-submissions` 资源可查询。需要补处理状态回写能力和状态审计。
新增能力:
| 能力 | 说明 |
| --- | --- |
| 状态更新 | 提供 Kafka 命令或内部写接口:`feedback.status.update`。 |
| 附件 | 通过文件链接查询反馈附件,并返回签名预览 URL。 |
| 分类 | 分类来自 `im_feedback_config.categories`,Admin 配置后 IM bootstrap 同步。 |
| 审计 | 处理人、处理备注、前后状态写入审计。 |
状态枚举:`received`、`processing`、`resolved`、`closed`。
### 3.12 操作日志
IM Server 需要补充业务侧审计完整性。当前本地 `im_audit_logs` 为空,不能支撑后台多页面审计。
写入场景:用户状态变更、群治理、消息处置、文件处置、反馈处理、敏感词命中、登录成功/失败、配置热更新、Kafka 命令执行结果。
字段:`request_id`、`actor_user_id`、`action`、`target_type`、`target_id`、`ip`、`user_agent`、`detail`、`created_at`。`detail` 中敏感值必须脱敏或存 hash。
### 3.13 用户账号审计
新增或扩展 internal resource `user-account-audit`,按用户聚合账号生命周期事件。
路径:`/internal/admin-query/tenants/{tenant}/user-account-audit`。
筛选:`user_id`、`action`、`operator_id`、`ip`、`created_at_start/end`。返回:`event_id`、`user_id`、`action`、`operator_type`、`operator_id`、`before_state`、`after_state`、`reason`、`ip`、`device_id`、`created_at`。
动作枚举:`registered`、`login_success`、`logout`、`login_failed`、`password_changed`、`password_reset`、`banned`、`unbanned`、`frozen`、`unfrozen`、`device_kicked`、`cancelled`、`deleted`。
### 3.14 群事件审计
已有 `im_group_admin_logs` 与 group outbox,可新增 internal resource `group-event-audit` 或复用 `group_admin-logs` 扩展为全局查询。
路径:`/internal/admin-query/tenants/{tenant}/group-event-audit`。
筛选:`topic`、`operator_id`、`target_user_id`、`action`、`created_at_start/end`。返回:`event_id`、`topic`、`operator_id`、`target_user_id`、`action`、`object_type`、`object_id`、`before_data`、`after_data`、`created_at`。
### 3.15 管理员登录历史
该页面主要由 Admin Server 的 HotGo 登录日志提供,IM Server 无需改造。若以后要展示 Admin 调用 IM internal API 的访问审计,可在 internal API 层增加 `internal_api_access_logs`,但不作为复刻 P0。
### 3.16 用户登录历史
当前缺少完整登录历史表与查询。需要在认证成功、token 刷新、主动/被动登出时记录日志。
新增表建议:`im_user_login_logs`。
字段:`id`、`user_id`、`login_type`、`device_id`、`platform`、`ip`、`region`、`user_agent`、`request_id`、`result`、`login_at`、`logout_at`、`created_at`。
新增 internal query:`/internal/admin-query/tenants/{tenant}/user-login-logs`,支持按 `user_id`、`phone/account`、`ip`、`platform`、`login_at_start/end` 查询。
### 3.17 IP 账号统计
新增聚合查询,来源为注册、登录成功、登录失败、风控命中日志。
路径:`/internal/admin-query/tenants/{tenant}/ip-account-stats`。
字段:`ip`、`region`、`user_count`、`register_count`、`login_count`、`failure_count`、`first_seen_at`、`last_seen_at`、`risk_level`。该接口可以实时聚合,也可以由定时任务写入快照表以降低查询成本。
### 3.18 登录失败日志
新增表建议:`im_login_failure_logs`。
字段:`id`、`account`、`user_id`、`failure_type`、`reason`、`ip`、`region`、`device_id`、`platform`、`user_agent`、`request_id`、`attempt_at`。
新增 internal query:`/internal/admin-query/tenants/{tenant}/login-failure-logs`。失败类型枚举:`password_error`、`code_error`、`account_not_found`、`account_disabled`、`rate_limited`、`risk_blocked`。
### 3.19 私域设置
IM Server 需要确保客户端 `/v1/im/bootstrap` 使用 Admin 发布后的配置,并支持热更新。
配置来源:
| 配置 | 使用位置 |
| --- | --- |
| 注册/邀请码/短信 | 注册、验证码、密码找回。 |
| 上传/文件审核 | 上传、预览、消息附件。 |
| 反馈/邮箱/通知 | 客户端入口与提交表单。 |
| 版本/工作台 | bootstrap、app release、workbench。 |
| 声网/音视频 | `/v1/im/calls/rtc-join`。 |
| 好友功能 | `/v1/im/bootstrap` 返回 `global_friend_enabled`、入口隐藏建议和提示文案;实际拦截由后端完成。 |
| 消息宵禁 | `/v1/im/bootstrap` 返回当前宵禁摘要和提示文案;发送消息时仍以后端实时校验为准。 |
改造点:配置事件必须带版本号;IM 缓存应支持按租户回滚到上一发布版本;bootstrap 返回的配置只包含客户端需要的非敏感字段。
### 3.20 安全策略
IM Server 是安全策略的执行层。需要将 Admin 发布的策略接入登录、验证码、消息、文件、群、好友、实名、音视频等关键入口。全局禁止加好友和宵禁必须后端强制执行,客户端展示仅作为体验优化。
策略项:
| 策略 | 执行点 |
| --- | --- |
| 密码强度 | 注册、改密、重置密码。 |
| 登录限频 | 登录、验证码校验、密码找回。 |
| IP 黑白名单 | 登录、注册、发消息、上传文件。 |
| 敏感词 | 消息、资料、群资料、反馈。 |
| 文件审核 | 上传完成、消息发送前后、后台重审。 |
| 实名要求 | 加好友、建群、入群、发起音视频等敏感能力。 |
| 风控挑战 | 登录异常、IP 异常、设备异常。 |
| 全局好友功能 | 用户搜索、好友申请、二维码解析、群成员资料、个人名片、推荐联系人、邀请注册自动加好友。 |
| 消息宵禁 | 单聊/私聊发送消息入口,默认拦截 P2P topic 的 `{pub}`;如产品确认群聊也管控,可扩展到 group topic。 |
动作枚举统一为 `allow`、`challenge`、`block`、`audit_only`。
全局禁止加好友执行规则:
| 入口 | 后端行为 |
| --- | --- |
| 用户搜索 `/v1/im/users/search` | 可直接返回空列表,或返回脱敏结果但不允许发起好友申请。 |
| 用户详情 `/v1/im/users/{id}` | 非好友场景隐藏手机号、账号、二维码、个人扩展资料,只保留必要公开字段。 |
| 好友申请 `/v1/im/friend-requests` | 返回业务错误 reason,例如 `FRIEND_DISABLED`。 |
| 二维码解析 `/v1/im/qrcodes/resolve` | 禁止解析出可加好友目标,或返回脱敏提示。 |
| 群成员资料 | 群成员列表可保留昵称/头像用于群聊展示,但点击个人信息时返回脱敏资料并禁止添加。 |
| 邀请注册自动加好友 | 注册成功后跳过自动加好友并写审计,或按策略直接拒绝该邀请码能力。 |
宵禁执行规则:
| 项 | 说明 |
| --- | --- |
| 配置 | `message_curfew_enabled`、`message_curfew_rules`,规则包含时区、日期类型、开始时间、结束时间、scope、白名单、提示文案。 |
| 判断时机 | P2P topic 发布消息前校验;HTTP 消息发送、转发、草稿转发送等入口也要校验。 |
| 拦截结果 | 返回明确 reason,例如 `MESSAGE_CURFEW_ACTIVE`,并记录 `im_audit_logs` 或风控日志。 |
| 白名单 | 支持用户、系统账号、特定会话豁免。 |
| 跨天 | 支持如下班后 `18:00-09:00` 的跨天时间段。 |
## 4. Internal Admin Query 新增清单
建议在 `server/internal_admin_query_resources.go` 增补资源,并在 `server/internal_api.go` 路由分发中注册:
| 资源 | 必要性 | 说明 |
| --- | --- | --- |
| `dashboard/overview`、`dashboard/trends` | P0 | 首页统计。 |
| `private-messages`、`group-messages` | P0 | 消息管理列表。 |
| `user-login-logs`、`login-failure-logs` | P0 | 登录审计。 |
| `ip-account-stats` | P1 | IP 风险聚合。 |
| `user-account-audit`、`group-event-audit` | P1 | 专题审计。 |
| `sensitive-word-hits` | P1 | 敏感词命中查询。 |
所有列表接口返回现有结构:`items`、`total`、`page`、`per_page`。时间筛选继续使用 `created_at_start`、`created_at_end` 等字段,UID 参数继续支持数字 ID 与 `usr...` 编码。
## 5. Kafka 命令新增清单
已有用户与群治理命令保留。为复刻后台补充以下命令:
| 命令 | 说明 |
| --- | --- |
| `message.hide` | 后台隐藏消息,客户端不可见或后台标记隐藏。 |
| `message.unhide` | 恢复隐藏消息。 |
| `message.delete` | 后台删除消息,建议软删除。 |
| `message.restore` | 恢复误删消息。 |
| `file.quarantine` | 文件隔离。 |
| `file.delete` | 文件删除。 |
| `feedback.status.update` | 反馈处理状态更新。 |
| `group.suspend`、`group.unsuspend` | 如产品确认需要群封停/解封,则新增。 |
| `security.policy.reload` | 强制刷新安全策略缓存。 |
| `friend.policy.reload` | 强制刷新好友入口策略缓存,可与 `security.policy.reload` 合并实现。 |
| `curfew.policy.reload` | 强制刷新宵禁策略缓存,可与 `security.policy.reload` 合并实现。 |
命令 payload 必须包含 `command_id`、`actor_user_id`、`reason`、目标 ID、`version` 或 `expected_version`。执行后发布 result,状态为 `success`、`failed`、`dead`。
## 6. 数据库改造建议
配套建表与兼容迁移脚本见 [`sql/IM-Server改造.sql`](sql/IM-Server改造.sql)。脚本默认使用本地 `tinode`,上线时必须对每个独立租户数据库分别执行,租户业务表不增加 `tenant_id`。
租户库新增或补强表:
| 表 | 用途 |
| --- | --- |
| `im_user_login_logs` | 用户登录成功、登出、刷新等历史。 |
| `im_login_failure_logs` | 登录失败与风控拦截历史。 |
| `im_message_admin_actions` | 后台消息处置记录,可与消息表状态解耦。 |
| `im_sensitive_word_hits` | 敏感词命中记录。 |
| `im_ip_account_stats_daily` | IP 账号统计快照,可选。 |
已有表需补数据写入:`im_audit_logs` 当前本地为空,需要在关键业务入口统一写;`im_devices` 本地为空,需要确认设备绑定/解绑路径是否完整;`im_group_files` 本地为空,需要验证群文件写入链路。
索引建议:消息列表按 `(topic, created_at)`、`(from, created_at)`;登录日志按 `(user_id, login_at)`、`(ip, login_at)`;失败日志按 `(account, attempt_at)`、`(ip, attempt_at)`;敏感词命中按 `(scene, created_at)`、`(user_id, created_at)`。
## 7. 验收要求
1. Admin 20 个页面的查询按钮均能通过 internal query 返回真实数据或标准空态。
2. 用户、群、消息、文件、反馈的后台写操作均通过 Kafka 命令,具备幂等、结果回传、死信处理。
3. 登录历史、失败日志、账号审计、群事件审计不再依赖空表,关键入口可产生真实审计数据。
4. 敏感词与安全策略变更可热更新,无需重启 IM Server。
5. 所有 internal query 均保持只读、分页、鉴权、脱敏和错误 reason 规范。
6. 邀请码格式在 Admin 与 IM 注册链路完全一致,避免后台生成后客户端无法使用。