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

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

## Overview

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

## Requirements

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

### Non-Functional
- [x] 性能：核心读路径（inbox 列表、待办列表、事项列表）P95 < 150ms（单用户典型数据量）
- [x] 安全：权限以后端业务授权为准；数据库层保留 RLS 防御边界
- [x] 一致性：关键写路径（好友状态、权限变更、任务触发）使用事务保障
- [x] 可演进：支持旧表迁移、双写与灰度切换

## 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 形态演进 |
| 好友关系用单表双向规范化表示 | 避免 A-B / B-A 重复，降低去重成本 |
| 事项权限采用 ACL 表而非仅 owner | 满足“仅特定人可修改”的协作场景 |
| 待办采用单表 + JSONB 来源数组 | 一张表搞定待办，source_ids 存储关联日程事件 |
| 自动化采用 Jobs + Runs 双表 | 只支持 daily/weekly 两种循环，active/disabled 两种状态 |
| inbox 采用单表接收者视角 | 发送者 + 消息类型 + 关联业务，一表搞定待处理消息 |

## A. 设计原则与边界

### 1) 核心实体与聚合边界
- 用户聚合：`profiles`（含 settings JSONB）, `user_agents`
- 社交聚合：`friendships`, `groups`, `group_members`
- 协作事项聚合：`schedule_items`, `schedule_subscriptions`
- 消息聚合：`inbox_messages`
- 待办聚合：`todos`
- 自动化聚合：`automation_jobs`, `automation_runs`

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

### 3) 多租户假设
- 默认假设：单租户产品（同一业务库服务所有用户），以 `user_id` 做数据隔离
- 扩展预留：各核心表可预留 `tenant_id UUID NULL`（需业务确认是否近期引入组织空间）

## B. 领域模型与关系图（文字化）

### 实体与关系
- `auth.users (1) - (1) profiles`（settings 作为 JSONB 内嵌）
- `auth.users (1) - (1) user_agents`
- `auth.users (N) - (N) auth.users` 通过 `friendships`
- `auth.users (1) - (N) groups`（创建者）
- `groups (1) - (N) group_members`，`auth.users (1) - (N) group_members`
- `auth.users (1) - (N) schedule_items`（创建者）
- `schedule_items (1) - (N) schedule_subscriptions`，`auth.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) automation_runs`

### 关键约束
- 唯一性：
  - `user_agents.user_id` 唯一
  - `friendships(user_low_id, user_high_id)` 唯一
  - `group_members(group_id, user_id)` 唯一
  - `schedule_subscriptions(item_id, subscriber_id)` 唯一
- 外键：统一显式 `ON DELETE` 策略（见下）
- 可空性：权限关键字段、状态字段默认 `NOT NULL`
- 删除策略：
  - 用户删除：大部分 `CASCADE`（用户私有数据）；跨用户协作数据优先软删
  - 事项删除：对子表 `CASCADE`；待办保留历史，改 `status = 'archived'`

## C. 数据库表设计（PostgreSQL）

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

### 1) 用户与 agent

#### `profiles`（已有，建议补齐）
- PK: `id UUID` (`auth.users.id`)
- 关键字段: `username`, `avatar_url`, `bio`
- **新增 JSONB 字段**:
  - `settings JSONB`（用户自定义设置，含 `preferences`, `privacy`, `notification` 三大块）
  - `settings_version INTEGER DEFAULT 1`（兼容旧数据的版本字段）
- 时间字段: `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 JSONB`（agent 配置参数）
  - `capability_version INTEGER DEFAULT 1`
- 时间字段: `created_at`, `updated_at`, `deleted_at`
- 状态字段: `status`（`active|paused|migrating`）
- 索引:
  - `UNIQUE(user_id) WHERE deleted_at IS NULL`
  - `INDEX(status)`
  - `INDEX(agent_type)`
  - `GIN(config)`（按需）
- 审计: `created_by`, `updated_by`

### 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`
- 状态字段: `status`（`pending|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`, `visibility`, `owner_id`
- 时间字段: `created_at`, `updated_at`, `deleted_at`
- 状态字段: `status`（`active|archived`）
- 索引: `INDEX(owner_id, status)`, `INDEX(visibility)`
- 审计: `created_by`, `updated_by`

