Files
social-app/docs/runtime/runtime-database.md
T
qzl e161ca22c4 refactor(chat): 重构聊天模块并集成历史消息加载功能
- 删除冗余的 chat_history_repository 和 home_mock_data
- 简化 ag_ui_event fromJson 使用工厂映射表
- 提取 ChatBloc 事件处理方法,添加 loadHistory/loadMoreHistory
- HomeScreen 集成 ChatBloc 实现历史消息加载和下拉刷新
- 更新 AGENTS.md 文档约束
2026-03-02 15:05:10 +08:00

394 lines
10 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.
# Database Schema
**Status:** Active
**Reference:** [Plan: social-app 数据模型重设计](../plans/2026-02-26-social-data-model-redesign.md)
---
## 枚举约定
所有枚举使用字符串存储,不使用整数值:
- Database: `VARCHAR(20)` + `CHECK` 约束
- Code: Python `Enum` 继承 `str`
---
## 表清单
| 表名 | 说明 |
|------|------|
| `profiles` | 用户资料(含 settings JSONB |
| `user_agents` | 用户专属 Agent |
| `memories` | 用户/工作记忆 |
| `friendships` | 好友关系 |
| `groups` | 群组 |
| `group_members` | 群组成员 |
| `schedule_items` | 日程事项 |
| `schedule_subscriptions` | 日程订阅与权限 |
| `inbox_messages` | 待处理消息 |
| `todos` | 待办 |
| `todo_sources` | 待办与日程来源关联 |
| `automation_jobs` | 定时任务 |
| `sessions` | Agent 对话会话 |
| `llm_factories` | LLM 工厂配置 |
| `llms` | LLM 模型实例 |
---
## 表结构
### profiles
用户资料表,含内置设置。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK`auth.users.id` |
| `username` | VARCHAR(50) | 用户名 |
| `avatar_url` | TEXT | 头像 URL |
| `bio` | TEXT | 个人简介 |
| `settings` | JSONB | 用户设置 |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | 软删时间 |
**settings JSONB 默认结构:**
```json
{
"version": 1,
"preferences": {
"interface_language": "zh-CN",
"ai_language": "zh-CN",
"timezone": "Asia/Shanghai"
},
"privacy": {},
"notification": {}
}
```
---
### user_agents
用户专属 Agent 配置。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `user_id` | UUID | 用户 ID(唯一) |
| `llm_id` | UUID | 关联的 LLM 模型 |
| `agent_type` | VARCHAR(20) | 枚举:`INTENT_RECOGNITION`, `TASK_EXECUTION`, `RESULT_REPORTING` |
| `config` | JSONB | Agent 配置参数 |
| `status` | VARCHAR(20) | 状态:`active`, `paused`, `migrating` |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | 软删时间 |
---
### memories
用户与工作记忆。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `owner_id` | UUID | 用户 ID |
| `agent_id` | UUID | Agent IDwork 类型必填) |
| `memory_type` | VARCHAR(20) | 枚举:`user`, `work` |
| `title` | VARCHAR(255) | 标题 |
| `content` | JSONB | 记忆内容 |
| `source` | VARCHAR(20) | 来源:`manual`, `agent`, `imported` |
| `status` | VARCHAR(20) | 状态:`active`, `disabled` |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
**约束:** work 类型必须有 agent_iduser 类型必须无 agent_id
**content JSONB 示例:**
```json
// 用户记忆
{"type": "preference", "data": {"style": "concise", "language": "zh-CN"}}
// 工作记忆
{"type": "workflow_summary", "data": {"task": "代码审查", "learnings": ["优先检查安全漏洞"], "improvements": []}}
```
---
### friendships
好友关系(双向规范化)。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `user_low_id` | UUID | 较小 UUID |
| `user_high_id` | UUID | 较大 UUID |
| `initiator_id` | UUID | 发起方用户 ID |
| `status` | VARCHAR(20) | 状态:`pending`, `accepted`, `blocked`, `declined`, `canceled` |
| `requested_at` | TIMESTAMPTZ | 请求时间 |
| `accepted_at` | TIMESTAMPTZ | 接受时间 |
| `blocked_by` | UUID | 阻止者用户 ID |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
**约束:** `user_low_id < user_high_id``(user_low_id, user_high_id)` 唯一
---
### groups
群组。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `name` | VARCHAR(100) | 群组名称 |
| `description` | TEXT | 群组描述 |
| `owner_id` | UUID | 创建者 ID |
| `status` | VARCHAR(20) | 状态:`active`, `archived` |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | 软删时间 |
---
### group_members
群组成员。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `group_id` | UUID | 群组 ID |
| `user_id` | UUID | 用户 ID |
| `role` | VARCHAR(20) | 角色:`owner`, `admin`, `member` |
| `join_source` | VARCHAR(20) | 加入方式:`invited`, `joined` |
| `invited_by` | UUID | 邀请人 ID |
| `joined_at` | TIMESTAMPTZ | 加入时间 |
| `status` | VARCHAR(20) | 状态:`active`, `muted`, `removed` |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
| `removed_at` | TIMESTAMPTZ | 移除时间 |
**约束:** `(group_id, user_id)` 唯一
---
### schedule_items
日程事项。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `owner_id` | UUID | 所有者 ID |
| `title` | VARCHAR(255) | 标题 |
| `description` | TEXT | 描述 |
| `start_at` | TIMESTAMPTZ | 开始时间 |
| `end_at` | TIMESTAMPTZ | 结束时间 |
| `timezone` | VARCHAR(50) | 时区 |
| `metadata` | JSONB | 扩展字段 |
| `recurrence_rule` | VARCHAR(100) | 循环规则 |
| `source_type` | VARCHAR(20) | 来源:`manual`, `imported`, `agent_generated` |
| `status` | VARCHAR(20) | 状态:`active`, `completed`, `canceled`, `archived` |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
**metadata JSONB 默认结构:**
```json
{
"color": "#FF6B6B",
"location": "会议室A",
"notes": "记得提前准备投影仪",
"attachments": [
{
"name": "会议纪要.pdf",
"url": "https://...",
"visible_to": [],
"type": "document"
},
{
"name": "投影仪提醒",
"visible_to": ["uuid1"],
"type": "reminder",
"content": "记得带投影仪"
}
],
"version": 1
}
```
---
### schedule_subscriptions
日程订阅与权限。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `item_id` | UUID | 日程事项 ID |
| `subscriber_id` | UUID | 订阅者 ID |
| `permission` | INTEGER | 权限位图(view=1, invite=2, edit=4 |
| `notify_level` | VARCHAR(20) | 通知级别:`all`, `mentions`, `none` |
| `status` | VARCHAR(20) | 状态:`active`, `paused`, `unsubscribed` |
| `created_at` | TIMESTAMPTZ | 创建时间 |
**约束:** `(item_id, subscriber_id)` 唯一,`permission BETWEEN 0 AND 7`
---
### inbox_messages
待处理消息(接收者视角)。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `recipient_id` | UUID | 接收者 ID |
| `sender_id` | UUID | 发送者 ID(系统消息可为 NULL) |
| `message_type` | VARCHAR(20) | 类型:`friend_request`, `calendar`, `system`, `group` |
| `friendship_id` | UUID | 好友请求关联(friend_request 时必填) |
| `schedule_item_id` | UUID | 日程关联(calendar 时必填) |
| `group_id` | UUID | 群组关联(group 时必填) |
| `content` | TEXT | 消息内容(system 用) |
| `is_read` | BOOLEAN | 是否已读 |
| `status` | VARCHAR(20) | 状态:`pending`, `accepted`, `rejected`, `dismissed` |
| `created_at` | TIMESTAMPTZ | 创建时间 |
**message_type 与业务字段对应:**
| message_type | 必填字段 |
|--------------|----------|
| friend_request | friendship_id |
| calendar | schedule_item_id |
| system | 全部可空 |
| group | group_id |
---
### todos
待办事项。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `owner_id` | UUID | 所有者 ID |
| `title` | VARCHAR(255) | 标题 |
| `description` | TEXT | 描述 |
| `due_at` | TIMESTAMPTZ | 截止时间 |
| `priority` | INTEGER | 优先级(1=重要且紧急, 2=重要不紧急, 3=紧急不重要, 4=不重要不紧急) |
| `status` | VARCHAR(20) | 状态:`pending`, `done`, `canceled` |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `completed_at` | TIMESTAMPTZ | 完成时间 |
---
### todo_sources
待办与日程来源关联。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `todo_id` | UUID | 待办 ID |
| `schedule_item_id` | UUID | 日程事项 ID |
| `created_at` | TIMESTAMPTZ | 创建时间 |
**约束:** `(todo_id, schedule_item_id)` 唯一
---
### automation_jobs
自动化定时任务。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `owner_id` | UUID | 所有者 ID |
| `title` | VARCHAR(255) | 任务标题 |
| `prompt` | TEXT | AI 执行 prompt |
| `schedule_type` | VARCHAR(20) | 调度类型:`daily`, `weekly` |
| `run_at` | TIMESTAMPTZ | 首次运行时间 |
| `next_run_at` | TIMESTAMPTZ | 下次运行时间 |
| `timezone` | VARCHAR(50) | 时区 |
| `last_run_at` | TIMESTAMPTZ | 最近运行时间 |
| `status` | VARCHAR(20) | 状态:`active`, `disabled` |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
---
### sessions
Agent 对话会话。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `user_id` | UUID | 用户 ID |
| `session_type` | VARCHAR(20) | 会话类型:`chat`, `automation` |
| `job_id` | UUID | 自动化任务 IDautomation 时必填) |
| `last_activity_at` | TIMESTAMPTZ | 最后活跃时间 |
| `created_at` | TIMESTAMPTZ | 创建时间 |
**约束:** `session_type='chat' → job_id IS NULL`, `session_type='automation' → job_id IS NOT NULL`
---
### llm_factories
LLM 工厂配置。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `name` | VARCHAR(50) | 工厂名称 |
| `base_url` | TEXT | API 基础 URL |
| `api_key` | TEXT | API 密钥 |
| `enabled` | BOOLEAN | 是否启用 |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
---
### llms
LLM 模型实例。
| 字段 | 类型 | 说明 |
|------|------|------|
| `id` | UUID | PK |
| `factory_id` | UUID | 工厂 ID |
| `model_id` | VARCHAR(50) | 模型标识 |
| `name` | VARCHAR(100) | 显示名称 |
| `context_window` | INTEGER | 上下文窗口大小 |
| `enabled` | BOOLEAN | 是否启用 |
| `created_at` | TIMESTAMPTZ | 创建时间 |
| `updated_at` | TIMESTAMPTZ | 更新时间 |
---
## 外键删除策略
| 外键 | 删除策略 |
|------|----------|
| `sessions.job_id` | RESTRICT |
| `todo_sources.todo_id` | CASCADE |
| `todo_sources.schedule_item_id` | CASCADE |
| `inbox_messages.friendship_id` | CASCADE |
| `inbox_messages.schedule_item_id` | CASCADE |
| `inbox_messages.group_id` | CASCADE |
---
## RLS 策略
所有 `public` 业务表默认启用 RLS
- `anon`: 全部 DENY
- `authenticated`: 全部 DENY
- `service_role`: 由后端服务连接,不依赖 RLS