@@ -36,19 +36,19 @@
| 用户与 agent 采用 1:1 主约束 + 可扩展结构 | 当前满足“每用户专属 agent”,未来允许多 agent 形态演进 |
| 好友关系用单表双向规范化表示 | 避免 A-B / B-A 重复,降低去重成本 |
| 事项权限采用 ACL 表而非仅 owner | 满足“仅特定人可修改”的协作场景 |
| 待办采用主 表 + 源映射表 | 支持从事项提取、手动创建、去重与追踪来源 |
| 自动化调度 采用 `rrule + cron + interval` 三选一 | 同时覆盖日历型循环和工程型间隔任务 |
| inbox 采用事件聚合模型 | 将好友请求/群组邀请/事项变更统一进入 待处理中心 |
| 待办采用单 表 + JSONB 来源数组 | 一张表搞定待办,source_ids 存储关联日程事件 |
| 自动化采用 Jobs + Runs 双表 | 只支持 daily/weekly 两种循环,active/disabled 两种状态 |
| inbox 采用单表接收者视角 | 发送者 + 消息类型 + 关联业务,一表搞定 待处理消息 |
## A. 设计原则与边界
### 1) 核心实体与聚合边界
- 用户聚合:`profiles` (含 settings JSONB) , `user_agents`
- 社交聚合:`friendships` , `groups` , `group_members`
- 协作事项聚合:`schedule_items` , `schedule_item_ subscriptions` , `schedule_item_permissions`
- 消息聚合:`inbox_events` , `inbox_receipt s`
- 待办聚合:`todos` , `todo_sources`
- 自动化聚合:`automation_jobs` , `automation_schedules` , `automation_runs`
- 协作事项聚合:`schedule_items` , `schedule_subscriptions`
- 消息聚合:`inbox_message s`
- 待办聚合:`todos`
- 自动化聚合:`automation_jobs` , `automation_runs`
### 2) 一致性分级
- 强一致(同事务):好友关系状态迁移、群组成员角色变更、事项权限写入、定时任务抢占执行
@@ -67,13 +67,10 @@
- `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_item_ subscriptions` , `auth.users (1) - (N) schedule_item_ subscriptions`
- `schedule_items (1) - (N) schedule_item_permissions` , `auth.users (1) - (N) schedule_item_permission s`
- `inbox_events (1) - (N) inbox_receipts` , `auth.users (1) - (N) inbox_receipts`
- `schedule_items (1) - (N) schedule_subscriptions` , `auth.users (1) - (N) schedule_subscriptions`
- `auth.users (1) - (N) inbox_message s`
- `auth.users (1) - (N) todos`
- `todos (1) - (N) todo_sources` (一条待办可有多个来源记录,默认 1 条)
- `auth.users (1) - (N) automation_jobs`
- `automation_jobs (1) - (N) automation_schedules`
- `automation_jobs (1) - (N) automation_runs`
### 关键约束
@@ -81,15 +78,12 @@
- `user_agents.user_id` 唯一
- `friendships(user_low_id, user_high_id)` 唯一
- `group_members(group_id, user_id)` 唯一
- `schedule_item_ subscriptions(item_id, subscriber_id)` 唯一
- `schedule_item_permissions(item_id, subject_type, subject_id, permission)` 唯一
- `todo_sources(source_type, source_id, owner_id)` 唯一(防止重复抽取)
- `automation_runs(job_id, idempotency_key)` 唯一
- `schedule_subscriptions(item_id, subscriber_id)` 唯一
- 外键:统一显式 `ON DELETE` 策略(见下)
- 可空性:权限关键字段、状态字段、外部幂等键 默认 `NOT NULL`
- 可空性:权限关键字段、状态字段默认 `NOT NULL`
- 删除策略:
- 用户删除:大部分 `CASCADE` (用户私有数据);跨用户协作数据优先软删
- 事项删除:对子表 `CASCADE` ;待办来源 保留历史可 改 `SET NULL` + 软删
- 事项删除:对子表 `CASCADE` ;待办保留历史, 改 `status = 'archived'`
## C. 数据库表设计(PostgreSQL)
@@ -164,27 +158,26 @@
- PK: `id UUID`
- 关键字段:
- `group_id` , `user_id`
- `role` ( JSONB 数组,权柄组合,如 `["view"] ` / `["view", "invite"] ` / `["view", "invite", "edit"] ` )
- `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, status)`
- `INDEX(group_id, role, status)`
- `INDEX(user_id, status)`
- GIN 索引支持权柄查询:`INDEX group_members_role USING GIN(role)`
- 审计: `created_by` , `updated_by`
**权柄 说明 ** :
| 权柄 | 含义 |
|------|------|
| `view` | 查看群组信息、成员列表、聊天记录 |
| `invite` | 邀请新成员入群 |
| `edit` | 修改群组信息、管理成员(禁言/移除) |
**role 说明 ** :
| role | 含义 | 创建事项时默认给群组的权限 |
|------|------|---------------------------|
| `creator` | 群主/创建者 | `["view", "invite", "edit"]` |
| `admin` | 管理员 | `["view", "invite"]` |
| `member` | 普通成员 | `["view"]` |
- 群主(创建者)默认拥有全部权柄: `["view", "invite", "edit"]`
- 权柄可动态变更:服务层使用 `jsonb ||` 或 `jsonb -` 原子操作增减权柄
- 角色可升降:服务层变更 role 字段即可
- 角色决定了该用户在群里创建的日程事项默认授予群组的权限(见下方映射)
### 3) 用户设置(已合并至 profiles 表)
@@ -222,184 +215,157 @@
#### `schedule_items`
- PK: `id UUID`
- 关键字段:
- `owner_id` , `title` , `description`
- `start_at` , `end_at` , `timezon e`
- `recurrence_rule` (可空)
- `source_type` ( `manual|imported|agent_generated `)
- 时间字段: `created_at` , `updated_at` , `delete d_at`
- 状态字段: `status` ( `running|completed|archived `)
- `owner_id`
- `titl e`
- `description`
- `start_at `
- `en d_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)`
- `INDEX(updated_at DESC) `
- 审计: `created_by` , `updated_by`
- 审计: `created_by `
#### `schedule_item_ subscriptions`
#### `schedule_subscriptions`
- PK: `id UUID`
- 关键字段: `item_id` , `subscriber_id` , `notify_level` , `subscription_source`
- 时间字段: `created_at` , `updated_at` , `unsubscribed_at `
- 状态字段: `status` ( `active|paused|un subscribed`)
- 关键字段:
- `item_id `
- ` subscriber_i d`
- `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` , `updated_by`
- 审计: `created_by`
#### `schedule_item_permissions`
- PK: `id UUID`
- 关键字段: `item_id` , `subject_type` ( `user|group|friend_circle` ) , `subject_id` , `permission`
- 时间字段: `created_at` , `updated_at` , `expires_at`
- 状态字段: `status` ( `active|revoked|expired` )
- 约束:
- `UNIQUE(item_id, subject_type, subject_id, permission)`
- `permission` 建议枚举 : `view|comment|edit|manage `
- 索引:
- `INDEX(item_id, permission, status)`
- `INDEX(subject_type, subject_id, status)`
- 审计: `granted_by` , `updated_by`
**权柄说明 ** :
| 权柄 | 含义 |
|------|------|
| `view` | 查看事项详情 |
| `invite` | 邀请其他人订阅此事项 |
| `edit` | 修改事项内容、管理订阅 |
- 事项 owner 默认拥有全部权柄: `[" view", "invite", "edit"] `
- 权限变更使用 JSONB 原子操作: `UPDATE ... SET permission = permission || '["edit"]'::jsonb`
### 5) 待处理消息(Inbox)
#### `inbox_event s`
#### `inbox_message s`
- PK: `id UUID`
- 关键字段: `event_type` , `actor_id` , `object_type` , `object_id` , `payload_jsonb` , `dedupe_key`
- 时间字段: `created_at` , `updated_at`
- 状态字段: `status` ( `open|resolved|canceled` )
- 约束: `UNIQUE(dedupe_key) `
- 索引: `INDEX(event_type, created_at DESC)` , `GIN(payload_jsonb)`
- 审计: `c reated_by` , `updated_by `
#### `inbox_receipts`
- PK: `id UUID `
- 关键字段: `event_id` , `recipient_id` , `inbox_state` , `action_required` , `acted_at`
- 时间字段: `created_at` , `updated_at` , `read_at`
- 状态字段: `inbox_state` ( `pending|read|accepted|rejected|dismissed|expired` )
- 约束: `UNIQUE(event_id, recipient_id)`
- 关键字段:
- `recipient_id` (接收者)
- `sender_id` (发送者 )
- `message_type` ( `friend_request` / `group_invitation` / `schedule_item_shared `)
- `content` ( TEXT 或 JSONB,消息内容)
- `rel ated_type` (关联业务类型: `friendship` / `group` / `schedule_item `)
- `related_id` (关联业务 ID)
- 时间字段: `created_at` , `read_at` , `acted_at`
- 状态字段: `status` ( `pending|read|accepted|rejected|dismissed `)
- 索引:
- `INDEX(recipient_id, inbox_ state , created_at DESC)`
- 部分索引 `INDEX(recipient_id, created_at DESC) WHERE inbox_ state ='pending'`
- 审计: `created_by` , `updated_by`
- `INDEX(recipient_id, status , created_at DESC)`
- 部分索引 `INDEX(recipient_id, created_at DESC) WHERE status ='pending'`
- 审计: `created_by`
### 6) 待办与来源映射
**说明 ** :一张表搞定,接收者视角,只关心谁发的、什么类型、关联什么业务对象。
### 6) 待办
#### `todos`
- PK: `id UUID`
- 关键字段: `owner_id` , `title` , `description` , `due_at` , `priority` , `origin_type` , `source_hash`
- 时间字段: `created_at` , `updated_at` , `completed_at` , `deleted_at `
- 状态字段: `status` ( `pending|in_progress|done|canceled|archived `)
- 关键字段:
- `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, upd ated_at DESC)`
- 部分索引 `INDEX(owner_id, due_at) WHERE status IN ( 'pending','in_progress') `
- 审计: `created_by` , `updated_by`
#### `todo_sources`
- PK: `id UUID`
- 关键字段: `todo_id` , `owner_id` , `source_type` ( `schedule_item|manual|inbox_event|automation` ) , `source_id` , `extracted_at` , `sync_mode`
- 时间字段: `created_at` , `updated_at`
- 状态字段: `status` ( `linked|unlinked|stale` )
- 约束: `UNIQUE(owner_id, source_type, source_id)` (去重关键)
- 索引:
- `INDEX(todo_id)`
- `INDEX(owner_id, source_type, status)`
- 审计: `created_by` , `updated_by`
- `INDEX(owner_id, cre ated_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`
- 时间字段: `created_at` , `updated_at` , `deleted_at `
- 状态字段: `status` ( `active|paused|disabled `)
- 索引: `INDEX(owner_id, status)` , `INDEX(target_type, target_id) `
- 审计: `created_by` , `updated_by `
#### `automation_schedules`
- PK: `id UUID `
- 关键字段:
- `job_id UNIQUE`
- `schedule_type` ( `cron|rrule|interval` )
- `cron_expr` / `rrule_text` / `interval_seconds` (三选一)
- `timezone` , `start_at` , `end_at` , `next_run_at`
- 关键字段:
- `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|paused|expired|invali d` )
- 约束:
- `CHECK` 保证三种表达互斥且至少一项有效
- 索引:
- 部分索引 `INDEX(next_run_at) WHERE status='active'`
- `INDEX(job_id, status)`
- 审计: `created_by` , `updated_by`
- 状态字段: `status` ( `active | disable d` )
- 索引: `INDEX(owner_id, status)`
- 审计: `created_by`
#### `automation_runs`
- PK: `id UUID`
- 关键字段: `job_id` , `scheduled_for` , `started_at` , `finished_at` , `attempt` , `max_retries` , `idempotency_key` , `worker_id` , `result_jsonb` , `error_code`
- 时间字段: `created_at` , `updated_at `
- 状态字段: `status` ( `queued|running|succeeded|failed|canceled|dead_letter` )
- 约束:
- `UNIQUE(job_id, idempotency_key) `
- `CHECK(attempt <= max_retries + 1) `
- 索引:
- `INDEX(job_id, scheduled_for DESC) `
- `INDEX(status, scheduled_for)`
- 部分索引 `INDEX(status, updated_at) WHERE status IN ('queued','running') `
- 审计 : `created_by` , `updated_by `
- 关键字段:
- `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) 事项编辑 权限落表
### 1) 事项权限落表
- 权限直接存储在 `schedule_subscriptions.permission` JSONB 数组中
- 权限决策顺序:
1. `schedule_items.owner_id` (天然 `manage `)
2. `schedule_item_permissions` 针对 `subject_type=user` 的显式授权
3. 用户所在群组在 `subject_type=group` 的授权
4. 默认无编辑权限
- 建议在服务层计算“有效权限”,可落缓存字段 `effective_permission` (可选)
1. `schedule_items.owner_id` → 全部权柄 `["view", "invite", "edit"] `
2. `schedule_subscriptions` 中该用户的 `permission` 数组
3. 默认只有 `["view"]`
### 2) 群组角色 与事项关系
- `group_members.role` : JSONB 数组,权柄组合 `["view"]` / `["view", "invite"]` / `["view", "invite", "edit"]`
- 群主(创建者)默认拥有全部权柄
- 权柄与事项权限映射:
- 群成员 `view ` → 事项 `view`
- 群成员 `invite` → 隐含 ` view`
- 群成员 `edit` → 事项 `edit|manage`
- 若事项绑定群组上下文,可增 `schedule_items.context_group_id NULL`
### 2) 群组与事项权限
- 群成员在事项中的权限通过 `schedule_subscriptions.subject_type = 'group'` 关联
- 群角色决定默认权限:
- `creator` → `["view", "invite", "edit"]`
- `admin ` → `[" view", "invite"] `
- `member` → `[" view"] `
## E. 消息与待办联动
### 1) inbox 关联来源
- `inbox_events.event _type` 建议 枚举:
- `friend_request`
- `group_invitation`
- `group_role_changed`
- `schedule_item_changed`
- `schedule_item_permission_granted`
- `automation_run_failed`
- 通过 `object_type/object_id` 直接关联业务对象
### 1) inbox 关联业务对象
- `inbox_messages.message _type` 枚举:
- `friend_request` (好友请求)
- `group_invitation` (群组邀请)
- `schedule_item_shared` (日程事项分享)
- 通过 `related_type` / `related_id` 关联业务对象
### 2) 待办提取与防循环
- 从事项提取待办:
- 先计算 `source_hash = sha256(owner_id + source_type + source_id + title + due_at_bucket) `
- 查 `todo_sources(owner_id, source_type, source_id)` 唯一约束防重复
- 防循环同步:
- `todo_sources.sync_mode` : `one_way|two_way`
- 当来源为 `schedule_item` 且 `two_way` 时,写回需携带 `sync_trace_id`
- 同一 `sync_trace_id` 在同一对象链路只消费一次(应用层幂等)
### 2) 待办来源 提取
- 从事项提取待办时,将日程事件 ID 存入 `todos.source_ids` JSONB 数组
- 手动创建的待办 `source_ids = [] `
- 支持多来源:同一待办可关联多个日程事项 `source_ids = [<id1>, <id2>]`
- 待办完成时无需反向更新来源事项状态(简化设计)
## F. 定时任务模型
### 1) 循环表达建议
- 推荐优先级:
- 用户型日历任务:`rrule`
- 运维/工程任务:`cron`
- 简单轮询:`interval_seconds`
- 数据层统一在 `automation_schedules` ,并通过 `schedule_type` 区分
### 1) 调度规则
- `schedule_type` 枚举: `daily` (每日) | `weekly` (每周)
- `schedule_time` 格式:`HH:MM` (如 `09:00` 表示每天/每周几点执行)
- 调度器扫描 `status='active'` 的任务,按 `schedule_type + schedule_time` 计算下次执行时间
### 2) 触发记录与重试
- 任务调度器按 `next_run_at` 扫描活跃计划,插入 `automation_runs(status='queued')`
- 执行器抢占: `SELECT ... FOR UPDATE SKIP LOCKED `
- 重试策略 : `attempt` 递增,失败后按退避策略更新下一次 `scheduled_for`
### 3) 幂等与并发冲突
- 幂等键:`idempotency_key = sha256(job_id + scheduled_for + logical_partition)`
- 冲突处理:唯一约束冲突时视为重复投递,直接忽略或合并结果
- 并发安全:`automation_jobs.version` (乐观锁)可选
### 2) 执行记录
- 每次执行生成 `automation_runs` 记录
- 状态流转: `queued` → `running` → `succeeded` | `failed `
- 失败 重试:`attempt` 字段记录当前重试次数(需业务确认最大重试次数)
## G. 演进与迁移计划(从旧表到新模型)
@@ -410,7 +376,7 @@
4. 提供只写新表的影子接口(内部开关)
### Phase 2: 协作与联动接入(12-16 小时)
1. 新建 `schedule_items* ` , `inbox_* ` , `todos* ` , `automation_* `
1. 新建 `schedule_items` , `schedule_subscriptions ` , `inbox_messages ` , `todos` , `automation_jobs` , `automation_runs `
2. 编写回填脚本(从旧事项/旧消息结构回填,若不存在则跳过)
3. 开启双写:旧接口写旧表同时写新表,记录双写差异日志
@@ -462,15 +428,15 @@
2. 引入 `user_agents` ,通过 `UNIQUE(user_id)` 满足每用户专属 agent。
3. 用户设置内嵌至 `profiles.settings JSONB` ,支持渐进式扩展。
4. 好友关系采用标准化双向一行模型,避免重复边。
4. 群组采用 `groups + group_members` ,角色内建 owne r/admin/member。
5. 事项、订阅、权限三表解耦,支持多人订阅与精细编辑授权。
6. inbox 采用 `events + receipts` ,统一承载待处理动作 。
7. 待办采用 `todos + todo_sources` ,实现来源追踪与去重 。
8. 自动化采用 `jobs + schedules + runs` ,支持 cron/rrule/interval 。
9. 所有关键表补齐状态机字段与审计字段,支持可观测与追责。
10. 索引以“ 用户维度 + 状态 + 时间” 为主,兼顾移动端列表查询。
11. 迁移走“ 四阶段” :并行建模 -> 双写回填 -> 读切换 -> 清理。
12. 通过幂等键、部分索引和事务边界保障高并发稳定性。
5. 群组采用 `groups + group_members` ,角色内建 creato r/admin/member。
6. 事项、订阅、权限三表解耦,支持多人订阅与精细编辑授权。
7. inbox 采用单表 `inbox_messages` ,接收者视角简洁设计 。
8. 待办采用单表 `todos` ,通过 `source_ids` JSONB 数组存储来源日程事件 。
9. 自动化采用 `jobs + runs` 双表,只支持 daily/weekly 两种循环 。
10. 所有关键表补齐状态机字段与审计字段,支持可观测与追责。
11. 索引以" 用户维度 + 状态 + 时间" 为主,兼顾移动端列表查询。
12. 迁移走" 四阶段" :并行建模 -> 双写回填 -> 读切换 -> 清理。
13. 通过幂等键、部分索引和事务边界保障高并发稳定性。
### I-2. 后续 API 设计所需数据契约清单
@@ -484,19 +450,15 @@
- `GroupDTO` : `id,name,owner_id,visibility,status`
- `GroupMemberDTO` : `group_id,user_id,role,status,joined_at`
- 事项
- `ScheduleItemDTO` : `id,owner_id,title,start_at,end_at,status, timezone,recurrence_rule`
- `ScheduleSubscriptionDTO` : `item_id,subscriber_id,status,notify_level `
- `SchedulePermissionDTO` : `item_id,subject_type,subject_id,permission,status`
- `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
- `InboxEvent DTO` : `id,event_type,object_type,object_id,payload,status,crea ted_at`
- `InboxReceiptDTO` : `event_id,recipient_id,inbox_state,action_required,read_at,acted_at`
- `InboxMessage DTO` : `id,recipient_id,sender_id,message_type,content,related_type,related_id,status,created_at,read_at,ac ted_at`
- Todo
- `TodoDTO` : `id,owner_id,title,due_at,status,priority,origin_type `
- `TodoSourceDTO` : `todo_id,source_type,source_id,sync_mode,status`
- `TodoDTO` : `id,owner_id,title,description,due_at,priority,status,source_ids (JSONB数组),created_at,completed_at `
- 自动化
- `AutomationJobDTO` : `id,owner_id,job_type,target_type,target_id,status `
- `AutomationSchedule DTO` : `job_id,schedule_type,cron_expr,rrule_tex t,interval_seconds,next_run_at,status `
- `AutomationRunDTO` : `id,job_id,scheduled_for,status,attempt,idempotency_key,error_code`
- `AutomationJobDTO` : `id,owner_id,name, job_type,target_type,target_id,params,schedule_type,schedule_time,status,created_at `
- `AutomationRun DTO` : `id, job_id,scheduled_at,started_a t,f inished_at,status,attempt,error_message,result `
### I-3. 最小可行迁移 DDL 清单(按优先级)
@@ -512,23 +474,17 @@ P0(身份与社交基础)
P1(协作事项)
7. `CREATE TABLE schedule_items (...)`
8. `CREATE TABLE schedule_item_ subscriptions (...)`
9. `CREATE TABLE schedule_item_permissions (...)`
10. `CREATE INDEX` ( owner/status/time + permission 查询)
8. `CREATE TABLE schedule_subscriptions (...)`
9. `CREATE INDEX` ( owner/status/time + subscription 查询)
P2(消息与待办)
11. `CREATE TABLE inbox_event s (...)`
12. `CREATE TABLE inbox_receipt s (...)`
13. `CREATE TABLE todos (...)`
14. `CREATE TABLE todo_sources (...)`
15. `CREATE UNIQUE INDEX uq_todo_sources_owner_source (...)`
11. `CREATE TABLE inbox_message s (...)`
12. `CREATE TABLE todo s (...)`
P3(自动化)
16. `CREATE TABLE automation_jobs (...)`
17. `CREATE TABLE automation_schedule s (...)`
18. `CREATE TABLE automation_runs (...)`
19. `CREATE UNIQUE INDEX uq_automation_runs_job_idempotency (...)`
20. `CREATE INDEX idx_automation_schedules_next_run_active (...)`
13. `CREATE TABLE automation_jobs (...)`
14. `CREATE TABLE automation_run s (...)`
15. `CREATE INDEX idx_ automation_runs_job_scheduled (...)`
P4(安全与治理)
21. 对新增 `public` 表执行 `ALTER TABLE ... ENABLE ROW LEVEL SECURITY`
@@ -571,7 +527,6 @@ P4(安全与治理)
1. ~~`profiles.username` 是否允许重名~~ (已确认:允许重名,仅建普通索引)。
2. ~~group_members.role 权柄组合~~ (已确认:JSONB 数组 `["view", "invite", "edit"]` )。
3. 是否近期需要“ 组织/团队” 多租户(决定 `tenant_id` 是否立即强制)。
3. 是否近期需要" 组织/团队" 多租户(决定 `tenant_id` 是否立即强制)。
4. 事项是否必须绑定群组上下文(`context_group_id` 是否必需)。
5. 待办与事项同步是否默认双向(推荐默认单向,降低循环风险 )。
6. 自动化任务失败重试上限与退避策略(固定/指数)。
5. 自动化任务失败重试上限与退避策略(固定/指数 )。