#### `group_members`
- PK: `id UUID`
- 关键字段: 
  - `group_id`, `user_id`
  - `role`（枚举：`creator` | `admin` | `member`）
  - `join_source`（`invited|joined`）
  - `invited_by`, `joined_at`
- 时间字段: `created_at`, `updated_at`, `removed_at`
- 状态字段: `status`（`active|muted|removed`）
- 约束: `UNIQUE(group_id, user_id)`
- 索引:
  - `INDEX(group_id, role, status)`
  - `INDEX(user_id, status)`
- 审计: `created_by`, `updated_by`

**role 说明**：
| role | 含义 | 创建事项时默认给群组的权限 |
|------|------|---------------------------|
| `creator` | 群主/创建者 | `["view", "invite", "edit"]` |
| `admin` | 管理员 | `["view", "invite"]` |
| `member` | 普通成员 | `["view"]` |

- 角色可升降：服务层变更 role 字段即可
- 角色决定了该用户在群里创建的日程事项默认授予群组的权限（见下方映射）

### 3) 用户设置（已合并至 profiles 表）

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

```json
{
  "version": 1,
  "preferences": {
    "theme": "dark",
    "language": "zh-CN",
    "timezone": "Asia/Shanghai"
  },
  "privacy": {
    "profile_visible_to": "friends",
    "activity_visible_to": "friends",
    "allow_friend_requests": true
  },
  "notification": {
    "enabled": true,
    "push_enabled": true,
    "email_enabled": false,
    "quiet_hours_start": "22:00",
    "quiet_hours_end": "08:00"
  }
}
```

- 扩展方式：新增字段时递增 `settings_version`，应用层做 schema 兼容
- 索引策略：对高频查询字段（如 `notification.enabled`）使用表达式索引
- 更新方式：服务层使用 JSONB merge 或字段级 UPDATE，避免读-改-写并发问题（建议用 `jsonb_set` 原子操作）

### 4) 事项与订阅/权限

#### `schedule_items`
- PK: `id UUID`
- 关键字段:
  - `owner_id`
  - `title`
  - `description`
  - `start_at`
  - `end_at`
  - `timezone`
  - `recurrence_rule`（可选，支持循环日程）
  - `source_type`（`manual | imported | agent_generated`）
- 时间字段: `created_at`, `updated_at`
- 状态字段: `status`（`active | completed | canceled`）
- 索引: 
  - `INDEX(owner_id, start_at)`
  - `INDEX(status, start_at)`
- 审计: `created_by`

#### `schedule_subscriptions`
- PK: `id UUID`
- 关键字段: 
  - `item_id`
  - `subscriber_id`
  - `permission`（JSONB 数组，权柄组合：`["view"]` / `["view", "edit"]` / `["view", "invite", "edit"]`）
  - `notify_level`（`all | mentions | none`）
- 时间字段: `created_at`
- 状态字段: `status`（`active | paused | unsubscribed`）
- 约束: `UNIQUE(item_id, subscriber_id)`
- 索引: `INDEX(subscriber_id, status)`, `INDEX(item_id, status)`
- 审计: `created_by`

**权柄说明**：
| 权柄 | 含义 |
|------|------|
| `view` | 查看事项详情 |
| `invite` | 邀请其他人订阅此事项 |
| `edit` | 修改事项内容、管理订阅 |

- 事项 owner 默认拥有全部权柄：`["view", "invite", "edit"]`
- 权限变更使用 JSONB 原子操作：`UPDATE ... SET permission = permission || '["edit"]'::jsonb`

### 5) 待处理消息（Inbox）

#### `inbox_messages`
- PK: `id UUID`
- 关键字段: 
  - `recipient_id`（接收者）
  - `sender_id`（发送者）
  - `message_type`（`friend_request` / `group_invitation` / `schedule_item_shared`）
  - `content`（TEXT 或 JSONB，消息内容）
  - `related_type`（关联业务类型：`friendship` / `group` / `schedule_item`）
  - `related_id`（关联业务 ID）
- 时间字段: `created_at`, `read_at`, `acted_at`
- 状态字段: `status`（`pending|read|accepted|rejected|dismissed`）
- 索引:
  - `INDEX(recipient_id, status, created_at DESC)`
  - 部分索引 `INDEX(recipient_id, created_at DESC) WHERE status='pending'`
- 审计: `created_by`

**说明**：一张表搞定，接收者视角，只关心谁发的、什么类型、关联什么业务对象。

