Room 模块设计文档
1. 概述
Room 模块是本系统核心的协作与消息通信功能模块,提供稳定、高效、可扩展的实时消息平台。系统采用 Rust (Actix-web) 后端 + React 19 前端的技术栈,通过 WebSocket 实现实时通信,集成了 AI 代理进行智能协作。
技术栈
- 后端: Rust + Actix-web + SeaORM + Redis + NATS
- 前端: React 19 + TypeScript + Tailwind CSS
- 实时通信: WebSocket (自定义协议)
- 消息队列: NATS (事件分发)
- 缓存: Redis (序列号管理、去重)
2. 数据模型
2.1 核心表结构
room - 房间表
| 字段 |
类型 |
说明 |
| id |
UUID (v7) |
主键,时间排序 |
| project |
UUID |
所属项目 |
| room_name |
VARCHAR(128) |
房间名称 |
| public |
BOOLEAN |
是否公开房间 |
| category |
UUID (nullable) |
所属分类 |
| created_by |
UUID |
创建者 |
| created_at |
TIMESTAMPTZ |
创建时间 |
| last_msg_at |
TIMESTAMPTZ |
最后消息时间 |
room_message - 消息表
| 字段 |
类型 |
说明 |
| id |
UUID (v7) |
主键 |
| seq |
BIGINT |
全局序列号(递增) |
| room |
UUID |
所属房间 |
| sender_type |
ENUM |
member / ai / system |
| sender_id |
UUID (nullable) |
发送者 ID |
| thread |
UUID (nullable) |
所属线程 |
| in_reply_to |
UUID (nullable) |
回复的消息 ID |
| content |
TEXT |
消息内容 |
| content_type |
ENUM |
text / markdown / code / mention |
| edited_at |
TIMESTAMPTZ (nullable) |
编辑时间 |
| send_at |
TIMESTAMPTZ |
发送时间 |
| revoked |
TIMESTAMPTZ (nullable) |
撤回时间 |
| revoked_by |
UUID (nullable) |
撤回操作者 |
room_member - 房间成员表
| 字段 |
类型 |
说明 |
| room |
UUID |
房间 ID |
| user |
UUID |
用户 ID |
| role |
ENUM |
Owner / Admin / Member |
| first_msg_in |
TIMESTAMPTZ (nullable) |
首次发消息时间 |
| joined_at |
TIMESTAMPTZ (nullable) |
加入时间 |
| last_read_seq |
BIGINT (nullable) |
已读序列号 |
| do_not_disturb |
BOOLEAN |
免打扰 |
| dnd_start_hour |
INT (nullable) |
DND 开始小时 |
| dnd_end_hour |
INT (nullable) |
DND 结束小时 |
room_category - 频道分类表
| 字段 |
类型 |
说明 |
| id |
UUID |
主键 |
| project |
UUID |
所属项目 |
| name |
VARCHAR(64) |
分类名称 |
| position |
INT |
排序位置 |
room_thread - 线程表
| 字段 |
类型 |
说明 |
| id |
UUID |
主键 |
| room |
UUID |
所属房间 |
| parent_message |
UUID |
父消息 ID |
| created_by |
UUID |
创建者 |
| created_at |
TIMESTAMPTZ |
创建时间 |
room_ai - AI 配置表
| 字段 |
类型 |
说明 |
| room |
UUID |
房间 ID |
| model |
UUID |
AI 模型 ID |
| version |
VARCHAR (nullable) |
模型版本 |
| call_count |
INT |
调用次数 |
| last_call_at |
TIMESTAMPTZ (nullable) |
最后调用时间 |
| history_limit |
INT |
上下文历史限制 |
| system_prompt |
TEXT |
系统提示词 |
| temperature |
FLOAT |
温度参数 |
| max_tokens |
INT |
最大 token 数 |
| use_exact |
BOOLEAN |
精确模式 |
| think |
BOOLEAN |
思考模式 |
| stream |
BOOLEAN |
流式输出 |
| min_score |
FLOAT (nullable) |
最小分数阈值 |
room_message_reaction - 消息反应表
| 字段 |
类型 |
说明 |
| id |
UUID |
主键 |
| message |
UUID |
消息 ID |
| user |
UUID |
用户 ID |
| emoji |
VARCHAR(32) |
emoji |
| created_at |
TIMESTAMPTZ |
创建时间 |
room_pin - 置顶消息表
| 字段 |
类型 |
说明 |
| id |
UUID |
主键 |
| room |
UUID |
房间 ID |
| message |
UUID |
消息 ID |
| pinned_by |
UUID |
置顶者 |
| pinned_at |
TIMESTAMPTZ |
置顶时间 |
2.2 消息内容类型
type MessageContentType = 'text' | 'markdown' | 'code' | 'mention';
type MessageSenderType = 'member' | 'ai' | 'system';
3. WebSocket 通信协议
3.1 协议格式
请求
interface WsRequest {
type: 'request';
request_id: string; // 唯一请求 ID
action: WsAction; // 操作类型
params?: WsRequestParams;
}
响应
interface WsResponse {
type: 'response';
request_id: string;
action: string;
data?: WsResponseData;
error?: WsError;
}
3.2 Action 列表
房间管理
| Action |
说明 |
权限 |
room.list |
获取房间列表 |
Member |
room.get |
获取房间详情 |
Member |
room.create |
创建房间 |
Admin |
room.update |
更新房间 |
Admin |
room.delete |
删除房间 |
Admin |
room.subscribe |
订阅房间事件 |
Member |
room.unsubscribe |
取消订阅 |
Member |
消息管理
| Action |
说明 |
权限 |
message.list |
获取消息列表(分页) |
Member |
message.create |
发送消息 |
Member |
message.update |
编辑消息 |
Owner |
message.revoke |
撤回消息 |
Owner |
message.get |
获取单条消息 |
Member |
message.search |
搜索消息 |
Member |
成员管理
| Action |
说明 |
权限 |
member.list |
获取成员列表 |
Member |
member.add |
添加成员 |
Admin |
member.remove |
移除成员 |
Admin |
member.leave |
离开房间 |
Member |
member.update_role |
更新角色 |
Admin |
member.set_read_seq |
设置已读位置 |
Member |
分类管理
| Action |
说明 |
权限 |
category.list |
获取分类列表 |
Member |
category.create |
创建分类 |
Admin |
category.update |
更新分类 |
Admin |
category.delete |
删除分类 |
Admin |
线程管理
| Action |
说明 |
权限 |
thread.list |
获取线程列表 |
Member |
thread.create |
创建线程 |
Member |
thread.messages |
获取线程消息 |
Member |
反应管理
| Action |
说明 |
权限 |
reaction.add |
添加反应 |
Member |
reaction.remove |
移除反应 |
Owner |
reaction.list_batch |
批量获取反应 |
Member |
置顶管理
| Action |
说明 |
权限 |
pin.list |
获取置顶列表 |
Member |
pin.add |
添加置顶 |
Admin |
pin.remove |
移除置顶 |
Admin |
AI 管理
| Action |
说明 |
权限 |
ai.list |
获取 AI 配置列表 |
Member |
ai.upsert |
创建/更新 AI 配置 |
Admin |
ai.delete |
删除 AI 配置 |
Admin |
通知管理
| Action |
说明 |
权限 |
notification.list |
获取通知列表 |
Member |
notification.mark_read |
标记已读 |
Member |
notification.mark_all_read |
全部标记已读 |
Member |
notification.archive |
归档通知 |
Member |
提及管理
| Action |
说明 |
权限 |
mention.list |
获取提及列表 |
Member |
mention.read_all |
全部标记已读 |
Member |
3.3 实时事件推送
type WsEventType =
| 'room.created'
| 'room.updated'
| 'room.deleted'
| 'message.created'
| 'message.updated'
| 'message.revoked'
| 'member.joined'
| 'member.left'
| 'member.role_changed'
| 'thread.created'
| 'reaction.updated'
| 'pin.updated';
4. 后端架构
4.1 目录结构
libs/room/src/
├── lib.rs # 模块入口
├── service.rs # RoomService 主服务
├── room.rs # 房间 CRUD
├── message.rs # 消息管理
├── member.rs # 成员管理
├── category.rs # 分类管理
├── thread.rs # 线程管理
├── reaction.rs # 反应管理
├── pin.rs # 置顶管理
├── ai.rs # AI 配置管理
├── notification.rs # 通知管理
├── search.rs # 搜索功能
├── connection.rs # WebSocket 连接管理
├── room_ai_queue.rs # AI 队列锁
├── error.rs # 错误类型
├── types.rs # 请求/响应类型
├── helpers.rs # 辅助函数
├── metrics.rs # 指标收集
├── ws_context.rs # WebSocket 上下文
└── draft_and_history.rs # 草稿和编辑历史
4.2 核心服务 RoomService
pub struct RoomService {
db: DatabaseConnection,
cache: AppCache,
queue: NatsContext,
ai_client: AiClient,
rate_limiter: RateLimiter,
log: Logger,
}
4.3 并发控制
- 物理并发限制:
tokio::sync::Semaphore
- 消息序列号: Redis INCR 原子递增
- 消息去重:
DashMap<UUID, HashSet<i64>> 内存缓存
- AI 队列锁: Redis 分布式锁 (
ai:room:queue:lock:{room_id})
4.4 AI 队列机制
// Redis 键结构
ai:room:queue:{room_id} // 队列
ai:room:queue:seq:{room_id} // 序号
ai:room:queue:lock:{room_id} // 分布式锁
ai:room:queue:ticket:{room_id}:{ticket_id} // 票据
// 锁参数
LOCK_TTL_MS: 120_000 // 锁超时 2 分钟
TICKET_TTL_MS: 90_000 // 票据超时 1.5 分钟
MAX_BACKOFF_MS: 200 // 最大退避 200ms
4.5 定时任务
- 空闲房间清理: 30 天无消息的房间标记为归档
- 频率限制刷新: 每分钟重置计数
- 陈旧指标清理: 定期清理过期数据
5. 前端架构
5.1 目录结构
src/
├── components/room/
│ ├── DiscordServerSidebar.tsx # 服务器图标侧边栏 (72px)
│ ├── DiscordChannelSidebar.tsx # 可折叠频道列表
│ ├── DiscordChatPanel.tsx # 主聊天面板
│ ├── DiscordMemberList.tsx # 成员列表 (带在线状态)
│ ├── message/
│ │ ├── MessageList.tsx # 消息列表
│ │ ├── MessageInput.tsx # 消息输入框
│ │ ├── MessageBubble.tsx # 消息气泡
│ │ └── MessageActions.tsx # 消息操作菜单
│ ├── RoomThreadPanel.tsx # 线程侧边栏
│ ├── RoomMentionPanel.tsx # 提及面板
│ ├── RoomPinBar.tsx # 置顶栏
│ ├── RoomMessageSearch.tsx # 消息搜索
│ ├── RoomSettingsPanel.tsx # 设置面板
│ ├── RoomAiAuthBanner.tsx # AI 认证提示
│ ├── RoomAiTasksPanel.tsx # AI 任务面板
│ └── ...
├── contexts/
│ └── room-context.tsx # 房间状态管理
└── lib/
└── ws-protocol.ts # WebSocket 协议定义
5.2 React Context 状态管理
interface RoomContextValue {
// 房间状态
rooms: RoomResponse[];
currentRoom: RoomResponse | null;
roomsLoading: boolean;
// 消息状态
messages: MessageWithMeta[];
threads: RoomThreadResponse[];
// 成员状态
members: RoomMember[];
membersLoading: boolean;
// AI 配置
roomAiConfigs: RoomAiResponse[];
// WebSocket 状态
wsStatus: 'open' | 'connecting' | 'disconnected';
wsError: Error | null;
wsClient: WebSocketClient | null;
// 操作方法
sendMessage: (content: string, inReplyTo?: string) => Promise<void>;
editMessage: (messageId: string, content: string) => Promise<void>;
revokeMessage: (messageId: string) => Promise<void>;
updateRoom: (roomId: string, data: Partial<RoomUpdateRequest>) => Promise<void>;
refreshThreads: () => Promise<void>;
}
5.3 Discord 风格 UI 布局
┌─────────────────────────────────────────────────────────────────┐
│ [Icon] │ # channel-name [🔍][👤] │
├──────────┼─────────────────────────────────────────┬────────────┤
│ │ ┌─────────────────────────────────┐ │ │
│ Category │ │ Message List │ │ Members │
│ ────────│ │ (with virtual scrolling) │ │ Online(3) │
│ # gen │ │ │ │ ● user1 │
│ # dev │ │ user1 [10:30] Hello! │ │ ● user2 │
│ # ai │ │ ↳ user2 [10:32] Hi! │ │ │
│ │ │ │ │ Offline(5)│
│ Category │ │ 🤖 AI [10:33] Thinking... │ │ ○ user3 │
│ ────────│ │ │ │ │
│ 🔒 priv │ └─────────────────────────────────┘ │ │
│ ├─────────────────────────────────────────┤ │
│ │ [+] Type a message... [@][📎] │ │
└──────────┴─────────────────────────────────────────┴────────────┘
72px Flex: 1 240px
5.4 消息数据流
用户输入 → MessageInput
↓
WebSocket.send({ action: 'message.create', params: { content, room_id } })
↓
后端处理 → Redis INCR seq → DB insert → NATS publish
↓
WebSocket.push({ event: 'message.created', data: message })
↓
RoomContext.handleMessage() → setMessages(prev => [...prev, message])
↓
MessageList 渲染
6. API 端点 (REST)
6.1 房间管理
GET /api/projects/{project}/rooms # 房间列表
GET /api/projects/{project}/rooms/{room} # 房间详情
POST /api/projects/{project}/rooms # 创建房间
PATCH /api/projects/{project}/rooms/{room} # 更新房间
DELETE /api/projects/{project}/rooms/{room} # 删除房间
6.2 消息管理
GET /api/rooms/{room}/messages # 消息列表 (分页)
GET /api/rooms/{room}/messages/{message} # 单条消息
POST /api/rooms/{room}/messages # 发送消息
PATCH /api/rooms/{room}/messages/{message} # 编辑消息
DELETE /api/rooms/{room}/messages/{message} # 撤回消息
GET /api/rooms/{room}/messages/search # 搜索消息
GET /api/rooms/{room}/messages/{message}/history # 编辑历史
6.3 AI 端点
GET /api/rooms/{room}/ai # AI 配置列表
POST /api/rooms/{room}/ai # 创建 AI 配置
PATCH /api/rooms/{room}/ai/{model} # 更新 AI 配置
DELETE /api/rooms/{room}/ai/{model} # 删除 AI 配置
7. 关键设计原则
| 原则 |
实现方式 |
| 高内聚低耦合 |
模块化服务层、清晰的领域边界 |
| 异步非阻塞 |
Tokio async/await、Redis 异步客户端 |
| 事件驱动 |
NATS Pub/Sub 解耦组件 |
| 强类型安全 |
TypeScript + Rust 编译期检查 |
| 分层架构 |
Service → Repository → Database |
| 鲁棒性优先 |
完善的错误处理、限流、资源回收 |
8. 已实现功能清单
8.1 核心功能 ✅
8.2 实时功能 ✅
8.3 AI 集成 ✅
8.4 富媒体消息 ✅
8.5 全文搜索 ✅
8.6 通知系统 ✅
8.4 用户体验 ✅
9. 已完成功能 (详细技术方案)
9.1 富媒体消息支持 ✅
9.1.1 图片消息
技术实现:
- 前端: FileNode.tsx Tiptap 扩展,支持 inline 文件节点
- 富媒体消息类型: MessageContentType::Image, Audio, Video, File
- 文件上传: Tiptap IMEditor 支持拖拽上传
- 状态管理: uploading/done/error 三种状态
代码位置:
- src/components/room/message/editor/FileNode.tsx (Tiptap 文件节点)
- src/components/room/message/editor/IMEditor.tsx (富文本编辑器)
9.1.2 消息内容类型 ✅
已实现的消息类型:
- Text (text)
- Image (image)
- Audio (audio)
- Video (video)
- File (file)
代码位置:
- libs/models/rooms/mod.rs (MessageContentType enum)
9.2 历史消息优化 ✅
9.2.1 虚拟滚动列表
技术实现:
- @tanstack/react-virtual + useVirtualizer
- 按需渲染可见区域消息 (overscan: 30)
- 动态高度估算 (estimateMessageRowHeight)
- 日期分隔符自动插入
- 滚动位置保持 (加载更多时)
代码位置:
- src/components/room/message/MessageList.tsx
功能特性:
- [x] IntersectionObserver 自动加载更多
- [x] 滚动位置恢复
- [x] 滚动到底部按钮
- [x] 日期分组分隔符
9.2.2 IndexedDB 离线缓存 ✅
技术实现:
- IndexedDB 本地持久化存储
- 双索引: by_room, by_room_seq
- 支持离线消息恢复
- 自动保存/加载消息
API:
- saveMessage(msg) # 保存单条
- saveMessages(roomId, msgs) # 批量保存
- loadMessages(roomId) # 加载房间消息
- loadOlderMessagesFromIdb() # 加载历史消息
- getMaxSeq(roomId) # 获取最大序列号 (去重)
代码位置:
- src/lib/storage/indexed-db.ts
- src/contexts/room-context.tsx (集成缓存)
9.3 全文搜索 ✅
9.3.1 PostgreSQL 全文索引
技术实现:
- content_tsv TSVECTOR 列
- GIN 索引 (idx_room_message_content_tsv)
- plainto_tsquery('simple', query) 全文搜索
代码位置:
- libs/room/src/search.rs (room_message_search)
- libs/migrate/sql/m20250628_000080_add_message_reactions_and_search.sql
搜索功能:
- [x] 全文搜索 API
- [x] 分页支持 (limit, offset)
- [x] 结果计数 (total)
- [x] 显示名称解析
9.4 通知系统完善 ✅
9.4.1 多维度通知配置 ✅
技术实现:
- room_member 表新增字段:
- do_not_disturb: BOOLEAN (免打扰开关)
- dnd_start_hour: INT (DND 开始时间, 0-23)
- dnd_end_hour: INT (DND 结束时间, 0-23)
数据库迁移:
- libs/migrate/m20250628_000078_add_room_member_do_not_disturb.rs
代码位置:
- libs/models/rooms/room_member.rs
9.4.2 通知系统
已实现功能:
- [x] 提及通知 (Mention)
- [x] 线程通知 (Thread)
- [x] DND 免打扰时段
- [x] 通知列表 API
- [x] 标记已读 API
代码位置:
- libs/room/src/notification.rs
- libs/service/user/notification.rs
10. 待实现功能
10.1 富媒体消息完善
待实现:
1. [ ] 对象存储集成 (S3/MinIO)
2. [ ] 文件下载 API
3. [ ] 图片预览 Modal
4. [ ] 视频播放器集成
5. [ ] Office 文档预览
6. [ ] 文件大小/类型验证
7. [ ] 图片压缩 (WebWorker)
10.2 全文搜索增强
待实现:
1. [ ] 时间范围筛选
2. [ ] 用户筛选 (@username)
3. [ ] 文件类型筛选 (content_type)
4. [ ] 搜索历史记录
5. [ ] 结果高亮
6. [ ] 正则搜索支持
7. [ ] 数据库触发器自动更新 tsvector
10.3 推送通知
待实现:
1. [ ] Web Push 集成 (service worker)
2. [ ] 移动端推送
3. [ ] 通知中心 UI
4. [ ] 未读计数 Badge
5. [ ] 关键词提醒
10.4 性能优化
待实现:
1. [ ] room_message 表分区 (按时间)
2. [ ] 读写分离
3. [ ] 房间列表缓存 (Redis)
4. [ ] 成员列表缓存
5. [ ] Redis Pipeline 批量操作
6. [ ] 组件代码分割 (React.lazy)
7. [ ] 图片懒加载
10.5 AI 增强功能
待实现:
1. [ ] AI 连续对话上下文管理
2. [ ] AI 会话历史管理
3. [ ] AI 切换对话线程
4. [ ] AI 输出 Markdown 渲染优化
5. [ ] AI 工具调用扩展 (消息引用/代码执行/搜索)
6. [ ] 定时 AI 任务
7. [ ] 会议纪要生成
10.6 国际化 (i18n)
待实现:
1. [ ] 前端 i18n (react-i18next)
2. [ ] 后端 i18n (rust-i18n)
3. [ ] 提取 UI 字符串
4. [ ] 语言切换器
5. [ ] 日期/时间本地化
6. [ ] RTL 语言支持
11. 测试计划
11.1 单元测试
11.2 集成测试
11.3 E2E 测试
12. 部署与运维
11.1 环境变量
# 数据库
DATABASE_URL=postgresql://user:pass@host:5432/db
# Redis
REDIS_URL=redis://host:6379
# NATS
NATS_URL=nats://host:4222
# 对象存储
S3_ENDPOINT=https://s3.example.com
S3_BUCKET=room-media
AWS_ACCESS_KEY_ID=xxx
AWS_SECRET_ACCESS_KEY=xxx
# AI
OPENAI_API_KEY=sk-xxx
OPENROUTER_API_KEY=xxx
11.2 Kubernetes 配置
# Room Service Deployment
resources:
requests:
memory: "256Mi"
cpu: "100m"
limits:
memory: "1Gi"
cpu: "500m"
# HPA 自动扩缩容
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
11.3 监控指标
- WebSocket 连接数
- 消息吞吐量 (msg/s)
- AI 调用延迟
- Redis 缓存命中率
- 数据库查询延迟
13. 安全考虑
12.1 权限模型
项目权限 → 房间权限 → 成员角色
Admin/Owner → Admin/Owner/Member
12.2 输入验证
- 消息内容长度限制 (MAX: 10000 chars)
- 文件大小限制 (MAX: 100MB)
- 文件类型白名单
12.3 CSRF/XSS 防护
- WebSocket 请求携带 JWT
- 消息内容转义
- 文件名 sanitize