Files
TrueGrowth/specs/003-chat-drawer/data-model.md

178 lines
5.6 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.
# Data Model: 对话抽屉 (Chat Drawer)
**Date**: 2025-12-03
**Feature**: 001-chat-drawer
## Entities
### ChatSession (对话会话)
| Field | Type | Description | Constraints |
|-------|------|-------------|-------------|
| id | string | 会话唯一标识 | UUID v4, 主键 |
| title | string | 会话标题 | 从首条消息截取max 30字符 |
| createdAt | number | 创建时间戳 | Unix milliseconds |
| updatedAt | number | 最后更新时间戳 | Unix milliseconds |
| messageCount | number | 消息数量 | ≥ 0 |
**Lifecycle States**: Active → Archived (future)
**Indexes**:
- Primary: `id`
- Secondary: `updatedAt` (用于排序)
### ChatMessage (对话消息)
| Field | Type | Description | Constraints |
|-------|------|-------------|-------------|
| id | string | 消息唯一标识 | UUID v4, 主键 |
| sessionId | string | 所属会话ID | 外键 → ChatSession.id |
| role | 'user' \| 'assistant' | 消息角色 | 枚举值 |
| content | string | 消息内容 | Markdown格式 |
| timestamp | number | 发送时间戳 | Unix milliseconds |
| status | MessageStatus | 消息状态 | 枚举值 |
| attachments | Attachment[] | 附件列表 | 可选,数组 |
| error | string \| null | 错误信息 | 可选 |
**MessageStatus 枚举**:
- `sending`: 发送中
- `streaming`: AI正在生成
- `success`: 发送成功
- `failed`: 发送失败
**Indexes**:
- Primary: `id`
- Compound: `[sessionId, timestamp]` (用于按会话查询消息)
### Attachment (附件)
| Field | Type | Description | Constraints |
|-------|------|-------------|-------------|
| id | string | 附件唯一标识 | UUID v4 |
| name | string | 文件名 | max 255字符 |
| type | string | MIME类型 | e.g., 'image/png' |
| size | number | 文件大小 | bytes |
| data | string | 文件数据 | Base64 或 Blob URL |
| isBlob | boolean | 是否为Blob URL | 用于清理 |
**支持的文件类型**:
- 图片: image/png, image/jpeg, image/gif, image/webp
- 文档: application/pdf, text/plain, text/markdown
- 其他: application/json, text/csv
**大小限制**:
- 单个文件: 10MB
- 单条消息总附件: 20MB
### DrawerState (抽屉状态)
| Field | Type | Description | Constraints |
|-------|------|-------------|-------------|
| isOpen | boolean | 是否展开 | 默认 false |
| width | number | 当前宽度 | 320-500px默认视口30% |
| activeSessionId | string \| null | 当前活跃会话ID | 可选 |
**Note**: DrawerState 存储在 localStorage不使用 IndexedDB需要同步访问
## Relationships
```
┌─────────────────┐ ┌─────────────────┐
│ ChatSession │ 1:N │ ChatMessage │
│─────────────────│───────│─────────────────│
│ id (PK) │ │ id (PK) │
│ title │ │ sessionId (FK) │
│ createdAt │ │ role │
│ updatedAt │ │ content │
│ messageCount │ │ timestamp │
└─────────────────┘ │ status │
│ attachments[] │
└─────────────────┘
│ 1:N (embedded)
┌─────────────────┐
│ Attachment │
│─────────────────│
│ id │
│ name │
│ type │
│ size │
│ data │
└─────────────────┘
```
## Storage Schema
### IndexedDB Configuration
```javascript
// Database: 'aitu-chat'
// Version: 1
const stores = {
sessions: {
keyPath: 'id',
indexes: [
{ name: 'updatedAt', keyPath: 'updatedAt', unique: false }
]
},
messages: {
keyPath: 'id',
indexes: [
{ name: 'sessionId', keyPath: 'sessionId', unique: false },
{ name: 'sessionTimestamp', keyPath: ['sessionId', 'timestamp'], unique: false }
]
}
};
```
### localStorage Keys
```typescript
const CHAT_STORAGE_KEYS = {
DRAWER_STATE: 'aitu:chat:drawer-state',
ACTIVE_SESSION: 'aitu:chat:active-session',
};
```
## Validation Rules
### ChatSession
- `id`: 必须是有效的 UUID v4
- `title`: 非空最大30字符自动从首条消息截取
- `createdAt/updatedAt`: 有效的 Unix 时间戳
### ChatMessage
- `id`: 必须是有效的 UUID v4
- `sessionId`: 必须引用存在的 ChatSession
- `role`: 必须是 'user' 或 'assistant'
- `content`: 用户消息最大10000字符AI消息无限制
- `attachments`: 单条消息最多5个附件
### Attachment
- `type`: 必须在支持的 MIME 类型列表中
- `size`: 单个文件最大10MB
- `data`: Base64 字符串或有效的 Blob URL
## Data Cleanup Policies
### 自动清理
- 会话数量超过50时删除最早的会话保留最近50个
- 单会话消息超过100条时删除最早的消息
- Blob URL 在页面卸载时自动释放
### 手动清理
- 用户可删除单个会话及其所有消息
- 用户可清空所有对话历史
## Migration Strategy
### Version 1 (Initial)
- 创建 sessions 和 messages stores
- 无需迁移
### Future Versions
- 使用 localforage 的版本管理
- 迁移脚本模式参考 `history-migration.ts`