### 6) 待办

#### `todos`
- PK: `id UUID`
- 关键字段: 
  - `owner_id`
  - `title`
  - `description`
  - `due_at`
  - `priority`（枚举：`low | medium | high | urgent`）
  - `source_ids`（JSONB 数组，关联的日程事件 ID，`[]` 表示手动创建）
- 时间字段: `created_at`, `completed_at`
- 状态字段: `status`（`pending | done | canceled`）
- 索引:
  - `INDEX(owner_id, status, due_at)`
  - `INDEX(owner_id, created_at DESC)`
  - 部分索引 `INDEX(owner_id, due_at) WHERE status='pending'`
- 审计: `created_by`

### 7) 自动化定时任务

#### `automation_jobs`
- PK: `id UUID`
- 关键字段: 
  - `owner_id`
  - `name`
  - `job_type`
  - `target_type`
  - `target_id`
  - `params`（JSONB）
  - `schedule_type`（枚举：`daily | weekly`）
  - `schedule_time`（时间，如 `09:00` 表示每天/每周几点执行）
- 时间字段: `created_at`, `updated_at`
- 状态字段: `status`（`active | disabled`）
- 索引: `INDEX(owner_id, status)`
- 审计: `created_by`

#### `automation_runs`
- PK: `id UUID`
- 关键字段: 
  - `job_id`
  - `scheduled_at`（计划执行时间）
  - `started_at`
  - `finished_at`
  - `status`（`queued | running | succeeded | failed`）
  - `attempt`
  - `error_message`
  - `result`（JSONB）
- 时间字段: `created_at`
- 索引: `INDEX(job_id, scheduled_at DESC)`, `INDEX(status, scheduled_at)`

## D. 权限与协作模型

### 1) 事项权限落表
- 权限直接存储在 `schedule_subscriptions.permission` JSONB 数组中
- 权限决策顺序：
  1. `schedule_items.owner_id` → 全部权柄 `["view", "invite", "edit"]`
  2. `schedule_subscriptions` 中该用户的 `permission` 数组
  3. 默认只有 `["view"]`

### 2) 群组与事项权限
- 群成员在事项中的权限通过 `schedule_subscriptions.subject_type = 'group'` 关联
- 群角色决定默认权限：
  - `creator` → `["view", "invite", "edit"]`
  - `admin` → `["view", "invite"]`
  - `member` → `["view"]`

## E. 消息与待办联动

### 1) inbox 关联业务对象
- `inbox_messages.message_type` 枚举：
  - `friend_request`（好友请求）
  - `group_invitation`（群组邀请）
  - `schedule_item_shared`（日程事项分享）
- 通过 `related_type` / `related_id` 关联业务对象

### 2) 待办来源提取
- 从事项提取待办时，将日程事件 ID 存入 `todos.source_ids` JSONB 数组
- 手动创建的待办 `source_ids = []`
- 支持多来源：同一待办可关联多个日程事项 `source_ids = [<id1>, <id2>]`
- 待办完成时无需反向更新来源事项状态（简化设计）

## F. 定时任务模型

### 1) 调度规则
- `schedule_type` 枚举：`daily`（每日） | `weekly`（每周）
- `schedule_time` 格式：`HH:MM`（如 `09:00` 表示每天/每周几点执行）
- 调度器扫描 `status='active'` 的任务，按 `schedule_type + schedule_time` 计算下次执行时间

### 2) 执行记录
- 每次执行生成 `automation_runs` 记录
- 状态流转：`queued` → `running` → `succeeded` | `failed`
- 失败重试：`attempt` 字段记录当前重试次数（需业务确认最大重试次数）

## G. 演进与迁移计划（从旧表到新模型）

### Phase 1: 基础并行建模（8-12 小时）
1. 新建核心表（不删旧表）：`user_agents`, `friendships`, `groups`, `group_members`
2. 对 `profiles` 表新增 `settings JSONB`, `settings_version` 字段
3. 建立最小外键和索引，启用 RLS deny-all 策略
4. 提供只写新表的影子接口（内部开关）

### Phase 2: 协作与联动接入（12-16 小时）
1. 新建 `schedule_items`, `schedule_subscriptions`, `inbox_messages`, `todos`, `automation_jobs`, `automation_runs`
2. 编写回填脚本（从旧事项/旧消息结构回填，若不存在则跳过）
3. 开启双写：旧接口写旧表同时写新表，记录双写差异日志

