Files
social-app/docs/plans/2026-02-26-social-data-model-redesign.md
T
qzl 76853452f6 chore: commit remaining workspace updates
include AGENTS guidance updates, plan doc replacements, and utility script changes left in working tree
2026-02-26 17:59:30 +08:00

26 KiB
Raw Blame History

Plan: social-app 数据库数据模型重设计(支持社交/事项/自动化)

Date: 2026-02-26 Author: AI Assistant Status: Draft

枚举存储约定

统一使用枚举名称(字符串)存储,不使用整数值。

  • 数据库层:VARCHAR(20) + CHECK 约束
  • 代码层:Python Enum 类继承 str
  • 优势:调试可读、易扩展(新增枚举值无需迁移旧数据)、ORM 友好
class AgentType(str, Enum):
    INTENT_RECOGNITION = "INTENT_RECOGNITION"
    TASK_EXECUTION = "TASK_EXECUTION"
    RESULT_REPORTING = "RESULT_REPORTING"
-- Migration
ALTER TABLE user_agents ADD CONSTRAINT chk_agent_type 
  CHECK (agent_type IN ('INTENT_RECOGNITION', 'TASK_EXECUTION', 'RESULT_REPORTING'));

Overview

本方案面向 social-app 的下一阶段功能升级,重设计 PostgreSQL 数据模型,统一支持用户专属 agent、好友/群组协作、待处理消息、设置、可订阅且可授权编辑的日程事项、待办联动与自动化定时任务。目标是在 FastAPI + Flutter 协作场景下提供长期稳定的数据基础,降低后续 API 演进和跨端同步复杂度。

Requirements

Functional

  • 每个用户有专属 agent,且模型可扩展到未来多 agent 能力
  • 用户支持好友关系、群组创建与成员管理
  • 用户支持 inbox/pending 待处理消息
  • 用户支持个性化设置(偏好/隐私/通知)
  • 用户支持“绑定日程的事项”,可多人订阅,且仅特定人可修改
  • 用户支持待办事项(可由日程事项提取,也可手动创建)
  • 用户支持自动化定时任务(循环触发)

Non-Functional

  • 性能:核心读路径(inbox 列表、待办列表、事项列表)P95 < 150ms(单用户典型数据量)
  • 安全:权限以后端业务授权为准;数据库层保留 RLS 防御边界
  • 一致性:关键写路径(好友状态、权限变更、任务触发)使用事务保障
  • 可演进:当前阶段采用重建库快速迭代;后续稳定后切换为增量迁移与灰度

Technical Approach

采用“认证域(auth.users+ 业务域(public.*)”分层建模。保持 auth.users 作为身份主键来源,业务表统一引用 user_id UUID -> auth.users.id。领域边界拆分为:Identity/Profile、Social Graph、Collaboration(事项/订阅/权限)、Inbox、Todo、Automation。通过“规范化主模型 + 局部物化/冗余快照”平衡一致性与查询性能。

Key Decisions

Decision Rationale
用户与 agent 采用 1:1 主约束 + 可扩展结构 当前满足"每用户专属 agent",未来允许多 agent 形态演进
记忆系统采用单表 + memory_type 区分 user 类型可选 agent_idwork 类型必须绑定 agent_id
好友关系用单表双向规范化表示 避免 A-B / B-A 重复,降低去重成本
事项权限采用 ACL 表而非仅 owner 满足“仅特定人可修改”的协作场景
待办采用主表 + 关联表 todos + todo_sources 保证来源关系可校验
自动化采用 Jobs 单表 + Sessions 关联 sessions 通过 session_type + job_id 区分普通对话与自动化运行
inbox 采用单表接收者视角 发送者 + 消息类型 + 关联业务,一表搞定待处理消息

A. 设计原则与边界

1) 核心实体与聚合边界

  • 用户聚合:profiles(含 settings JSONB, user_agents, memories
  • 社交聚合:friendships, groups, group_members
  • 协作事项聚合:schedule_items, schedule_subscriptions(当前仅用户主体)
  • 消息聚合:inbox_messages
  • 待办聚合:todos
  • 自动化聚合:automation_jobs

2) 一致性分级

  • 强一致(同事务):好友关系状态迁移、群组成员角色变更、事项权限写入、定时任务抢占执行
  • 最终一致:inbox 衍生、待办同步、提醒派发(允许异步补偿)

3) 多租户假设

  • 默认假设:单租户产品(同一业务库服务所有用户),以 user_id 做数据隔离
  • 扩展预留:各核心表可预留 tenant_id UUID NULL(需业务确认是否近期引入组织空间)

