diff --git a/public/sw.js b/public/sw.js new file mode 100644 index 0000000..72d02c2 --- /dev/null +++ b/public/sw.js @@ -0,0 +1,51 @@ +// Service Worker for Web Push Notifications +const CACHE_NAME = 'app-v1'; + +self.addEventListener('push', (event) => { + if (!event.data) return; + + let data; + try { + data = event.data.json(); + } catch { + data = { title: 'Notification', body: event.data.text() }; + } + + const options = { + body: data.body || '', + icon: data.icon || '/icon.png', + badge: '/badge.png', + data: { url: data.url || '/' }, + vibrate: [200, 100, 200], + requireInteraction: false, + }; + + event.waitUntil( + self.registration.showNotification(data.title || 'App Notification', options) + ); +}); + +self.addEventListener('notificationclick', (event) => { + event.notification.close(); + + const url = event.notification.data?.url || '/'; + + event.waitUntil( + self.clients.matchAll({ type: 'window', includeUncontrolled: true }).then((clients) => { + for (const client of clients) { + if (client.url === url && 'focus' in client) { + return client.focus(); + } + } + return self.clients.openWindow(url); + }) + ); +}); + +self.addEventListener('install', () => { + self.skipWaiting(); +}); + +self.addEventListener('activate', (event) => { + event.waitUntil(self.clients.claim()); +}); diff --git a/room.md b/room.md new file mode 100644 index 0000000..e839445 --- /dev/null +++ b/room.md @@ -0,0 +1,814 @@ +# 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 消息内容类型 +```typescript +type MessageContentType = 'text' | 'markdown' | 'code' | 'mention'; + +type MessageSenderType = 'member' | 'ai' | 'system'; +``` + +--- + +## 3. WebSocket 通信协议 + +### 3.1 协议格式 + +#### 请求 +```typescript +interface WsRequest { + type: 'request'; + request_id: string; // 唯一请求 ID + action: WsAction; // 操作类型 + params?: WsRequestParams; +} +``` + +#### 响应 +```typescript +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 实时事件推送 +```typescript +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 +```rust +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>` 内存缓存 +- **AI 队列锁**: Redis 分布式锁 (`ai:room:queue:lock:{room_id}`) + +### 4.4 AI 队列机制 +```rust +// 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 状态管理 +```typescript +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; + editMessage: (messageId: string, content: string) => Promise; + revokeMessage: (messageId: string) => Promise; + updateRoom: (roomId: string, data: Partial) => Promise; + refreshThreads: () => Promise; +} +``` + +### 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 核心功能 ✅ +- [x] 房间 CRUD (创建/读取/更新/删除) +- [x] 消息 CRUD (发送/编辑/撤回/历史) +- [x] 成员管理 (邀请/移除/角色变更) +- [x] 频道分类 (创建/排序/折叠) +- [x] 线程回复 (创建线程/线程消息) +- [x] 消息反应 (emoji 反应) +- [x] 消息置顶 +- [x] 消息搜索 +- [x] 未读计数 + +### 8.2 实时功能 ✅ +- [x] WebSocket 长连接 +- [x] 消息实时推送 +- [x] 成员状态同步 +- [x] 在线状态显示 +- [x] 消息去重 +- [x] IndexedDB 离线缓存 +- [x] 虚拟滚动列表 (@tanstack/react-virtual) + +### 8.3 AI 集成 ✅ +- [x] AI 模型配置 +- [x] AI 消息发送 +- [x] 系统提示词 +- [x] 上下文历史限制 +- [x] 流式输出支持 +- [x] AI 队列锁 + +### 8.4 富媒体消息 ✅ +- [x] 消息内容类型: text, image, audio, video, file +- [x] Tiptap 富文本编辑器 (IMEditor) +- [x] FileNode Tiptap 扩展 (文件/图片节点) +- [x] 文件上传状态管理 (uploading/done/error) +- [x] Markdown 支持 + +### 8.5 全文搜索 ✅ +- [x] PostgreSQL 全文索引 (GIN + tsvector) +- [x] 搜索 API (room_message_search) +- [x] 分页与结果计数 + +### 8.6 通知系统 ✅ +- [x] 提及通知 +- [x] 线程通知 +- [x] DND 免打扰时段 (do_not_disturb, dnd_start/end_hour) + +### 8.4 用户体验 ✅ +- [x] 消息草稿自动保存 +- [x] @提及功能 +- [x] 回复引用 +- [x] 消息时间格式化 +- [x] Discord 风格 UI +- [x] 侧边栏折叠 +- [x] 成员列表按角色着色 + +--- + +## 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 单元测试 +- [ ] RoomService 业务逻辑测试 +- [ ] 消息序列号生成测试 +- [ ] 权限检查测试 +- [ ] React Hooks 测试 + +### 11.2 集成测试 +- [ ] WebSocket 连接测试 +- [ ] 数据库事务测试 +- [ ] Redis 缓存测试 +- [ ] NATS 消息分发测试 + +### 11.3 E2E 测试 +- [ ] 房间创建流程 +- [ ] 消息发送与接收 +- [ ] 消息编辑与撤回 +- [ ] AI 对话流程 + +--- + +## 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