### Phase 3: 读切换与一致性校验（8-12 小时）
1. API 读路径灰度切换到新表（按用户百分比）
2. 每日对账：记录数、状态分布、关键字段哈希比对
3. 指标稳定后停止旧表写入，保留只读回滚窗口

### Phase 4: 收尾与清理（4-8 小时）
1. 下线旧读路径和旧双写逻辑
2. 保留旧表冷备份后归档/删除
3. 固化运行手册与告警阈值

### 回滚策略
- 任意阶段回滚：读切回旧表 + 关闭新表写开关
- 双写阶段故障：保留操作日志，可按时间窗重放补偿
- 最终切换前必须满足：新旧关键查询结果偏差 < 0.1%

## H. 两套方案对比

### 方案 1（推荐）：规范化、可维护性优先
- 特点：按领域拆表，ACL 与来源映射独立，严格约束
- 优点：一致性好、权限边界清晰、长期演进成本低
- 缺点：联表较多，初期 API 复杂度较高

### 方案 2：开发效率优先、适度反规范化
- 特点：将部分结构合并为 JSONB（如 `permissions_snapshot`, `todo_origin`）
- 优点：开发快、迁移初期改动小
- 缺点：约束弱、查询和审计困难、后续重构成本高
- 注：`user_settings` 已按此思路内嵌至 profiles，其他模块仍建议保持规范化

### 对比矩阵

| 维度 | 方案 1（规范化） | 方案 2（反规范化） |
|------|------------------|--------------------|
| 复杂度 | 中高 | 中 |
| 查询性能 | 读热点需索引与缓存优化 | 单行读取快，复杂筛选慢 |
| 写入成本 | 中（多表事务） | 低到中 |
| 扩展性 | 高 | 中低 |
| 风险 | 中（实施复杂） | 中高（数据质量和权限风险） |

### 推荐结论
- 推荐方案 1：当前业务已包含社交关系、协作权限、跨域联动和自动化调度，若选择反规范化将把复杂性转移到应用层并放大后续维护风险。方案 1 在 FastAPI + PostgreSQL 下更符合长期可维护与可审计目标。

## I. 交付物

### I-1. 可直接进入实现计划的结论性摘要（12 条）
1. 以 `auth.users` 为身份主键，业务表统一 `user_id` 外键。
2. 引入 `user_agents`，通过 `UNIQUE(user_id)` 满足每用户专属 agent。
3. 用户设置内嵌至 `profiles.settings JSONB`，支持渐进式扩展。
4. 好友关系采用标准化双向一行模型，避免重复边。
5. 群组采用 `groups + group_members`，角色内建 creator/admin/member。
6. 事项、订阅、权限三表解耦，支持多人订阅与精细编辑授权。
7. inbox 采用单表 `inbox_messages`，接收者视角简洁设计。
8. 待办采用单表 `todos`，通过 `source_ids` JSONB 数组存储来源日程事件。
9. 自动化采用 `jobs + runs` 双表，只支持 daily/weekly 两种循环。
10. 所有关键表补齐状态机字段与审计字段，支持可观测与追责。
11. 索引以"用户维度 + 状态 + 时间"为主，兼顾移动端列表查询。
12. 迁移走"四阶段"：并行建模 -> 双写回填 -> 读切换 -> 清理。
13. 通过幂等键、部分索引和事务边界保障高并发稳定性。

### I-2. 后续 API 设计所需数据契约清单

- 用户/agent
  - `UserAgentDTO`: `id,user_id,llm_id,agent_type,status,capability_version,config,updated_at`
  - `UserSettingsDTO`（内嵌于 Profile）: `settings JSONB, settings_version`
- 好友
  - `FriendshipDTO`: `id,user_a,user_b,status,initiator_id,requested_at,accepted_at`
  - 状态流转：`pending -> accepted|declined|canceled|blocked`
- 群组
  - `GroupDTO`: `id,name,owner_id,visibility,status`
  - `GroupMemberDTO`: `group_id,user_id,role,status,joined_at`
- 事项
  - `ScheduleItemDTO`: `id,owner_id,title,description,start_at,end_at,timezone,recurrence_rule,source_type,status,created_at`
  - `ScheduleSubscriptionDTO`: `id,item_id,subscriber_id,permission (JSONB数组),notify_level,status,created_at`