B. 领域模型与关系图(文字化)

实体与关系

  • auth.users (1) - (1) profilessettings 作为 JSONB 内嵌)
  • auth.users (1) - (1) user_agents
  • auth.users (1) - (N) memories
  • user_agents (1) - (N) memorieswork 类型)
  • auth.users (N) - (N) auth.users 通过 friendships
  • auth.users (1) - (N) groups(创建者)
  • groups (1) - (N) group_membersauth.users (1) - (N) group_members
  • auth.users (1) - (N) schedule_items(创建者)
  • schedule_items (1) - (N) schedule_subscriptionsauth.users (1) - (N) schedule_subscriptions
  • auth.users (1) - (N) inbox_messages
  • auth.users (1) - (N) todos
  • auth.users (1) - (N) automation_jobs
  • automation_jobs (1) - (N) sessions(通过 sessions.job_id 关联)

关键约束

  • 唯一性:
    • user_agents.user_id 唯一
    • friendships(user_low_id, user_high_id) 唯一
    • group_members(group_id, user_id) 唯一
    • schedule_subscriptions(item_id, subscriber_id) 唯一
  • CHECK
    • friendships: user_low_id < user_high_iduser_low_id <> user_high_id
    • schedule_subscriptions: permission BETWEEN 0 AND 7
    • memories: work 类型必须有 agent_iduser 类型必须无 agent_id
    • sessions: session_type/job_id 组合一致
  • 外键:统一显式 ON DELETE 策略(见下)
  • 可空性:权限关键字段、状态字段默认 NOT NULL
  • 删除策略:
    • 用户删除:大部分 CASCADE(用户私有数据);跨用户协作数据优先软删
    • 事项删除:对子表 CASCADE;待办保留历史,改 status = 'archived'

外键删除策略明细(必做)

  • sessions.job_id -> automation_jobs.id: ON DELETE RESTRICT
  • todo_sources.todo_id -> todos.id: ON DELETE CASCADE
  • todo_sources.schedule_item_id -> schedule_items.id: ON DELETE CASCADE
  • inbox_messages.friendship_id -> friendships.id: ON DELETE CASCADE
  • inbox_messages.schedule_item_id -> schedule_items.id: ON DELETE CASCADE
  • inbox_messages.group_id -> groups.id: ON DELETE CASCADE

C. 数据库表设计(PostgreSQL

以下为推荐主表(方案 1,规范化优先)。字段示例采用 UUID + timestamptz + enum/text-check

1) 用户与 agent

