Files
social-app/docs/runtime/runtime-database.md
T
qzl 1f6cb1a48f refactor: 删除未使用的 api_external_url 配置并完善 runtime 文档
- 删除 SupabaseSettings 中未使用的 api_external_url computed field
- 更新测试文件移除相关测试用例
- backend/AGENTS.md 新增软删除设计规则
- runtime-database.md 更新表结构(删除 user_agents,表名更新为 agent_chat_sessions/messages,system_agents)
- runtime-frontend.md 补充路由结构和功能模块说明
- 根 AGENTS.md 清理过时技能路径引用
2026-03-06 18:25:18 +08:00

546 lines
19 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
**Last Updated:** 2026-03-06
---
## 架构概览
### 数据库层职责
- **Supabase**: 认证(JWT 签发与验证)
- **Backend**: 业务授权(Service 层)、数据访问(Repository 层)
- **ORM**: SQLAlchemyasync + asyncpg,使用 service_role 连接)
### 核心模块
| 模块 | 路径 | 说明 |
|------|------|------|
| Base Classes | `backend/src/core/db/` | ORM 基类、Session 管理、Repository 基类 |
| Models | `backend/src/models/` | 数据模型定义 |
| Migrations | `backend/alembic/versions/` | 数据库迁移脚本 |
---
## 设计约定
### 枚举存储
**所有枚举使用字符串存储,不使用整数值:**
- Database: `VARCHAR(20)` + `CHECK` 约束
- Code: Python `Enum` 继承 `str`
```python
class AgentType(str, Enum):
INTENT_RECOGNITION = "INTENT_RECOGNITION"
TASK_EXECUTION = "TASK_EXECUTION"
RESULT_REPORTING = "RESULT_REPORTING"
```
### 软删除
**软删除标记数据为不可见,不级联删除:**
- 使用 `deleted_at: datetime | None` 列(通过 `SoftDeleteMixin`
- 查询过滤:Repository `_apply_soft_delete_filter()` 自动排除已删除记录
- 级联策略:默认不级联,强依赖关系在 Service 层手动处理
- 恢复策略:只恢复记录本身,关联数据通过查询自动恢复可见
- 唯一约束:使用 partial index 排除 `deleted_at IS NOT NULL`
```sql
-- Partial unique index in migration
CREATE UNIQUE INDEX ux_user_email
ON users(email)
WHERE deleted_at IS NULL
```
---
## 表清单
| 表名 | 说明 | 状态 |
|------|------|------|
| `profiles` | 用户资料(含 settings JSONB | Active |
| `memories` | 用户记忆 | Active |
| `friendships` | 好友关系 | Active |
| `groups` | 群组 | Active |
| `group_members` | 群组成员 | Active |
| `schedule_items` | 日程事项 | Active |
| `schedule_subscriptions` | 日程订阅与权限 | Active |
| `inbox_messages` | 待处理消息 | Active |
| `todos` | 待办 | Active |
| `todo_sources` | 待办与日程来源关联 | Active |
| `automation_jobs` | 定时任务 | Active |
| `agent_chat_sessions` | Agent 对话会话 | Active |
| `agent_chat_messages` | 会话消息记录 | Active |
| `llm_factory` | LLM 工厂配置 | Active |
| `llms` | LLM 模型实例 | Active |
| `system_agents` | 系统级 Agent 配置 | Active |
| `invite_codes` | 邀请码 | Active |
---
## 表结构详细
### profiles
用户资料表,含用户设置。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK, FK → auth.users.id | 用户 ID |
| `username` | VARCHAR(30) | UNIQUE, NOT NULL | 用户名 |
| `avatar_url` | TEXT | NULLABLE | 头像 URL |
| `bio` | VARCHAR(200) | NULLABLE | 个人简介 |
| `settings` | JSONB | NOT NULL, DEFAULT '{}' | 用户设置 |
| `referred_by` | UUID | NULLABLE, FK → profiles.id | 邀请人 ID |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
**settings JSONB 结构:**
```json
{
"version": 1,
"preferences": {
"interface_language": "zh-CN",
"ai_language": "zh-CN",
"timezone": "Asia/Shanghai"
},
"agent_prompts": {
"INTENT_RECOGNITION": "自定义提示词...",
"TASK_EXECUTION": "自定义提示词..."
},
"privacy": {},
"notification": {}
}
```
---
### memories
用户记忆。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 记忆 ID |
| `owner_id` | UUID | NOT NULL, FK → profiles.id | 所有者 ID |
| `memory_type` | VARCHAR(20) | NOT NULL, CHECK | 枚举:`user`, `work` |
| `title` | VARCHAR(255) | NOT NULL | 标题 |
| `content` | JSONB | NOT NULL | 记忆内容 |
| `source` | VARCHAR(20) | NOT NULL | 来源:`manual`, `agent`, `imported` |
| `status` | VARCHAR(20) | NOT NULL | 状态:`active`, `disabled` |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
**content JSONB 示例:**
```json
// 用户记忆
{"type": "preference", "data": {"style": "concise", "language": "zh-CN"}}
// 工作记忆
{"type": "workflow_summary", "data": {"task": "代码审查", "learnings": ["优先检查安全漏洞"], "improvements": []}}
```
---
### friendships
好友关系(双向规范化)。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 关系 ID |
| `user_low_id` | UUID | NOT NULL | 较小 UUID |
| `user_high_id` | UUID | NOT NULL | 较大 UUID |
| `initiator_id` | UUID | NOT NULL | 发起方用户 ID |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`pending`, `accepted`, `blocked`, `declined`, `canceled` |
| `requested_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 请求时间 |
| `accepted_at` | TIMESTAMPTZ | NULLABLE | 接受时间 |
| `blocked_by` | UUID | NULLABLE | 阻止者用户 ID |
| `created_by` | UUID | NULLABLE | 创建者 |
| `updated_by` | UUID | NULLABLE | 更新者 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
**约束:**
- `user_low_id < user_high_id`
- `UNIQUE(user_low_id, user_high_id)`
---
### groups
群组。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 群组 ID |
| `name` | VARCHAR(100) | NOT NULL | 群组名称 |
| `description` | TEXT | NULLABLE | 群组描述 |
| `owner_id` | UUID | NOT NULL, FK → profiles.id | 创建者 ID |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`active`, `archived` |
| `created_by` | UUID | NULLABLE | 创建者 |
| `updated_by` | UUID | NULLABLE | 更新者 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
---
### group_members
群组成员。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 成员 ID |
| `group_id` | UUID | NOT NULL, FK → groups.id | 群组 ID |
| `user_id` | UUID | NOT NULL, FK → profiles.id | 用户 ID |
| `role` | VARCHAR(20) | NOT NULL, CHECK | 角色:`owner`, `admin`, `member` |
| `join_source` | VARCHAR(20) | NOT NULL | 加入方式:`invited`, `joined` |
| `invited_by` | UUID | NULLABLE, FK → profiles.id | 邀请人 ID |
| `joined_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 加入时间 |
| `removed_at` | TIMESTAMPTZ | NULLABLE | 移除时间 |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`active`, `muted`, `removed` |
| `created_by` | UUID | NULLABLE | 创建者 |
| `updated_by` | UUID | NULLABLE | 更新者 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
**约束:** `UNIQUE(group_id, user_id)`
---
### schedule_items
日程事项。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 事项 ID |
| `owner_id` | UUID | NOT NULL, FK → profiles.id | 所有者 ID |
| `title` | VARCHAR(255) | NOT NULL | 标题 |
| `description` | TEXT | NULLABLE | 描述 |
| `start_at` | TIMESTAMPTZ | NOT NULL | 开始时间 |
| `end_at` | TIMESTAMPTZ | NULLABLE | 结束时间 |
| `timezone` | VARCHAR(50) | NOT NULL, DEFAULT 'UTC' | 时区 |
| `metadata` | JSONB | NOT NULL, DEFAULT '{}' | 扩展字段 |
| `recurrence_rule` | VARCHAR(255) | NULLABLE | 循环规则 |
| `source_type` | VARCHAR(20) | NOT NULL, CHECK | 来源:`manual`, `imported`, `agent_generated` |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`active`, `completed`, `canceled`, `archived` |
| `created_by` | UUID | NULLABLE | 创建者 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
**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 | 订阅 ID |
| `item_id` | UUID | NOT NULL, FK → schedule_items.id | 日程事项 ID |
| `subscriber_id` | UUID | NOT NULL, FK → profiles.id | 订阅者 ID |
| `permission` | INTEGER | NOT NULL, CHECK, DEFAULT 1 | 权限位图(view=1, invite=2, edit=4 |
| `notify_level` | VARCHAR(20) | NOT NULL, DEFAULT 'all' | 通知级别:`all`, `mentions`, `none` |
| `status` | VARCHAR(20) | NOT NULL, DEFAULT 'active' | 状态:`active`, `paused`, `unsubscribed` |
| `created_by` | UUID | NULLABLE | 创建者 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
**约束:**
- `UNIQUE(item_id, subscriber_id)`
- `permission BETWEEN 0 AND 7`
---
### inbox_messages
待处理消息(接收者视角)。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 消息 ID |
| `recipient_id` | UUID | NOT NULL, FK → profiles.id | 接收者 ID |
| `sender_id` | UUID | NULLABLE, FK → profiles.id | 发送者 ID(系统消息可为 NULL) |
| `message_type` | VARCHAR(20) | NOT NULL, CHECK | 类型:`friend_request`, `calendar`, `system`, `group` |
| `friendship_id` | UUID | NULLABLE, FK → friendships.id | 好友请求关联(friend_request 时必填) |
| `schedule_item_id` | UUID | NULLABLE, FK → schedule_items.id | 日程关联(calendar 时必填) |
| `group_id` | UUID | NULLABLE, FK → groups.id | 群组关联(group 时必填) |
| `content` | TEXT | NULLABLE | 消息内容(system 用) |
| `is_read` | BOOLEAN | NOT NULL, DEFAULT false | 是否已读 |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`pending`, `accepted`, `rejected`, `dismissed` |
| `created_by` | UUID | NULLABLE | 创建者 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
**message_type 与业务字段对应:**
| message_type | 必填字段 |
|--------------|----------|
| friend_request | friendship_id |
| calendar | schedule_item_id |
| system | 全部可空 |
| group | group_id |
**sender 约束:** system 类型 sender_id 为空,其他类型 sender_id 必填
---
### todos
待办事项。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 待办 ID |
| `owner_id` | UUID | NOT NULL, FK → profiles.id | 所有者 ID |
| `title` | VARCHAR(255) | NOT NULL | 标题 |
| `description` | VARCHAR(1000) | NULLABLE | 描述 |
| `due_at` | TIMESTAMPTZ | NULLABLE | 截止时间 |
| `priority` | INTEGER | NOT NULL, CHECK, DEFAULT 3 | 优先级(1-41=重要且紧急) |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`pending`, `done`, `canceled` |
| `completed_at` | TIMESTAMPTZ | NULLABLE | 完成时间 |
| `created_by` | UUID | NULLABLE | 创建者 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
**约束:** `priority BETWEEN 1 AND 4`
---
### todo_sources
待办与日程来源关联。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 关联 ID |
| `todo_id` | UUID | NOT NULL, FK → todos.id ON DELETE CASCADE | 待办 ID |
| `schedule_item_id` | UUID | NOT NULL, FK → schedule_items.id ON DELETE CASCADE | 日程事项 ID |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
**约束:** `UNIQUE(todo_id, schedule_item_id)`
---
### automation_jobs
自动化定时任务。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 任务 ID |
| `owner_id` | UUID | NOT NULL, FK → profiles.id | 所有者 ID |
| `title` | VARCHAR(255) | NOT NULL | 任务标题 |
| `prompt` | TEXT | NOT NULL | AI 执行 prompt |
| `schedule_type` | VARCHAR(20) | NOT NULL, CHECK | 调度类型:`daily`, `weekly` |
| `run_at` | TIMESTAMPTZ | NOT NULL | 首次运行时间 |
| `next_run_at` | TIMESTAMPTZ | NULLABLE | 下次运行时间 |
| `timezone` | VARCHAR(50) | NOT NULL, DEFAULT 'UTC' | 时区 |
| `last_run_at` | TIMESTAMPTZ | NULLABLE | 最近运行时间 |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`active`, `disabled` |
| `created_by` | UUID | NULLABLE | 创建者 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
**约束:** `UNIQUE(id, owner_id)`
---
### agent_chat_sessions
Agent 对话会话。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 会话 ID |
| `user_id` | UUID | NOT NULL, FK → profiles.id | 用户 ID |
| `session_type` | VARCHAR(20) | NOT NULL, CHECK | 会话类型:`chat`, `automation` |
| `job_id` | UUID | NULLABLE, FK → automation_jobs.id ON DELETE RESTRICT | 自动化任务 IDautomation 时必填) |
| `title` | VARCHAR(255) | NULLABLE | 会话标题 |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`pending`, `running`, `completed`, `failed` |
| `last_activity_at` | TIMESTAMPTZ | NULLABLE | 最后活跃时间 |
| `message_count` | INTEGER | NOT NULL, DEFAULT 0 | 消息计数 |
| `total_tokens` | INTEGER | NOT NULL, DEFAULT 0 | 总 token 数 |
| `total_cost` | NUMERIC(12,6) | NOT NULL, DEFAULT 0 | 总费用 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
**约束:**
- `session_type='chat' → job_id IS NULL`
- `session_type='automation' → job_id IS NOT NULL`
---
### agent_chat_messages
会话消息记录。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 消息 ID |
| `session_id` | UUID | NOT NULL, FK → agent_chat_sessions.id | 会话 ID |
| `seq` | INTEGER | NOT NULL | 消息序号 |
| `role` | VARCHAR(20) | NOT NULL, CHECK | 角色:`user`, `assistant`, `system`, `tool` |
| `content` | TEXT | NOT NULL | 消息内容 |
| `model_code` | VARCHAR(50) | NULLABLE | 模型标识 |
| `tool_name` | VARCHAR(100) | NULLABLE | 工具名称 |
| `input_tokens` | INTEGER | NOT NULL, DEFAULT 0 | 输入 token 数 |
| `output_tokens` | INTEGER | NOT NULL, DEFAULT 0 | 输出 token 数 |
| `cost` | NUMERIC(12,6) | NOT NULL, DEFAULT 0 | 费用 |
| `currency` | VARCHAR(3) | NOT NULL, DEFAULT 'USD' | 货币 |
| `latency_ms` | INTEGER | NULLABLE | 延迟(毫秒) |
| `metadata` | JSONB | NOT NULL, DEFAULT '{}' | 扩展字段 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
**约束:** `UNIQUE(session_id, seq)`
---
### llm_factory
LLM 工厂配置。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 工厂 ID |
| `name` | VARCHAR(50) | UNIQUE, NOT NULL | 工厂名称 |
| `request_url` | VARCHAR(255) | NOT NULL | API 请求 URL |
| `avatar` | TEXT | NULLABLE | 头像 URL |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
---
### llms
LLM 模型实例。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 模型 ID |
| `factory_id` | UUID | NOT NULL, FK → llm_factory.id ON DELETE RESTRICT | 工厂 ID |
| `model_code` | VARCHAR(50) | UNIQUE, NOT NULL | 模型标识 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
| `deleted_at` | TIMESTAMPTZ | NULLABLE | 软删时间 |
---
### system_agents
系统级 Agent 配置(原 user_agent_catalog)。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `agent_type` | VARCHAR(20) | PK, CHECK | Agent 类型 |
| `llm_id` | UUID | NOT NULL, FK → llms.id ON DELETE RESTRICT | 关联的 LLM 模型 |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`active`, `paused`, `migrating` |
| `config` | JSONB | NOT NULL, DEFAULT '{}' | Agent 配置参数 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
**agent_type 枚举值:**
- `INTENT_RECOGNITION` - 意图识别
- `TASK_EXECUTION` - 任务执行
- `RESULT_REPORTING` - 结果报告
---
### invite_codes
邀请码。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| `id` | UUID | PK | 邀请码 ID |
| `code` | VARCHAR(8) | UNIQUE, NOT NULL, CHECK | 邀请码(8 位大写字母数字) |
| `owner_id` | UUID | NOT NULL, FK → profiles.id | 拥有者 ID |
| `status` | VARCHAR(20) | NOT NULL, CHECK | 状态:`active`, `disabled`, `expired` |
| `used_count` | INTEGER | NOT NULL, DEFAULT 0, CHECK | 已使用次数 |
| `max_uses` | INTEGER | NULLABLE | 最大使用次数 |
| `expires_at` | TIMESTAMPTZ | NULLABLE | 过期时间 |
| `reward_config` | JSONB | NULLABLE | 奖励配置 |
| `created_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 创建时间 |
| `updated_at` | TIMESTAMPTZ | NOT NULL, DEFAULT now() | 更新时间 |
**约束:**
- `code` 符合 `[ABCDEFGHJKMNPQRSTUVWXYZ23456789]{8}`
- `used_count >= 0`
---
## 外键删除策略
| 外键 | 删除策略 | 说明 |
|------|----------|------|
| `agent_chat_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 | 删除群组时级联删除消息 |
| `llms.factory_id` | RESTRICT | 禁止删除正在使用的工厂配置 |
| `system_agents.llm_id` | RESTRICT | 禁止删除正在使用的 LLM 模型 |
---
## RLS 策略
所有 `public` 业务表默认启用 RLS
- `anon`: 全部 DENY
- `authenticated`: 全部 DENY
- `service_role`: 由后端服务连接,不依赖 RLS
**例外:** 迁移表 `alembic_version` 不暴露给任何角色。
---
## Change Log
| 日期 | 变更 |
|------|------|
| 2026-03-06 | 删除 `user_agents` 表,重命名 `user_agent_catalog``system_agents`,更新 `agent_chat_sessions` / `agent_chat_messages` 表名,删除 `memories.agent_id` 字段 |
| 2026-02-28 | 新增 `invite_codes` 表、`profiles.referred_by` 字段 |
| 2026-02-26 | 初始版本,基于数据模型重设计 |