- Inbox
  - `InboxMessageDTO`: `id,recipient_id,sender_id,message_type,content,related_type,related_id,status,created_at,read_at,acted_at`
- Todo
  - `TodoDTO`: `id,owner_id,title,description,due_at,priority,status,source_ids (JSONB数组),created_at,completed_at`
- 自动化
  - `AutomationJobDTO`: `id,owner_id,name,job_type,target_type,target_id,params,schedule_type,schedule_time,status,created_at`
  - `AutomationRunDTO`: `id,job_id,scheduled_at,started_at,finished_at,status,attempt,error_message,result`

### I-3. 最小可行迁移 DDL 清单（按优先级）

P0（身份与社交基础）
1. `ALTER TABLE profiles ADD COLUMN settings JSONB DEFAULT '{}'`
2. `ALTER TABLE profiles ADD COLUMN settings_version INTEGER DEFAULT 1`
3. `CREATE INDEX idx_profiles_settings_notification ON profiles ((settings->>'notification_enabled'))`
4. `CREATE TABLE user_agents (...)`
5. `CREATE TABLE friendships (...)`
6. `CREATE TABLE groups (...)`
7. `CREATE TABLE group_members (...)`
8. `CREATE INDEX/UNIQUE/CHECK`（friendships 规范化约束）

P1（协作事项）
7. `CREATE TABLE schedule_items (...)`
8. `CREATE TABLE schedule_subscriptions (...)`
9. `CREATE INDEX`（owner/status/time + subscription 查询）

P2（消息与待办）
11. `CREATE TABLE inbox_messages (...)`
12. `CREATE TABLE todos (...)`

P3（自动化）
13. `CREATE TABLE automation_jobs (...)`
14. `CREATE TABLE automation_runs (...)`
15. `CREATE INDEX idx_automation_runs_job_scheduled (...)`

P4（安全与治理）
21. 对新增 `public` 表执行 `ALTER TABLE ... ENABLE ROW LEVEL SECURITY`
22. 为 `anon, authenticated` 创建默认 deny-all `SELECT/INSERT/UPDATE/DELETE` policy
23. 审计字段回填脚本与触发器（如需）

## Dependencies

- [ ] PostgreSQL 扩展：`pgcrypto`（UUID/哈希，若已启用可跳过）
- [ ] Alembic 迁移体系（现有）
- [ ] 后端任务执行器（Celery）用于自动化触发与补偿

## Testing Strategy

- **Unit Tests:** 状态流转、权限决策、去重哈希、幂等键生成
- **Integration Tests:** 迁移升级/回滚、双写一致性、RLS policy 基线、并发抢占执行
- **E2E Tests:** 好友请求到 inbox、群组邀请处理、事项订阅变更到待办、自动化任务触发到结果回显

## Risks & Mitigations

| Risk | Impact | Likelihood | Mitigation |
|------|--------|------------|------------|
| 旧表结构未知导致回填失败 | High | Medium | 先做 schema 探测脚本，按表存在性分支回填 |
| 双写期间新旧数据不一致 | High | Medium | 引入操作日志 + 对账任务 + 幂等补偿 |
| 权限模型过复杂影响上线进度 | Medium | Medium | 先上线最小权限集（owner/user/group），后续扩展 |
| 自动化任务并发冲突 | Medium | Medium | `SKIP LOCKED` + 幂等键 + 乐观锁版本号 |
| 索引不足导致移动端列表慢 | Medium | Medium | 先覆盖 P0/P1 热路径索引，监控后增量优化 |

## Estimated Effort

| Phase | Effort |
|-------|--------|
| Phase 1 | 8-12 hours |
| Phase 2 | 12-16 hours |
| Phase 3 | 8-12 hours |
| Phase 4 | 4-8 hours |
| **Total** | **32-48 hours** |

## 需业务确认（关键不确定项）

1. ~~`profiles.username` 是否允许重名~~（已确认：允许重名，仅建普通索引）。
2. ~~group_members.role 权柄组合~~（已确认：JSONB 数组 `["view", "invite", "edit"]`）。
3. 是否近期需要"组织/团队"多租户（决定 `tenant_id` 是否立即强制）。
4. 事项是否必须绑定群组上下文（`context_group_id` 是否必需）。
5. 自动化任务失败重试上限与退避策略（固定/指数）。