profiles(已有,建议补齐)

  • PK: id UUID (auth.users.id)
  • 关键字段: username, avatar_url, bio
  • 新增 JSONB 字段:
    • settings JSONB(用户自定义设置,含 version, preferences, privacy, notification 四大块)
  • 时间字段: created_at, updated_at, deleted_at
  • 索引:
    • INDEX(username)(允许重名,仅用于列表查询)
    • GIN(settings)(支持 JSONB 表达式查询)
    • 表达式索引:(settings->'notification'->>'enabled')(按需,对高频查询字段单独建)
  • 审计: created_by, updated_by(可等于 id
  • 删除策略: 用户删除时 CASCADE

user_agents

  • PK: id UUID
  • 关键字段:
    • user_id UNIQUE(每用户专属 agent
    • llm_id UUID NOT NULL(关联绑定的 LLM 模型)
    • agent_type VARCHAR(20) NOT NULL(枚举限制:INTENT_RECOGNITION | TASK_EXECUTION | RESULT_REPORTING
    • config JSONBagent 配置参数)
  • 时间字段: created_at, updated_at, deleted_at
  • 状态字段: statusactive|paused|migrating
  • 索引:
    • UNIQUE(user_id) WHERE deleted_at IS NULL
    • INDEX(status)
    • INDEX(agent_type)
    • GIN(config)(按需)
  • 审计: created_by, updated_by

memories

  • PK: id UUID
  • 关键字段:
    • owner_id(用户,NOT NULL
    • agent_idwork 类型时必需)
    • memory_type(枚举:user | work
    • title
    • contentJSONB,存储具体记忆结构)
    • sourcemanual | agent | imported
  • 时间字段: created_at, updated_at
  • 状态字段: statusactive | disabled
  • 索引:
    • INDEX(owner_id, memory_type, status)
    • INDEX(agent_id, memory_type, status)
    • GIN(content)(支持 JSONB 内容查询)
  • 约束: CHECK ((memory_type = 'work' AND agent_id IS NOT NULL) OR (memory_type = 'user' AND agent_id IS NULL))

memory_type 说明

类型 agent_id 说明
user 可空 用户记忆:偏好、背景信息、实体等
work 必需 工作记忆:长期运行后对工作流程的经验整理,避免重复错误

content JSONB 示例

// 用户记忆
{"type": "preference", "data": {"style": "concise", "language": "zh-CN"}}

// 工作记忆
{"type": "workflow_summary", "data": {"task": "代码审查", "learnings": ["优先检查安全漏洞", "关注性能热点"], "improvements": []}}

2) 社交关系

friendships

  • PK: id UUID
  • 关键字段:
    • user_low_id(两者中较小的 UUID
    • user_high_id(两者中较大的 UUID
    • initiator_id(发起请求方的 user_id,用于追溯谁主动)
    • status, requested_at, accepted_at, blocked_by
  • 时间字段: created_at, updated_at
  • 状态字段: statuspending|accepted|blocked|declined|canceled
  • 约束:
    • CHECK(user_low_id < user_high_id)(强制小值放 low,大值放 high,确保 A→B 和 B→A 是同一行)
    • CHECK(initiator_id IN (user_low_id, user_high_id))
    • UNIQUE(user_low_id, user_high_id)
  • 索引:
    • INDEX(user_low_id, status)
    • INDEX(user_high_id, status)
    • 部分索引 INDEX(status) WHERE status='pending'
  • 审计: created_by, updated_by

查询示例

  • 查询用户 A 的所有好友:SELECT * FROM friendships WHERE user_low_id = A OR user_high_id = A

groups

  • PK: id UUID
  • 关键字段: name, description, owner_id
  • 时间字段: created_at, updated_at, deleted_at
  • 状态字段: statusactive|archived
  • 索引: INDEX(owner_id, status)
  • 审计: created_by, updated_by

group_members

  • PK: id UUID
  • 关键字段:
    • group_id, user_id
    • role(枚举:owner | admin | member
    • join_sourceinvited|joined
    • invited_by, joined_at
  • 时间字段: created_at, updated_at, removed_at
  • 状态字段: statusactive|muted|removed
  • 约束: UNIQUE(group_id, user_id)
  • 索引:
    • INDEX(group_id, role, status)
    • INDEX(user_id, status)
  • 审计: created_by, updated_by

role 说明

role 含义
owner 群主/创建者
admin 管理员
member 普通成员
  • 角色可升降:服务层变更 role 字段即可

3) 用户设置(已合并至 profiles 表)

用户设置采用 JSONB 内嵌方式,渐进式扩展无需改表结构:

{
  "version": 1,
  "preferences": {
    "interface_language": "zh-CN",
    "ai_language": "zh-CN",
    "timezone": "Asia/Shanghai"
  },
  "privacy": {},
  "notification": {}
}
  • 索引策略:对高频查询字段使用表达式索引
  • 更新方式:服务层使用 JSONB merge 或字段级 UPDATE,避免读-改-写并发问题(建议用 jsonb_set 原子操作)

4) 事项与订阅/权限

schedule_items

  • PK: id UUID
  • 关键字段:
    • owner_id
    • title
    • description
    • start_at
    • end_at
    • timezone(用于将日程时间转换为用户本地时间显示)
    • metadataJSONB,扩展字段)
    • recurrence_rule(可选,支持循环日程)
    • source_typemanual | imported | agent_generated
  • 时间字段: created_at, updated_at
  • 状态字段: statusactive | completed | canceled | archived
  • 索引:
    • INDEX(owner_id, start_at)
    • INDEX(status, start_at)
  • 审计: created_by

metadata JSONB 示例

{
  "color": "#FF6B6B",
  "location": "会议室A",
  "notes": "记得提前准备投影仪",
  "attachments": [
    {
      "name": "会议纪要.pdf",
      "url": "https://...",
      "visible_to": [],
      "type": "document"
    },
    {
      "name": "投影仪提醒",
      "visible_to": ["uuid1"],
      "type": "reminder",
      "content": "记得带投影仪"
    },
    {
      "name": "技术方案.docx",
      "url": "https://...",
      "visible_to": ["uuid2"],
      "type": "document",
      "note": "需要他确认预算"
    }
  ],
  "version": 1
}
type 说明 特殊字段
document 文档/文件 url, note
reminder 提醒 content

schedule_subscriptions

  • PK: id UUID
  • 关键字段:
    • item_id
    • subscriber_id
    • permission(INTEGER,用位运算存储权限组合,NOT NULL DEFAULT 1
    • notify_levelall | mentions | noneNOT NULL DEFAULT 'all'
  • 时间字段: created_at
  • 状态字段: statusactive | paused | unsubscribedNOT NULL DEFAULT 'active'
  • 约束: UNIQUE(item_id, subscriber_id)
  • 约束补充: CHECK(permission BETWEEN 0 AND 7)view=1, invite=2, edit=40 表示无权限)
  • 索引: INDEX(subscriber_id, status), INDEX(item_id, status)
  • 审计: created_by

权柄说明(位运算)

权柄 二进制 说明
view 1 001 查看事项详情
invite 2 010 邀请其他人订阅此事项
edit 4 100 修改事项内容、管理订阅
  • 权限检查:permission & 2 = 2 检查是否有 invite 权限
  • 权限添加:permission | 2 添加 invite 权限
  • 事项 owner 默认拥有全部权柄:7111
  • owner 权柄由服务层恒等判定为 7,不依赖 owner 是否在 schedule_subscriptions 中存在记录

当前版本边界

  • schedule_subscriptions 仅支持用户订阅(subscriber_id -> auth.users.id
  • 事项协作暂不引入群主体授权

5) 待处理消息(Inbox

inbox_messages

  • PK: id UUID
  • 关键字段:
    • recipient_id(接收者)
    • sender_id(发送者,系统消息可为 NULL
    • message_type(枚举:friend_request | calendar | system | group
    • friendship_id(可空,friend_request 时必填)
    • schedule_item_id(可空,calendar 时必填)
    • group_id(可空,group 时必填)
    • contentTEXT,消息内容,系统消息用)
  • 时间字段: created_at
  • 状态字段:
    • is_readBOOLEAN,是否已读)
    • statuspending | accepted | rejected | dismissed
  • 索引:
    • INDEX(recipient_id, status, created_at DESC)
    • 部分索引 INDEX(recipient_id, created_at DESC) WHERE status='pending'
  • 审计: created_by

message_type 与业务字段对应关系

message_type 对应业务字段
friend_request friendship_id -> friendships.id
calendar schedule_item_id -> schedule_items.id
system 三个业务字段均为 NULL(内容直接在 content
group group_id -> groups.id

说明:一张表搞定,接收者视角,通过 message_type + 对应业务字段 直接定位要处理的业务,避免单列多态外键带来的引用不一致问题。

一致性约束(必做)

  • 使用 CHECK 保证不同 message_type 下仅允许对应业务字段非空(system 时业务字段全空)
  • 使用 CHECK 保证 message_type='system'sender_id IS NULL,否则 sender_id IS NOT NULL
  • friendship_idschedule_item_idgroup_id 分别建立 FK,并显式声明 ON DELETE 策略

6) 待办

todos

  • PK: id UUID
  • 关键字段:
    • owner_id
    • title
    • description
    • due_at
    • priority(INTEGER,用于四象限:1=重要且紧急, 2=重要不紧急, 3=紧急不重要, 4=不重要不紧急)
  • 时间字段: created_at, completed_at
  • 状态字段: statuspending | done | canceled
  • 索引:
    • INDEX(owner_id, status, due_at)
    • INDEX(owner_id, created_at DESC)
    • 部分索引 INDEX(owner_id, due_at) WHERE status='pending'
  • 审计: created_by

todo_sources

  • PK: id UUID
  • 关键字段:
    • todo_idFK -> todos.id
    • schedule_item_idFK -> schedule_items.id
  • 时间字段: created_at
  • 约束: UNIQUE(todo_id, schedule_item_id)
  • 索引: INDEX(todo_id), INDEX(schedule_item_id)

说明

  • 手动创建待办:不写 todo_sources
  • 从事项提取待办:写入 todo_sources,替代 JSONB 数组,保证来源关系可校验

7) 自动化定时任务

automation_jobs

  • PK: id UUID
  • 关键字段:
    • owner_id
    • title(任务标题)
    • promptAI 执行的 prompt
    • schedule_type(枚举:daily | weekly
    • run_at(首次运行时间)
    • next_run_at(下次运行时间,调度器扫描主字段)
    • timezone(时区,如 Asia/Shanghai
    • last_run_at(最近运行时间,可空)
  • 时间字段: created_at, updated_at
  • 状态字段: statusactive | disabled
  • 索引: INDEX(owner_id, status), INDEX(status, next_run_at)
  • 约束补充: UNIQUE(id, owner_id)(用于 sessions(job_id, user_id) 归属一致性外键)
  • 审计: created_by

说明:定时任务执行时,在 sessions 表创建记录存储 AI 对话内容。

8) 会话表扩展(已有 sessions

sessions(更新)

  • 新增字段:
    • session_typechat | automation
    • job_id(可空,FK -> automation_jobs.id
  • 一致性约束:
    • CHECK((session_type = 'chat' AND job_id IS NULL) OR (session_type = 'automation' AND job_id IS NOT NULL))
    • 通过复合 FK 约束归属一致性:FOREIGN KEY(job_id, user_id) -> automation_jobs(id, owner_id)
  • 索引:
    • INDEX(user_id, session_type, last_activity_at DESC)
    • INDEX(job_id)

D. 权限与协作模型

1) 事项权限落表

  • 权限直接存储在 schedule_subscriptions.permission 整数中(位运算)
  • owner 不写入 schedule_subscriptionsowner 权限仅由 schedule_items.owner_id 推导
  • 权限决策顺序:
    1. schedule_items.owner_id → 服务层恒等全部权柄 ["view", "invite", "edit"]7
    2. schedule_subscriptions 中该用户的 permission 位图
    3. 非 owner 且非 subscriber 默认无权限(0

2) 当前版本边界

  • 事项权限仅处理用户主体(owner + subscriber
  • 群组与事项权限继承关系不在本期范围

E. 消息与待办联动

1) inbox 关联业务对象

  • inbox_messages.message_type 枚举:
    • friend_request(好友请求)→ friendship_id 指向 friendships
    • calendar(日程邀请)→ schedule_item_id 指向 schedule_items
    • system(系统消息)→ 业务字段均为 NULL
    • group(群组邀请)→ group_id 指向 groups
  • 通过 message_type + 对应业务字段 直接定位业务对象,并用 CHECK 约束保证字段一致性

2) 待办来源提取

  • 从事项提取待办时,写入 todo_sources(todo_id, schedule_item_id)
  • 手动创建的待办不写 todo_sources
  • 支持多来源:同一待办可关联多个日程事项(多行 todo_sources
  • 待办完成时无需反向更新来源事项状态(简化设计)

F. 定时任务模型

1) 调度规则

  • schedule_type 枚举:daily(每日) | weekly(每周)
  • run_at 用于首次执行时间,next_run_at 用于后续调度
  • 调度器扫描 status='active' AND next_run_at <= now() 的任务,执行后回写下一次 next_run_at
  • timezone 参与下一次执行时间计算,避免时区偏差

2) 执行记录

  • 每次执行在 sessions 表创建记录,通过 sessions.job_id 关联 job
  • sessions 通过 session_type 区分 chatautomation
  • 执行失败时记录在 automation_jobs(如 last_error,可后续细化)

G. 数据库迁移思路

策略:重建数据库 + Alembic ORM 迁移

由于是全新设计的数据模型,且当前处于开发初期(可清除旧数据),采用重建数据库策略:

执行门禁(强制)

  • 仅允许在本地开发环境执行
  • 禁止在生产/共享环境执行 rm backend/alembic/versions/*.py
  • 执行前必须备份数据库或创建 git tag
  1. 删除所有旧 migration 脚本(保留 env.py
  2. 创建 ORM 模型文件
  3. 生成 Alembic migration
  4. 重建数据库并执行迁移

执行步骤

  1. 删除旧 migration 文件

    rm backend/alembic/versions/*.py
    
  2. 重建空数据库(确保以空库基线生成 initial migration

    docker compose --env-file .env -f infra/docker/docker-compose.yml down -v
    docker compose --env-file .env -f infra/docker/docker-compose.yml up -d db
    
  3. 创建 ORM 模型文件(参考 models/ 目录结构)

    • 新增:user_agents.py, memories.py, friendships.py, groups.py, group_members.py, schedule_items.py, schedule_subscriptions.py, inbox_messages.py, todos.py, todo_sources.py, automation_jobs.py
    • 更新:profile.py - 添加 settings 字段
    • 更新:agent_chat_session.py - 添加 session_typejob_id 字段
    • 重写:create_profile_for_new_user 触发器,确保 profiles.settings 有默认值
  4. 更新 models/__init__.py 导出所有模型

  5. 更新 alembic/env.py 添加模型导入

  6. 生成 initial migration(以空库为对比基线)

    cd backend && uv run alembic revision --autogenerate -m "initial schema"
    
  7. 为所有新建 public 业务表补齐 RLSSELECT/INSERT/UPDATE/DELETE policy

    • 每张表都执行 ENABLE ROW LEVEL SECURITY
    • 每张表都显式创建 SELECT/INSERT/UPDATE/DELETE policy
    • downgrade 必须可逆,不得弱化既定安全边界
    • anon/authenticated 默认全部 deny

    RLS 最小策略矩阵(本期统一模板):

    • anonSELECT/INSERT/UPDATE/DELETE 全部 deny
    • authenticatedSELECT/INSERT/UPDATE/DELETE 全部 deny
    • service_role:由后端服务连接使用,不依赖 RLS 放行
  8. 执行迁移

    cd backend && uv run alembic upgrade head
    
  9. 验证表结构

H. 交付物

ORM 模型文件清单

文件 说明
models/user_agents.py 用户专属 agent
models/memories.py 用户/工作记忆
models/friendships.py 好友关系
models/groups.py 群组
models/group_members.py 群组成员
models/schedule_items.py 日程事项
models/schedule_subscriptions.py 日程订阅与权限
models/inbox_messages.py 待处理消息
models/todos.py 待办
models/todo_sources.py 待办与事项来源关联
models/automation_jobs.py 定时任务
models/profile.py 更新:添加 settings 字段
models/agent_chat_session.py 更新:添加 session_typejob_id 字段

执行步骤

  1. 删除旧 migration 文件

    rm backend/alembic/versions/*.py
    
  2. 重建空数据库(确保以空库基线生成 initial migration

    docker compose --env-file .env -f infra/docker/docker-compose.yml down -v
    docker compose --env-file .env -f infra/docker/docker-compose.yml up -d db
    
  3. 创建/更新 ORM 模型文件

  4. 更新 models/__init__.py 导出所有模型

  5. 更新 alembic/env.py 添加模型导入

  6. 生成 initial migration(以空库为对比基线)

    cd backend && uv run alembic revision --autogenerate -m "initial schema"
    
  7. 为所有新建 public 业务表补齐 RLSSELECT/INSERT/UPDATE/DELETE policy

    • 每张表都执行 ENABLE ROW LEVEL SECURITY
    • 每张表都显式创建 SELECT/INSERT/UPDATE/DELETE policy
    • downgrade 必须可逆,不得弱化既定安全边界
  8. 执行迁移

    cd backend && uv run alembic upgrade head
    
  9. 更新测试文件适配新表结构

I. 数据库表名规范与审计

1) 命名规范(统一执行)

  • 使用 snake_case
  • 业务表统一使用复数名词(如 profiles, friendships, automation_jobs
  • 关联表使用 <主实体复数>_<从实体复数> 或约定俗成复数短语(如 group_members, todo_sources
  • 禁止过于泛化的表名(如 messages, sessions),必须带业务前缀
  • 存量历史表允许短期例外,但必须在审计表中登记并给出迁移计划
  • 缩写保持一致:LLM 统一使用 llm 前缀,不混用 model/llm 两套命名

2) 表名审计结果

当前表名 审计结论 建议表名 说明
profiles 通过 - 符合复数名词规范
user_agents 通过 - 语义清晰
memories 通过 - 语义清晰
friendships 通过 - 关系表命名清晰
groups 通过 - 符合规范
group_members 通过 - 关联表命名清晰
schedule_items 通过 - 语义清晰
schedule_subscriptions 通过 - 语义清晰
inbox_messages 通过 - 带业务前缀,避免歧义
todos 通过 - 简洁且清晰
todo_sources 通过 - 关联关系明确
automation_jobs 通过 - 语义清晰
llms 通过 - 与 LLM 语义一致
llm_factory 建议调整 llm_factories 当前为单数,建议改复数以统一规范
sessions 建议调整 agent_chat_sessions 过于泛化,建议加业务前缀
messages 建议调整 agent_chat_messages 过于泛化,建议加业务前缀

3) 落地建议

  • 本期命名边界:不重命名 llm_factory/sessions/messages,仅在新表严格执行命名规范
  • 本期最小可行:先保持现有表名可运行,新增表全部遵循规范
  • 下期统一治理:通过一次性迁移将 llm_factory/sessions/messages 重命名到规范名
  • 若本期直接重命名,需同步 ORM 模型、外键、索引、RLS policy 名称与运行文档