1. 模块职责说明
成员3负责两个公共基础模块:全局数据模块、系统日志模块。核心边界是“数据库事实由成员3统一读写,AI 推理和前端确认卡片不放进成员3”。
| 模块 |
负责什么 |
不负责什么 |
主要调用方 |
关联数据库表 |
| 全局数据模块 |
查询数据库事实;查询候选事项;校验用户归属、存在性、版本和写入前提;创建待确认写入请求;保存重排候选与画像原始观察等非业务事实工作流记录;用户确认后在事务中写入、修改或软删除业务事实 |
不做意图识别、参数补全、反问、LLM 调用、Prompt 管理、前端确认卡片展示;不允许子 Agent 直接调用本模块 |
母 AI 编排模块、基础业务模块、弹窗确认机制 |
users、long_goals、task_items、feedback_records、conversation_messages、write_requests、operation_confirmations、replan_proposals、replan_proposal_changes、replan_applications、user_profiles、task_profile_observations、task_profile_snapshots |
| 系统日志模块 |
记录 Agent 运行摘要,包括组件、函数、运行状态、错误码、开始与结束时间以及可选链路 ID |
不保存完整 Prompt、模型原文、完整 LLM 调用链;不替代 LangSmith 等可观测平台 |
母 AI 编排模块、全局数据模块、前端交互与展示模块 |
agent_run_records |
统一约束:
- AI 驱动写入只能由母 AI 编排模块发起,最终调用全局数据模块落盘。
- 业务界面和母 AI 编排模块可调用同一套全局数据模块;写操作也必须走统一确认与校验。
- 子 Agent 只能生成候选结果或结构化建议,不能直接读写数据库,也不能直接调用全局数据模块。
- 不能把前端传入的
is_confirmed = true 当作写入凭证;必须使用 write_requests + operation_confirmations + payload_hash。
- 删除操作使用软删除,必须维护
is_deleted 和 deleted_at。
- 成功业务写入与写入请求状态
applied 必须在同一个事务中完成;任一步失败都先回滚,再使用独立短事务将请求标记为 failed。系统日志模块只记录 Agent 运行摘要,不参与业务写入事务。
- 校验类能力(归属、存在性、目标唯一性、写入前提)作为进程内对外函数提供,供母 AI 编排模块与基础业务模块调用;不单独暴露 HTTP,可嵌入查询 / 写入路径复用。
- HTTP 接口中的当前用户必须从登录态解析,禁止信任前端随意传入的
user_id 做越权查询。
- 对话原文统一由全局数据模块写入
conversation_messages;媒体二进制不进库,只存 OSS 返回的 source_url。
2. 事务校验与软删除
2.1 事务校验
事务校验不是提前执行一次的普通查询,而是“事务校验并应用写入”内部不可跳过的步骤。公共数据模块必须按以下顺序执行:
BEGIN
→ 调用 assert_confirmed_write(user_id, write_request_id, payload_hash)
→ 校验目标仍存在、属于当前用户且 version 与 base_version / expected_item_version 一致
→ 校验 action 和 payload 字段在业务白名单内
→ 执行业务写入(含软删除、反馈追加、画像快照、重排应用等)
→ 将 `write_requests.status` 更新为 `applied`
COMMIT
成功路径中,业务写入和 write_requests.status=applied 必须一起提交。任一步失败都先 ROLLBACK,不得留下部分业务数据。回滚完成后,另开一个短事务将请求标记为 failed。幂等键用于阻止同一写入请求被重复执行;前端传入的单独布尔值不能替代确认记录。
assert_confirmed_write 只解决确认状态、用户归属、精确载荷和过期时间;它不替代身份认证、业务白名单和目标版本校验。
2.2 时间范围查询规则
以下规则是成员 3 对 Wiki“按时间范围查询”要求的字段级补充,所有事项时间范围查询必须复用同一谓词。查询窗口统一使用左闭右开区间 [from_time, to_time):
schedule 按日程区间与查询窗口重叠匹配:start_at < to_time AND end_at > from_time。
todo / subtask 按截止时间落入窗口匹配:due_at >= from_time AND due_at < to_time。
due_at IS NULL 的待办或子任务不属于任何确定时间窗口,因此在传入时间范围时排除;不带时间范围的全量查询仍可返回。
- “今日事项”先按
users.timezone 将本地日期换算成 UTC 起止时刻,再应用同一谓词,不能直接按数据库会话时区截取日期。
- 查询事项列表、今日事项、候选反馈目标和复盘关联数据必须使用相同规则,避免四个入口返回不一致的事项集合。
2.3 软删除
事项和长任务禁止物理删除。确认删除后只更新 is_deleted=true、deleted_at=now(),并将 version 加一。删除前必须校验用户归属、未删除状态和 base_version;重复删除、越权或版本冲突均应拒绝并回滚。
普通查询默认附带 is_deleted=false,但已删除记录仍保留主键及其关联反馈,保证既有业务事实可以追溯。
长任务与子任务策略:
- 创建
delete_goal 写入请求时,由服务端读取当前全部未软删子任务,将每个 item_id + expected_item_version 写入 payload 的 cascade_subtasks;该完整 payload 参与 payload_hash,确认卡片展示级联数量和明细。
- 应用确认请求时先锁定长任务,再锁定并读取当前未软删子任务;只有当前 ID/版本集合与
cascade_subtasks 完全一致,才在同一事务内软删除长任务和清单内子任务。确认后新增、删除、改版或改变归属的任一子任务都会触发版本冲突并整单回滚。
- 软删除长任务时,禁止物理删除子任务;子任务只更新
is_deleted=true、deleted_at=now()、version+1。
- 子任务行与其
feedback_records 关联仍保留,仅对普通查询不可见(默认 is_deleted=false 即可过滤),无需再靠 JOIN 父目标判断可见性。
- 查询长任务及子任务:若目标已软删或越权,直接返回错误,不返回其子任务列表。
- 级联软删在应用层同事务完成,不依赖库层
ON DELETE 物理级联;不在 MVP 引入单独的数据库软删触发器(避免与确认写入路径分叉)。
2.4 工作流记录与业务事实
| 类型 |
是否需要用户确认 |
示例 |
| 业务事实 |
是 |
task_items、long_goals、feedback_records、user_profiles、task_profile_snapshots 的创建/更新/软删除 |
| 工作流候选 |
否(但真正改事项时仍需确认) |
write_requests、replan_proposals、replan_proposal_changes |
| 系统运行记录 |
否 |
conversation_messages、task_profile_observations、agent_run_records |
重排方案可在确认前保存;真正修改事项必须通过 write_requests.action = apply(兼容历史枚举 apply_replan)并完成确认。
2.5 复盘数据查询边界
复盘不查询历史完整报告,而是在用户发起复盘时实时读取已经落库的业务事实:事项来自 task_items,执行反馈来自 feedback_records,关联长任务来自 long_goals。复盘 Agent 生成的完整报告只返回前端展示,不写入数据库;从报告中提炼的长任务简洁复盘摘要可以作为成员 3 的补充业务字段 long_goals.review_summary 保存。
查询步骤:
- 按
user_id、from_time、to_time 和可选 goal_id 查询时间范围内未软删除的事项;日程按区间重叠,待办/子任务按 due_at 落入 [from_time, to_time),无截止时间的事项不进入本次复盘数据集。
- 查询该用户在时间范围内产生、且关联上述事项的
feedback_records;同一事项允许返回多条不可变反馈。
- 根据事项的
long_goal_id 查询未软删除的关联长任务;传入 goal_id 时只返回该目标范围内的数据。
- 将三组事实组装成
ReviewDataResponse(items, feedbacks, goals),交给母 AI 编排模块,再传给复盘 Agent。
- 复盘 Agent 输出完整报告和不超过 500 字的
review_summary 候选;完整报告只展示,摘要写入候选必须走 action=update_goal 的确认链,应用后覆盖该长任务的最新摘要,不保存摘要历史版本。
- 没有匹配事实时返回三个空列表,不创建复盘记录,也不把“无数据”视为数据库错误。
MVP 只返回复盘原始数据集,不在全局数据模块计算完成率;允许额外保存长任务最新简洁复盘摘要,但不保存完整报告或摘要历史。若后续需要结构化统计,必须先明确多次反馈、部分完成和无反馈事项的计算规则,再扩展独立统计 DTO。
2.6 update_goal payload 契约(成员 3 补充)
Wiki 和数据库只固定 action + payload 外壳;以下字段级结构是成员 3 为避免普通字段、宏观规划与简洁复盘摘要修改歧义而补充的契约。action=update_goal 时,修改内容全部放入 payload,允许以下四种结构:
- 普通字段修改:包含
long_goal_id、changes。
- 仅更新宏观规划:
changes 只包含 plan_overview。
- 仅保存简洁复盘:
changes 只包含 review_summary。
- 组合修改:
changes 同时包含普通字段、plan_overview 或 review_summary 中的多项,用于用户明确要求一次修改多项内容。
changes 只允许 title、description、plan_overview、review_summary、start_at、deadline_at、status,且至少包含一个字段;review_summary 为空白或超过 500 字时拒绝;未知字段或空修改也应拒绝。
四种结构都使用同一个 write_action=update_goal。目标的 base_version 使用 write_requests.base_version 顶层字段承载,不在 payload 内重复。完整 payload 由数据库生成 payload_hash,确认卡片必须展示全部变更;组合修改在同一个事务中一次完成,任一字段失败则整体回滚,成功后 version 只递增一次。
3. 前后端 API 表
说明:
- 本模块对外首先是进程内函数能力;下列 HTTP API 是前端只读页与确认链路需要的后端入口,承接模块为全局数据模块。
- 基础业务模块可以做页面聚合,但最终仍应调用本模块函数,不允许另开一套直连数据库的写入通道。
- 请求中的
user_id 仅作文档字段说明;实现时必须从登录态注入,忽略或拒绝客户端伪造值。
| 页面 / 场景 |
API 名称 |
HTTP 方法 |
路径建议 |
承接模块 |
请求参数 |
响应数据 |
数据来源 |
是否写入 |
是否需要确认 |
数据库缺口 |
数据流转说明 |
| 今日事项页 / 时间顺序 Tab |
查询今日事项 |
GET |
/api/items/today |
全局数据模块 |
date(登录态推导 user_id) |
items: list[TaskItemDTO] |
task_items、users.timezone |
否 |
否 |
需补 due_at 部分索引 |
前端传入日期;按用户时区换算当天 [from_time, to_time);日程按区间重叠,待办/子任务按 due_at 落入窗口;默认排除软删和无截止时间事项 |
| 事项详情页 |
查询事项详情 |
GET |
/api/items/{item_id} |
全局数据模块 |
item_id |
item: TaskItemDTO |
task_items |
否 |
否 |
无 |
用登录用户 + item_id 限定归属;不存在或越权分别返回 404 / 403 |
| 长任务目标管理 Tab |
查询长任务列表 |
GET |
/api/goals |
全局数据模块 |
status?(登录态推导 user_id) |
goals: list[LongGoalDTO] |
long_goals |
否 |
否 |
无 |
默认查询当前用户未软删除长任务;可按状态过滤,按 updated_at DESC 返回 |
| 长任务详情页 |
查询长任务及子任务 |
GET |
/api/goals/{goal_id} |
全局数据模块 |
goal_id |
goal: LongGoalDTO、items: list[TaskItemDTO] |
long_goals、task_items |
否 |
否 |
无 |
返回长任务宏观规划文本和 item_type=subtask 子任务列表;plan_overview 仅展示 |
| 业务页面 / 确认卡片 |
创建写入请求 |
POST |
/api/write-requests |
全局数据模块 |
WriteRequestDraft(无前端伪造确认字段) |
WriteRequestDTO |
write_requests |
是,写候选 |
否,后续确认 |
无 |
基础业务模块或母 AI 编排模块提交已完成字段校验的结构化候选;服务端保存完整 action + payload,此时不改业务事实 |
| 确认卡片 |
提交确认事件 |
POST |
/api/confirmations |
全局数据模块 |
write_request_id、payload_hash、decision、client_event_id? |
ConfirmWriteResponse |
write_requests、operation_confirmations |
是,写确认 |
是 |
无 |
弹窗确认机制把用户决定落成确认记录;确认成功不直接写业务表 |
| 确认后落盘编排 |
应用已确认写入 |
POST |
/api/write-requests/{write_request_id}/apply |
全局数据模块 |
write_request_id、payload_hash |
ApplyConfirmedWriteResponse |
目标业务表、write_requests |
是 |
是 |
见查缺补漏 |
母 AI 编排模块或基础业务模块在确认后调用;成功路径同事务完成校验、业务写入和请求状态更新;失败时回滚业务事务,再标记请求失败 |
AI 对话主链路本身不额外增加成员3专属聊天 API;对话入口由母 AI 编排模块承接,本模块只提供其调用的查询与落盘函数。
长任务简洁复盘摘要不新增独立 HTTP 接口:母 AI 将 review_summary 放入 action=update_goal 的 changes,经确认后写回当前长任务;查询长任务列表、详情和复盘关联数据时随 LongGoalDTO 返回。完整复盘报告仍只展示,不写入数据库。
4. 模块对外函数表
| 所属模块 |
函数中文名称 |
函数类型 |
调用方 |
输入参数 |
返回值 |
依赖数据 |
依赖模块 |
是否写入 |
是否需要确认 |
失败处理 |
数据库缺口 |
数据流转说明 |
| 全局数据模块 |
查询事项列表 |
查询 |
母 AI 编排模块、基础业务模块 |
user_id、from_time?、to_time?、item_types?、status?、include_deleted=false |
items: list[TaskItemDTO] |
task_items |
无 |
否 |
否 |
用户不存在返回空列表或 404;时间范围非法返回参数错误 |
due_at 部分索引 |
有时间范围时使用 [from_time,to_time):日程按 start_at < to_time AND end_at > from_time,待办/子任务按 due_at >= from_time AND due_at < to_time,无截止时间者排除;默认 is_deleted=false |
| 全局数据模块 |
查询事项详情 |
查询 |
母 AI 编排模块、基础业务模块 |
user_id、item_id |
item: TaskItemDTO |
task_items |
无 |
否 |
否 |
不存在返回 404;不属于当前用户返回 403;已软删视为不存在 |
无 |
用 user_id + item_id 限定归属;只返回未软删除事项;不做指代推理 |
| 全局数据模块 |
查询长任务列表 |
查询 |
母 AI 编排模块、基础业务模块 |
user_id、status?、include_deleted=false |
goals: list[LongGoalDTO] |
long_goals |
无 |
否 |
否 |
非法状态返回参数错误;无数据返回空列表 |
无 |
支撑长任务目标管理 Tab 首屏;默认仅返回当前用户未软删除目标,按 updated_at DESC 排序;include_deleted=true 仅供恢复管理内部调用 |
| 全局数据模块 |
查询长任务及子任务 |
查询 |
母 AI 编排模块、基础业务模块 |
user_id、goal_id |
goal: LongGoalDTO、items: list[TaskItemDTO] |
long_goals、task_items |
无 |
否 |
否 |
长任务不存在、已删除或越权时返回错误 |
无 |
返回长任务基本信息、plan_overview 和子任务事实;母 AI 再把结果传给子 Agent |
| 全局数据模块 |
查询用户画像 |
查询 |
母 AI 编排模块、全局用户画像管理模块的上游编排 |
user_id |
profile: UserProfileDTO or None |
user_profiles |
无 |
否 |
否 |
未填写画像时返回空值,不阻塞主流程 |
无 |
只返回用户主动画像事实,不做 AI 归纳 |
| 全局数据模块 |
查询任务级画像 |
查询 |
母 AI 编排模块、任务级画像管理模块的上游编排 |
user_id、long_goal_id |
observations: list[TaskProfileObservationDTO]、current_snapshot: TaskProfileSnapshotDTO or None |
task_profile_observations、task_profile_snapshots |
无 |
否 |
否 |
长任务不存在返回错误;没有画像时返回空列表 |
无 |
原始观察与 AI 归纳快照分开返回 |
| 全局数据模块 |
查询候选反馈目标 |
查询 |
母 AI 编排模块 |
user_id、from_time、to_time、item_types? |
candidates: list[CandidateItemDTO] |
task_items |
无 |
否 |
否 |
无候选时由母 AI 触发反问;多候选时返回列表 |
due_at 部分索引 |
复用事项时间谓词:日程按区间重叠,待办/子任务按 due_at 落入 [from_time,to_time);默认排除软删和无截止时间事项,再交给反馈 Agent |
| 全局数据模块 |
查询复盘关联数据 |
查询 |
母 AI 编排模块 |
user_id、from_time、to_time、review_type?、goal_id? |
ReviewDataResponse,含 items、feedbacks、goals |
task_items、feedback_records、long_goals |
无 |
否 |
否 |
时间范围非法时返回参数错误;没有匹配事实时返回三个空列表 |
due_at 部分索引 |
实时查询已保存事实;事项复用同一时间谓词,再查询关联反馈和目标;默认排除软删及无截止时间的待办/子任务;不查询或保存完整复盘报告,可返回已保存的 review_summary;不计算完成率 |
| 全局数据模块 |
查询最近对话消息 |
查询 |
母 AI 编排模块 |
user_id、limit=20 |
messages: list[ConversationMessageDTO] |
conversation_messages |
无 |
否 |
否 |
超出上限时截断到 MVP 固定窗口 |
无 |
按 message_index 倒序取最近 N 条,再正序返回;支撑“最近 20 条对话 + 当前请求数据库事实” |
| 全局数据模块 |
保存对话消息 |
记录 |
母 AI 编排模块、基础业务模块 |
SaveConversationMessageRequest |
ConversationMessageDTO |
conversation_messages |
无 |
是,写系统运行记录 |
否 |
message_index 冲突、modality 与 source_url 不一致、用户不存在时拒绝 |
无 |
保存原文与可选 source_url;不存媒体二进制;不需要用户确认 |
| 全局数据模块 |
查询重排方案详情 |
查询 |
母 AI 编排模块、基础业务模块 |
user_id、proposal_id |
ReplanProposalDTO、changes: list[ReplanChangeDTO] |
replan_proposals、replan_proposal_changes |
无 |
否 |
否 |
方案不存在或越权时返回错误 |
无 |
供确认卡片展示候选变更;不修改事项 |
| 全局数据模块 |
校验事项归属 |
校验 |
母 AI 编排模块、基础业务模块 |
user_id、item_id |
owned: bool |
task_items |
无 |
否 |
否 |
事项不存在时返回 owned=false 或明确错误码 |
无 |
进程内函数,防越权;不暴露 HTTP |
| 全局数据模块 |
校验事项存在性 |
校验 |
母 AI 编排模块、基础业务模块 |
user_id、item_id |
exists: bool |
task_items |
无 |
否 |
否 |
已软删视为不存在 |
无 |
修改、删除、反馈前检查;is_deleted=false |
| 全局数据模块 |
校验目标唯一性 |
校验 |
母 AI 编排模块 |
user_id、candidate_condition |
unique_target / candidates / none |
task_items |
无 |
否 |
否 |
0 候选或 ≥2 候选时由母 AI 反问,本函数不猜主键 |
无 |
反馈定位与重排对象选择;可复用查询候选结果 |
| 全局数据模块 |
校验写入前提 |
校验 |
母 AI 编排模块、基础业务模块 |
user_id、write_request_id、payload_hash |
allowed: bool、拒绝原因 |
write_requests、operation_confirmations、目标表 |
无 |
否 |
否 |
未确认、过期、越权、版本冲突时返回不可写 |
无 |
封装 assert_confirmed_write + 归属 + 版本 + 白名单预检;真正写入仍走事务入口 |
| 全局数据模块 |
创建写入请求 |
生成候选 |
母 AI 编排模块、基础业务模块 |
WriteRequestDraft |
WriteRequestDTO |
write_requests |
无 |
是,写候选请求 |
否,后续确认 |
非法 action、payload 字段不在白名单、幂等键重复时返回错误 |
无 |
保存已完成字段校验的结构化候选;数据库触发器根据完整 payload 生成 hash;此时尚未改动业务事实 |
| 全局数据模块 |
保存重排候选方案 |
生成候选 |
母 AI 编排模块 |
SaveReplanProposalRequest |
ReplanProposalDTO |
replan_proposals、replan_proposal_changes |
无 |
是,写工作流候选 |
否 |
变更缺少 expected_item_version(update/delete)时拒绝 |
无 |
入参 changes 使用 ReplanChangeDraft(无 id/proposal_id);模块根据 input_snapshot 生成 input_snapshot_hash,调用方不得伪造;确认前可保存,真正改事项必须再走 apply |
| 全局数据模块 |
追加任务级画像原始观察 |
记录 |
母 AI 编排模块 |
AppendTaskProfileObservationRequest |
TaskProfileObservationDTO |
task_profile_observations |
无 |
是,只追加观察 |
否 |
长任务不存在或越权时拒绝 |
无 |
原始观察属系统运行记录,可自动追加;不覆盖历史观察 |
| 全局数据模块 |
记录确认事件 |
确认 |
弹窗确认机制、母 AI 编排模块、基础业务模块 |
ConfirmWriteRequest |
ConfirmWriteResponse |
write_requests、operation_confirmations |
无 |
是,写确认记录 |
是 |
请求不存在、已过期、payload_hash 不一致、重复确认时返回错误 |
无 |
确认成功只改变请求状态,不直接写业务事实 |
| 全局数据模块 |
事务校验并应用写入 |
确认落盘 |
母 AI 编排模块、基础业务模块 |
user_id、write_request_id、payload_hash |
ApplyResult |
write_requests、operation_confirmations、目标业务表 |
无 |
是,写业务事实 |
是 |
成功路径同事务提交;失败先回滚,再用短事务标记请求失败 |
见查缺补漏 |
统一入口:按 action 分派到具体确认后写入函数;业务写入与请求状态更新同事务 |
| 全局数据模块 |
确认后新增长任务 |
确认落盘 |
母 AI 编排模块、基础业务模块 |
user_id、write_request_id、payload_hash;payload 含 title、description?、start_at?、deadline_at? |
ApplyResult,含新增 long_goal_id |
write_requests、operation_confirmations、long_goals |
无 |
是 |
是 |
action 不匹配或字段非法时拒绝 |
无 |
执行已确认的 create_goal |
| 全局数据模块 |
确认后修改长任务 |
确认落盘 |
母 AI 编排模块、基础业务模块 |
user_id、write_request_id、payload_hash;action=update_goal;payload 含 long_goal_id、非空 changes;请求顶层 base_version 必填 |
ApplyResult |
write_requests、operation_confirmations、long_goals |
无 |
是 |
是 |
越权、已删除、版本冲突、空修改或未知字段时拒绝 |
无 |
changes 可同时包含普通字段与 plan_overview;完整变更一次确认并在同一事务执行,成功后版本只递增一次 |
| 全局数据模块 |
确认后软删除长任务 |
确认落盘 |
母 AI 编排模块、基础业务模块 |
user_id、write_request_id、payload_hash;payload 含 long_goal_id、cascade_subtasks: list[{item_id, expected_item_version}];请求顶层 base_version 必填 |
ApplyResult,含实际级联清单与数量 |
write_requests、operation_confirmations、long_goals、task_items |
无 |
是 |
是 |
目标已删除/越权/版本冲突,或当前子任务 ID/版本集合与确认清单不一致时整单拒绝 |
无 |
确认卡片展示完整级联范围;应用时锁定目标与子任务并逐项校验,只软删确认清单内对象;反馈外键仍指向保留行 |
| 全局数据模块 |
确认后新增事项 |
确认落盘 |
母 AI 编排模块、基础业务模块 |
user_id、write_request_id、payload_hash;payload 含 item_type、title、start_at?、end_at?、due_at?、long_goal_id? |
ApplyResult,含新增 item_id |
write_requests、operation_confirmations、task_items |
无 |
是 |
是 |
日程缺时间范围、子任务缺长任务、关系不合法时拒绝 |
无 |
执行已确认的新增日程、待办或子任务 |
| 全局数据模块 |
确认后修改事项 |
确认落盘 |
母 AI 编排模块、基础业务模块 |
user_id、write_request_id、payload_hash;payload 含 item_id、changes;请求顶层 base_version 必填 |
ApplyResult |
write_requests、operation_confirmations、task_items |
无 |
是 |
是 |
目标不存在、越权、版本冲突或字段不在白名单时拒绝 |
无 |
只修改白名单字段,并递增 version |
| 全局数据模块 |
确认后软删除事项 |
确认落盘 |
母 AI 编排模块、基础业务模块 |
user_id、write_request_id、payload_hash;payload 含 item_id;请求顶层 base_version 必填 |
ApplyResult |
write_requests、operation_confirmations、task_items |
无 |
是 |
是 |
已删除、越权或版本冲突时拒绝并整体回滚 |
无 |
只更新删除标记、删除时间和版本,保留关联反馈 |
| 全局数据模块 |
确认后追加执行反馈 |
确认落盘 |
母 AI 编排模块 |
user_id、write_request_id、payload_hash;payload 含 item_id、execution_status、raw_feedback、normalized_feedback、occurred_at、duration_minutes? |
ApplyResult,含 feedback_id |
write_requests、operation_confirmations、feedback_records、task_items |
无 |
是 |
是 |
反馈目标不匹配确认请求或目标事项不存在时拒绝 |
无 |
反馈是不可变事件,不直接修改 task_items.status |
| 全局数据模块 |
确认后更新用户画像 |
确认落盘 |
母 AI 编排模块、基础业务模块 |
user_id、write_request_id、payload_hash;payload 含 profile_data、source;如需乐观锁,使用请求顶层 base_version |
ApplyResult |
write_requests、operation_confirmations、user_profiles |
无 |
是 |
是 |
source 非法或版本冲突时拒绝 |
无 |
只保存用户主动填写或明确输入的画像;source 限 user_form / user_explicit_input |
| 全局数据模块 |
确认后保存任务级画像 |
确认落盘 |
母 AI 编排模块 |
user_id、write_request_id、payload_hash;payload 含 long_goal_id、profile_summary、version |
ApplyResult,含 snapshot_id |
write_requests、operation_confirmations、task_profile_snapshots |
无 |
是 |
是 |
长任务不存在、确认动作不匹配或版本冲突时拒绝 |
无 |
AI 归纳快照必须经确认;写入时把旧快照 is_current=false |
| 全局数据模块 |
确认后更新长任务宏观规划 |
确认落盘 |
母 AI 编排模块 |
user_id、write_request_id、payload_hash;action=update_goal;payload 含 long_goal_id、changes.plan_overview;请求顶层 base_version 必填 |
ApplyResult |
write_requests、operation_confirmations、long_goals |
无 |
是 |
是 |
规划文本为空、长任务不存在、越权或版本冲突时拒绝 |
无 |
宏观规划单独修改时使用 changes.plan_overview;若还包含普通字段,由「确认后修改长任务」按组合 payload 同事务处理;可执行任务仍来自 task_items(item_type=subtask) |
| 全局数据模块 |
确认后应用重排方案 |
确认落盘 |
母 AI 编排模块 |
user_id、write_request_id、payload_hash;payload 含 proposal_id;action=apply(兼容 apply_replan) |
ApplyResult,含 application_id |
replan_proposals、replan_proposal_changes、replan_applications、task_items |
无 |
是 |
是 |
任一变更版本冲突则整单回滚;方案状态非法时拒绝 |
无 |
同事务按 sort_order 应用全部变更,写入 replan_applications,并校验每条 expected_item_version |
| 系统日志模块 |
开始 Agent 运行记录 |
记录 |
母 AI 编排模块、全局数据模块、前端交互与展示模块 |
StartAgentRunRequest |
agent_run_id |
agent_run_records |
无 |
是 |
否 |
组件名为空或用户不存在时返回错误 |
无 |
创建请求级运行摘要 |
| 系统日志模块 |
结束 Agent 运行记录 |
记录 |
母 AI 编排模块、全局数据模块、前端交互与展示模块 |
FinishAgentRunRequest |
ok: bool |
agent_run_records |
无 |
是 |
否 |
运行记录不存在或不属于当前用户时返回错误 |
无 |
更新终态、错误码和结束时间;不保存完整模型响应 |
说明:
- 校验四类对应模块拆分 7.2.4,列入对外函数表供汇总发现提供方;不单独暴露 HTTP。
- 复盘接口只查询原始事实;复盘 Agent 生成的完整文本只展示、不入库;长任务最新
review_summary 需经确认后单独写回 long_goals。
- 长任务普通字段、宏观规划和最新简洁复盘摘要共用
write_action=update_goal;payload 可只含其中一类,也可在用户明确要求时组合多类,所有字段必须通过白名单并完整展示在同一确认卡片中。
5. 模块依赖函数表
本表只填写本模块主动依赖的其他模块能力,不填写「谁依赖本模块」。被依赖关系见第 4 节对外函数表的「调用方」列。
| 所属模块 |
依赖模块 |
需要的函数中文名称 |
依赖原因 |
输入参数 |
返回值 |
是否强依赖 |
缺失时处理 |
| 全局数据模块 |
用户账号模块 |
获取当前用户 ID / 校验登录态 |
所有查询和写入必须限定当前用户,防止越权 |
登录态、business_user_id? |
user_id、用户状态 |
是 |
无法确定用户时拒绝查询和写入 |
| 系统日志模块 |
用户账号模块 |
校验运行记录归属用户 |
Agent 运行摘要必须关联真实用户 |
user_id |
用户存在性和状态 |
是 |
用户不存在时拒绝写入运行摘要 |
| 系统日志模块 |
LangSmith 等可观测平台 |
关联 trace_id(可选) |
运行摘要只保存链路 ID,不保存完整 Prompt 和模型原文 |
trace_id |
外部链路地址或 ID |
否 |
没有 trace_id 时仍可写入运行摘要,但无法跳转完整调用链 |
6. 模块内部函数表
| 所属模块 |
内部函数中文名称 |
上游函数 |
下游函数 |
上游输入 |
内部处理 |
下游输出 |
依赖数据 |
是否调用 LLM |
是否写入 |
失败处理 |
数据流转说明 |
| 全局数据模块 |
规范化查询时间范围 |
查询事项列表 / 查询今日事项 API |
事项查询 SQL |
date、from_time、to_time、用户时区 |
将日期转换为当天 [from_time,to_time);校验开始时间小于结束时间;日程使用 start_at < to_time AND end_at > from_time,待办/子任务使用 due_at >= from_time AND due_at < to_time |
标准化范围与类型谓词 |
users.timezone、task_items |
否 |
否 |
时间格式错误返回参数错误 |
不查业务表,只做时间规范化;无时间范围不附加时间谓词 |
| 全局数据模块 |
组装复盘原始数据 |
查询复盘关联数据 |
返回 ReviewDataResponse |
user_id、标准化时间范围、goal_id? |
查询未软删除事项并复用类型时间谓词;查询与事项关联的不可变反馈;查询关联的未软删除长任务 |
items、feedbacks、goals |
task_items、feedback_records、long_goals |
否 |
否 |
无数据返回三个空列表;查询失败返回内部错误 |
只读取已保存事实,不读取历史复盘文本,不计算完成率,不产生写入 |
| 全局数据模块 |
组装事项 DTO |
各查询函数 |
对外返回 |
数据库行 |
过滤软删除字段;转换枚举、时间和版本字段 |
TaskItemDTO、LongGoalDTO |
task_items、long_goals |
否 |
否 |
字段缺失时记录内部错误 |
不返回 is_deleted 给普通只读页;内部校验仍使用该字段 |
| 全局数据模块 |
校验写入动作白名单 |
创建写入请求 / 事务校验并应用写入 |
创建候选或分派写入 |
action、payload |
按 action 校验字段;update_goal 要求 long_goal_id 和非空 changes,字段使用长任务白名单;delete_goal 要求 long_goal_id 和完整 cascade_subtasks 条目;禁止外部传入表名或任意 SQL 字段 |
合法 payload |
write_action 枚举 |
否 |
否 |
空修改、重复级联 ID、版本非正或非白名单字段直接拒绝 |
不执行业务写入 |
| 全局数据模块 |
分配对话 message_index |
保存对话消息 |
插入 conversation_messages |
user_id |
未提供序号时,在事务内对用户行加锁后计算 max(message_index)+1;调用方提供序号时校验唯一 |
下一个序号 |
conversation_messages |
否 |
否 |
序号冲突时回滚并重试或返回冲突 |
数据库唯一约束保证 (user_id, message_index) 唯一;不能用无锁的简单 max+1 保证并发安全 |
| 全局数据模块 |
预计算长任务级联删除范围 |
创建写入请求 |
校验写入动作白名单 / write_requests 插入 |
user_id、long_goal_id、base_version |
锁定并读取未软删目标及其所有未软删子任务,生成按 item_id 排序的 cascade_subtasks(含各自版本);目标或版本不匹配时拒绝创建请求 |
完整 delete_goal payload |
long_goals、task_items |
否 |
否 |
目标不存在、版本冲突或越权时不创建候选 |
读取不改变业务事实;生成的清单纳入 payload hash |
| 全局数据模块 |
创建候选写入请求 |
创建写入请求 |
返回 WriteRequestDTO |
WriteRequestDraft |
写入 write_requests,由数据库触发器根据完整 payload 生成 payload_hash,设置数据库默认过期时间和幂等约束 |
WriteRequestDTO |
write_requests |
否 |
是 |
幂等键重复时返回已有请求或冲突 |
不改业务事实表;确认卡片展示该 payload 的实际变更范围 |
| 全局数据模块 |
校验确认凭证 |
事务校验并应用写入 / 校验写入前提 |
校验目标归属和版本 |
user_id、write_request_id、payload_hash |
调用 assert_confirmed_write |
可执行确认凭证 |
write_requests、operation_confirmations |
否 |
否 |
未确认、过期或 hash 不一致时拒绝写入 |
不替代版本校验和白名单 |
| 全局数据模块 |
校验目标归属和版本 |
事务校验并应用写入 |
分派具体写入动作 |
target_type、target_id、base_version |
使用 user_id + id + version + is_deleted=false 检查目标;长任务删除另锁定并逐项比对 payload 中每个 cascade_subtasks.expected_item_version |
可写目标对象 |
task_items、long_goals 等 |
否 |
否 |
越权、已删除、版本变化或级联集合变化时返回冲突 |
重排场景改为校验每条 expected_item_version |
| 全局数据模块 |
分派具体写入动作 |
事务校验并应用写入 |
各确认后写入函数 |
已确认写入请求 |
按 action 与 payload 白名单分派 create/update/delete/feedback/profile/apply;update_goal 直接应用 changes,delete_goal 应用完整级联清单 |
业务写入结果 |
对应业务表 |
否 |
是 |
任一动作失败则事务回滚 |
不允许动态拼接表名 |
| 全局数据模块 |
执行软删除 |
确认后软删除事项 / 长任务 |
更新写入请求状态 |
target_type、target_id、base_version |
普通事项更新删除标记;长任务先校验确认 payload 的完整级联集合,再更新目标和清单内子任务 is_deleted=true、deleted_at=now()、version+1 |
删除结果(含级联明细与数量) |
task_items、long_goals |
否 |
是 |
已删除、版本冲突或级联集合变化时拒绝并整单回滚 |
不物理删除;反馈外键仍有效 |
| 全局数据模块 |
级联软删长任务子任务 |
执行软删除(长任务) |
更新写入请求状态 |
user_id、long_goal_id、cascade_subtasks |
FOR UPDATE 锁定当前未软删子任务;要求当前 ID/版本集合与确认 payload 完全一致;逐项更新清单内子任务 |
级联软删明细与数量 |
task_items |
否 |
是 |
新增、删除、改版或归属变化任一发生则整单回滚 |
仅软删标记;不碰 feedback_records;父目标锁阻止并发绕过确认范围 |
| 全局数据模块 |
应用重排变更集 |
确认后应用重排方案 |
更新写入请求状态 |
proposal_id、确认请求 |
按 sort_order 依次 create/update/soft-delete,并写 replan_applications |
应用摘要 |
replan_*、task_items |
否 |
是 |
任一变更冲突则整单回滚 |
不接受前端直接传变更列表绕过方案表 |
| 全局数据模块 |
更新写入请求状态 |
各确认后写入函数 |
对外 ApplyResult |
写入结果或失败原因 |
成功路径在当前业务事务中更新为 applied;失败路径先回滚,再开短事务更新为 failed |
ApplyResult 或错误 |
write_requests |
否 |
是 |
状态更新失败时回滚对应事务并返回内部错误 |
成功状态与业务写入同事务提交;失败状态不复用已回滚事务 |
| 系统日志模块 |
创建运行摘要 |
开始 Agent 运行记录 |
后续业务调用 |
Agent 调用上下文 |
插入 agent_run_records,状态默认 started |
agent_run_id |
agent_run_records |
否 |
是 |
缺少组件名时拒绝 |
不保存 Prompt |
| 系统日志模块 |
更新运行终态 |
结束 Agent 运行记录 |
无 |
agent_run_id、status、error_code? |
更新状态、错误码和 finished_at |
ok: bool |
agent_run_records |
否 |
是 |
不存在或越权时返回错误 |
不保存模型原文 |
7. Python 数据结构声明
以下结构用于对齐接口字段,不要求作为独立 Python 文件提交。
from datetime import date, datetime
from enum import Enum
from typing import Any, Literal
from uuid import UUID
from pydantic import BaseModel, Field
class ItemType(str, Enum):
schedule = "schedule"
todo = "todo"
subtask = "subtask"
class ItemStatus(str, Enum):
planned = "planned"
in_progress = "in_progress"
completed = "completed"
cancelled = "cancelled"
deferred = "deferred"
class GoalStatus(str, Enum):
active = "active"
completed = "completed"
paused = "paused"
cancelled = "cancelled"
archived = "archived"
class FeedbackStatus(str, Enum):
completed = "completed"
not_completed = "not_completed"
partially_completed = "partially_completed"
deferred = "deferred"
cancelled = "cancelled"
class MessageRole(str, Enum):
user = "user"
assistant = "assistant"
system = "system"
tool = "tool"
class InputModality(str, Enum):
text = "text"
voice_asr = "voice_asr"
image_ocr = "image_ocr"
class WriteAction(str, Enum):
create_goal = "create_goal"
update_goal = "update_goal"
delete_goal = "delete_goal"
create_item = "create_item"
update_item = "update_item"
delete_item = "delete_item"
append_feedback = "append_feedback"
update_user_profile = "update_user_profile"
save_task_profile_snapshot = "save_task_profile_snapshot"
apply = "apply"
apply_replan = "apply_replan" # 历史兼容;新接口优先 apply
class WriteRequestStatus(str, Enum):
pending = "pending"
confirmed = "confirmed"
rejected = "rejected"
expired = "expired"
applied = "applied"
failed = "failed"
class ProposalStatus(str, Enum):
draft = "draft"
pending_confirmation = "pending_confirmation"
confirmed = "confirmed"
applied = "applied"
rejected = "rejected"
expired = "expired"
conflict = "conflict"
failed = "failed"
class ConfirmationDecision(str, Enum):
confirmed = "confirmed"
rejected = "rejected"
class AgentRunStatus(str, Enum):
started = "started"
succeeded = "succeeded"
failed = "failed"
blocked = "blocked"
class ProposalChangeAction(str, Enum):
create = "create"
update = "update"
delete = "delete"
class TaskItemDTO(BaseModel):
id: UUID
user_id: UUID
item_type: ItemType
title: str
description: str | None = None
start_at: datetime | None = None
end_at: datetime | None = None
due_at: datetime | None = None
status: ItemStatus
long_goal_id: UUID | None = None
version: int
class CandidateItemDTO(TaskItemDTO):
match_reason: str | None = None
class LongGoalDTO(BaseModel):
id: UUID
user_id: UUID
title: str
description: str | None = None
plan_overview: str | None = None
review_summary: str | None = None
start_at: datetime | None = None
deadline_at: datetime | None = None
status: GoalStatus
version: int
class UserProfileDTO(BaseModel):
user_id: UUID
profile_data: dict[str, Any]
source: Literal["user_form", "user_explicit_input"]
version: int
updated_at: datetime
class TaskProfileObservationDTO(BaseModel):
id: UUID
user_id: UUID
long_goal_id: UUID
source: Literal["user_explicit_input", "replan_reason"]
raw_text: str
structured_observation: dict[str, Any]
source_message_id: UUID | None = None
created_at: datetime
class TaskProfileSnapshotDTO(BaseModel):
id: UUID
user_id: UUID
long_goal_id: UUID
profile_summary: dict[str, Any]
version: int
confirmation_id: UUID
is_current: bool
created_at: datetime
class FeedbackRecordDTO(BaseModel):
id: UUID
user_id: UUID
item_id: UUID
execution_status: FeedbackStatus
raw_feedback: str
normalized_feedback: str
duration_minutes: int | None = None
occurred_at: datetime
confirmation_id: UUID
created_at: datetime
class ConversationMessageDTO(BaseModel):
id: UUID
user_id: UUID
message_index: int
role: MessageRole
modality: InputModality | None = None
raw_content: str
source_url: str | None = None
metadata: dict[str, Any]
created_at: datetime
class SaveConversationMessageRequest(BaseModel):
user_id: UUID # 实现时由登录态或母 AI 上下文注入
role: MessageRole
raw_content: str
modality: InputModality | None = None
source_url: str | None = None
metadata: dict[str, Any] = Field(default_factory=dict)
message_index: int | None = None # 为空则由模块分配下一个序号
class ReplanChangeDraft(BaseModel):
"""创建重排方案时使用;尚无 id / proposal_id。"""
item_id: UUID | None = None
action: ProposalChangeAction
expected_item_version: int | None = None
before_snapshot: dict[str, Any] | None = None
after_snapshot: dict[str, Any]
sort_order: int
class ReplanChangeDTO(BaseModel):
id: UUID
proposal_id: UUID
item_id: UUID | None = None
action: ProposalChangeAction
expected_item_version: int | None = None
before_snapshot: dict[str, Any] | None = None
after_snapshot: dict[str, Any]
sort_order: int
class ReplanProposalDTO(BaseModel):
id: UUID
user_id: UUID
long_goal_id: UUID | None = None
input_snapshot_hash: str
proposal_summary: dict[str, Any]
status: ProposalStatus
created_at: datetime
updated_at: datetime
class QueryTodayItemsRequest(BaseModel):
user_id: UUID # 实现时由登录态注入
date: date
class QueryTodayItemsResponse(BaseModel):
items: list[TaskItemDTO]
class QueryGoalsRequest(BaseModel):
user_id: UUID
status: GoalStatus | None = None
include_deleted: bool = False
class QueryGoalsResponse(BaseModel):
goals: list[LongGoalDTO]
class QueryGoalWithItemsRequest(BaseModel):
user_id: UUID
goal_id: UUID
class QueryGoalWithItemsResponse(BaseModel):
goal: LongGoalDTO
items: list[TaskItemDTO]
class QueryUserProfileRequest(BaseModel):
user_id: UUID
class QueryUserProfileResponse(BaseModel):
profile: UserProfileDTO | None = None
class QueryTaskProfileRequest(BaseModel):
user_id: UUID
long_goal_id: UUID
class QueryTaskProfileResponse(BaseModel):
observations: list[TaskProfileObservationDTO]
current_snapshot: TaskProfileSnapshotDTO | None = None
class ReviewDataRequest(BaseModel):
user_id: UUID
from_time: datetime
to_time: datetime
review_type: str | None = None
goal_id: UUID | None = None
class ReviewDataResponse(BaseModel):
"""实时查询得到的复盘原始事实,不包含复盘报告文本。"""
items: list[TaskItemDTO]
feedbacks: list[FeedbackRecordDTO]
goals: list[LongGoalDTO]
class SaveReplanProposalRequest(BaseModel):
user_id: UUID
long_goal_id: UUID | None = None
trigger_request_id: UUID | None = None
input_snapshot: dict[str, Any]
proposal_summary: dict[str, Any]
changes: list[ReplanChangeDraft]
class AppendTaskProfileObservationRequest(BaseModel):
user_id: UUID
long_goal_id: UUID
source: Literal["user_explicit_input", "replan_reason"]
raw_text: str
structured_observation: dict[str, Any]
source_message_id: UUID | None = None
class UpdateGoalPayload(BaseModel):
"""action=update_goal 的完整操作内容;changes 至少包含一个白名单字段。"""
long_goal_id: UUID
changes: dict[str, Any]
class GoalCascadeSubtask(BaseModel):
item_id: UUID
expected_item_version: int = Field(gt=0)
class DeleteGoalPayload(BaseModel):
"""服务端生成并写入 hash 的完整长任务删除范围。"""
long_goal_id: UUID
cascade_subtasks: list[GoalCascadeSubtask]
class WriteRequestDraft(BaseModel):
user_id: UUID
action: WriteAction
payload: dict[str, Any]
idempotency_key: str
target_type: str | None = None
target_id: UUID | None = None
base_version: int | None = None
trace_id: str | None = None
class WriteRequestDTO(BaseModel):
id: UUID
user_id: UUID
action: WriteAction
target_type: str | None = None
target_id: UUID | None = None
payload: dict[str, Any]
payload_hash: str
idempotency_key: str
status: WriteRequestStatus
base_version: int | None = None
trace_id: str | None = None
expires_at: datetime
class ConfirmWriteRequest(BaseModel):
user_id: UUID
write_request_id: UUID
payload_hash: str
decision: ConfirmationDecision
client_event_id: str | None = None
class ConfirmWriteResponse(BaseModel):
confirmation_id: UUID
write_request_id: UUID
status: WriteRequestStatus
class ApplyConfirmedWriteRequest(BaseModel):
user_id: UUID
write_request_id: UUID
payload_hash: str
class ApplyResult(BaseModel):
write_request_id: UUID
action: WriteAction
target_type: str | None = None
target_id: UUID | None = None
result: dict[str, Any]
class ApplyConfirmedWriteResponse(BaseModel):
result: ApplyResult
class ValidateItemOwnershipRequest(BaseModel):
user_id: UUID
item_id: UUID
class ValidateItemOwnershipResponse(BaseModel):
owned: bool
class ValidateItemExistsRequest(BaseModel):
user_id: UUID
item_id: UUID
class ValidateItemExistsResponse(BaseModel):
exists: bool
class ValidateTargetUniquenessRequest(BaseModel):
user_id: UUID
candidate_condition: dict[str, Any]
class ValidateTargetUniquenessResponse(BaseModel):
result: Literal["unique", "multiple", "none"]
candidates: list[CandidateItemDTO] = Field(default_factory=list)
class ValidateWritePrerequisiteRequest(BaseModel):
user_id: UUID
write_request_id: UUID
payload_hash: str
class ValidateWritePrerequisiteResponse(BaseModel):
allowed: bool
reason: str | None = None
class StartAgentRunRequest(BaseModel):
user_id: UUID
correlation_id: UUID
component_name: str
function_name: str | None = None
source_message_id: UUID | None = None
trace_id: str | None = None
class FinishAgentRunRequest(BaseModel):
user_id: UUID
agent_run_id: UUID
status: AgentRunStatus
error_code: str | None = None
class AgentRunRecordDTO(BaseModel):
id: UUID
user_id: UUID
correlation_id: UUID
trace_id: str | None = None
component_name: str
function_name: str | None = None
status: AgentRunStatus
error_code: str | None = None
started_at: datetime
finished_at: datetime | None = None
8. 数据库查缺补漏表
对照《架构设计MVP阶段数据库设计初稿》逐项检查。结论:核心业务表、确认链路、软删除、重排工作流、画像双表和 Agent 运行摘要表已具备;当前剩余事项主要是成员 3 的实现约定与事务边界,不是 Wiki 或数据库缺表缺字段。
| 接口 / 函数名称 |
需要的数据 |
当前来源 |
是否可直接获得 |
是否可推导 |
缺口类型 |
建议补充 |
风险等级 |
| 查询今日事项 |
当前用户当天未删除事项;用户时区 |
task_items 时间字段;users.timezone;task_items_user_time_idx、task_items_user_due_idx |
是 |
是,由 date + timezone 推导当天范围 |
无 |
实现时必须用用户时区;日程使用时间索引,待办/子任务使用 due_at 部分索引;默认 is_deleted=false 即可排除已级联软删的子任务 |
低 |
| 查询事项列表 |
时间范围、事项类型、状态、软删除过滤条件 |
task_items;task_items_user_time_idx;成员 3 统一时间谓词 |
是 |
是 |
索引补充 |
日程使用区间重叠谓词;待办/子任务使用 due_at 窗口谓词;实现迁移新增 (user_id, due_at) 部分索引(仅 todo/subtask 且未软删) |
中 |
| 查询事项详情 |
事项 ID、用户归属、软删除状态、版本 |
task_items;(user_id, id) 复合唯一 |
是 |
否 |
无 |
HTTP 层从登录态取 user_id;已软删返回 404 |
低 |
| 查询长任务列表 |
当前用户长任务、状态、软删除过滤条件 |
long_goals;long_goals_user_status_idx |
是 |
否 |
无 |
提供 list_goals(user_id, status?, include_deleted=false) 和 /api/goals,按 updated_at DESC 返回 |
低 |
| 查询长任务及子任务 |
长任务信息、宏观规划、子任务列表 |
long_goals;task_items_goal_idx |
是 |
否 |
无 |
子任务仅通过 long_goal_id 归属,不设计父子树 |
低 |
| 查询用户画像 |
画像 JSON、来源、版本 |
user_profiles |
是 |
否 |
无 |
未填写时返回空,不阻塞主流程 |
低 |
| 查询任务级画像 |
原始观察 + 当前快照 |
task_profile_observations、task_profile_snapshots |
是 |
否 |
无 |
查询时过滤 is_current=true 快照 |
低 |
| 查询候选反馈目标 |
时间范围内可反馈事项 |
task_items |
是 |
是,可按时间/类型过滤 |
索引补充 |
复用统一时间谓词;todo/subtask 使用 due_at;实现迁移新增 (user_id, due_at) 部分索引 |
中 |
| 查询复盘关联数据 |
时间范围内已保存的事项、执行反馈和关联目标 |
task_items、feedback_records、long_goals |
是 |
否,MVP 不计算完成率 |
过滤规则补充 |
每次复盘实时查询三表;事项按日程重叠或 due_at 落窗筛选;无数据返回空列表;完整复盘报告不入库,目标可返回已保存的 review_summary |
低 |
| 查询最近对话消息 |
最近 N 条原文与 source_url |
conversation_messages;conversation_messages_window_idx |
是 |
否 |
无 |
按 message_index 倒序取、正序返回;媒体二进制不进库 |
低 |
| 保存对话消息 |
role、raw_content、modality、source_url、message_index |
conversation_messages 及 modality/source_url 一致性约束 |
是 |
未提供时可在事务内加锁后分配下一个序号 |
无 |
系统运行记录,无需用户确认;由全局数据模块统一写入;不能用无锁的简单 max+1 处理并发 |
低 |
| 查询重排方案详情 |
方案摘要与变更列表 |
replan_proposals、replan_proposal_changes |
是 |
否 |
无 |
变更修改/删除必须带 expected_item_version |
低 |
| 创建写入请求 |
action、完整 payload、幂等键、过期时间、base_version |
write_requests;触发器根据完整 payload 生成 payload_hash;(user_id, idempotency_key) 唯一 |
是 |
payload_hash 可推导;过期时间由数据库默认值生成 |
无 |
前端不得自造 hash 或过期时间;服务端接收已经完成字段校验的完整 action + payload,再保存候选请求;update_goal 使用 long_goal_id + changes |
高 |
| 保存重排候选方案 |
输入快照及其哈希、变更集 Draft、方案状态 |
replan_proposals、replan_proposal_changes |
是 |
input_snapshot_hash 由输入快照推导 |
无 |
入参用 ReplanChangeDraft;模块生成并保存 input_snapshot_hash;确认前可写工作流表;真正改事项必须再走 apply |
中 |
| 追加任务级画像原始观察 |
原始文本、结构化观察、来源 |
task_profile_observations |
是 |
否 |
无 |
只追加不覆盖;不需要确认 |
低 |
| 记录确认事件 |
确认请求、hash、decision、client_event_id |
operation_confirmations;write_request_id 唯一 |
是 |
否 |
无 |
一对一约束防重复确认 |
高 |
| 事务校验并应用写入 |
已确认请求、目标归属、版本、请求状态 |
assert_confirmed_write + 目标表 + write_requests |
是 |
否 |
无 |
成功路径将业务写入与请求状态 applied 同事务提交;失败先回滚,再开短事务标记请求 failed |
高 |
| 确认后新增/修改/软删除事项 |
事项字段、版本、软删除标记 |
task_items 及关系触发器 |
是 |
否 |
无 |
日程时间、子任务归属由数据库触发器兜底 |
中 |
| 确认后新增长任务/修改/软删除 |
长任务字段、版本、软删除标记;级联子任务 ID 与版本 |
long_goals、task_items |
是 |
否 |
成员 3 应用契约 |
delete_goal 应用时锁定目标和当前子任务,要求集合/版本与确认 payload 完全一致;同事务软删下属 subtask;不物理删除,反馈外键仍有效 |
中 |
| 确认后追加执行反馈 |
反馈事件、confirmation_id |
feedback_records |
是 |
否 |
无 |
反馈不直接改 task_items.status |
中 |
| 确认后更新用户画像 |
profile_data、source、version |
user_profiles;profile_source 枚举 |
是 |
否 |
无 |
source 仅允许 user_form / user_explicit_input |
中 |
| 确认后保存任务级画像 |
profile_summary、confirmation_id、is_current |
task_profile_snapshots |
是 |
否 |
无 |
新快照确认后需把旧快照 is_current=false;建议应用层同事务处理 |
中 |
| 确认后更新宏观规划 |
plan_overview、version;可选同时修改普通长任务字段 |
long_goals.plan_overview、长任务普通字段 |
是 |
否 |
无 |
单独或组合修改均使用 update_goal;组合修改一次确认、同事务执行、版本只递增一次 |
中 |
| 确认后应用重排方案 |
proposal、changes、application、write_request |
replan_* + task_items |
是 |
否 |
无 |
payload 必须含 proposal_id;新接口用 action=apply,兼容 apply_replan |
高 |
| 校验事项归属/存在性/唯一性/写入前提 |
归属、未删除、候选数量、确认状态 |
task_items、write_requests、operation_confirmations |
是 |
否 |
无 |
进程内对外函数;不暴露 HTTP |
低 |
| 开始/结束 Agent 运行记录 |
组件名、状态、trace、correlation |
agent_run_records |
是 |
否 |
无 |
不保存完整 Prompt |
低 |
| 保存长任务简洁复盘 |
long_goal_id、review_summary、base_version |
当前数据库初稿的 long_goals 尚无 review_summary |
否 |
否 |
缺字段 |
在 long_goals 增加可空 review_summary 文本字段及 500 字限制;通过 update_goal 确认写入,只保留最新摘要 |
中 |
| 生产数据库权限 |
运行账号不能直接 DML 业务表 |
部署配置;SQL 初稿只声明原则 |
否 |
否 |
缺部署授权规则 |
部署时收敛应用账号权限,只允许 repository/service 或受控函数写入 |
高 |
8.1 长任务简洁复盘字段(成员 3 补充)
long_goals.review_summary 是成员 3 针对“长任务保留一条简洁复盘”的新增字段级契约,不是三份 Wiki 已定义的固定字段。字段允许为空,最多 500 字;每个长任务只保留最新摘要,更新时覆盖旧值,不保存完整复盘报告和摘要历史。
该字段属于长任务业务事实,写入必须使用现有 action=update_goal、changes.review_summary、base_version 和用户确认链。数据库设计落地时需在 long_goals 增加可空文本字段及长度/非空校验,并在 LongGoalDTO、长任务详情/列表和复盘关联数据中返回;三份 Wiki 原文保持不变。
9. 风险说明
| 风险 |
表现 |
处理方式 |
| 前端伪造确认 |
只传 is_confirmed=true 就直接写入业务表 |
禁止布尔确认;必须校验 write_request_id、operation_confirmations、payload_hash、过期时间和用户归属 |
| 前端伪造用户 ID |
请求体携带他人 user_id 读数据 |
HTTP 层从登录态注入用户;查询默认带当前用户范围 |
| LLM 猜错数据库主键 |
用户说“把刚才那个任务删掉”,模型直接猜一个 ID |
母 AI 必须先调用全局数据模块查候选 / 校验目标唯一性;单候选才继续,多候选触发反问,无候选要求补充信息 |
| 并发修改导致覆盖 |
用户确认前,目标事项已被其他操作改过 |
更新和删除必须带 base_version;重排变更带 expected_item_version;冲突时返回 version_conflict |
| 重复点击确认或重复提交 |
同一个请求被应用多次 |
operation_confirmations.write_request_id 唯一;write_requests.idempotency_key 对同一用户唯一;已应用请求不可再次应用 |
| 重排部分成功 |
十条变更写到一半失败 |
同事务应用;任一条版本冲突则整单回滚,方案标记冲突并要求重新生成 |
| 软删除实现不完整 |
删除时漏写 deleted_at 或 version;普通查询仍返回已删除对象;误删关联反馈 |
删除操作只更新 is_deleted=true、deleted_at 和 version,不物理删除业务对象,也不修改关联反馈;普通查询默认过滤 is_deleted=false |
| 长任务软删后子任务仍可见 |
只软删目标、忘记级联子任务,今日事项仍出现旧子任务 |
确认后软删除长任务必须同事务调用「级联软删长任务子任务」;任一步失败整单回滚 |
update_goal 变更范围不透明 |
AI 额外加入用户未要求的普通字段、宏观规划或简洁复盘摘要;组合修改未完整展示 |
payload 只允许 long_goal_id 和白名单 changes;确认卡片逐项展示全部差异;hash 覆盖完整 payload;组合修改同事务执行 |
| 简洁复盘误存完整报告 |
review_summary 过长、包含完整报告,或覆盖用户未确认的旧摘要 |
限制为不超过 500 字;写入前展示新旧摘要差异并确认;只保存最新摘要,不保存完整报告或历史版本 |
| 运行摘要泄露隐私 |
把完整 Prompt、模型响应或敏感原文写入业务库 |
agent_run_records 只保存组件、函数、状态、错误码、时间和链路 ID;完整调用链交给 LangSmith |
| 数据库权限过大 |
应用账号绕过全局数据模块直接改表 |
部署时限制运行账号,不授予核心业务表直接 INSERT/UPDATE/DELETE 权限 |
1. 模块职责说明
成员3负责两个公共基础模块:全局数据模块、系统日志模块。核心边界是“数据库事实由成员3统一读写,AI 推理和前端确认卡片不放进成员3”。
users、long_goals、task_items、feedback_records、conversation_messages、write_requests、operation_confirmations、replan_proposals、replan_proposal_changes、replan_applications、user_profiles、task_profile_observations、task_profile_snapshotsagent_run_records统一约束:
is_confirmed = true当作写入凭证;必须使用write_requests+operation_confirmations+payload_hash。is_deleted和deleted_at。applied必须在同一个事务中完成;任一步失败都先回滚,再使用独立短事务将请求标记为failed。系统日志模块只记录 Agent 运行摘要,不参与业务写入事务。user_id做越权查询。conversation_messages;媒体二进制不进库,只存 OSS 返回的source_url。2. 事务校验与软删除
2.1 事务校验
事务校验不是提前执行一次的普通查询,而是“事务校验并应用写入”内部不可跳过的步骤。公共数据模块必须按以下顺序执行:
成功路径中,业务写入和
write_requests.status=applied必须一起提交。任一步失败都先ROLLBACK,不得留下部分业务数据。回滚完成后,另开一个短事务将请求标记为failed。幂等键用于阻止同一写入请求被重复执行;前端传入的单独布尔值不能替代确认记录。assert_confirmed_write只解决确认状态、用户归属、精确载荷和过期时间;它不替代身份认证、业务白名单和目标版本校验。2.2 时间范围查询规则
以下规则是成员 3 对 Wiki“按时间范围查询”要求的字段级补充,所有事项时间范围查询必须复用同一谓词。查询窗口统一使用左闭右开区间
[from_time, to_time):schedule按日程区间与查询窗口重叠匹配:start_at < to_time AND end_at > from_time。todo/subtask按截止时间落入窗口匹配:due_at >= from_time AND due_at < to_time。due_at IS NULL的待办或子任务不属于任何确定时间窗口,因此在传入时间范围时排除;不带时间范围的全量查询仍可返回。users.timezone将本地日期换算成 UTC 起止时刻,再应用同一谓词,不能直接按数据库会话时区截取日期。2.3 软删除
事项和长任务禁止物理删除。确认删除后只更新
is_deleted=true、deleted_at=now(),并将version加一。删除前必须校验用户归属、未删除状态和base_version;重复删除、越权或版本冲突均应拒绝并回滚。普通查询默认附带
is_deleted=false,但已删除记录仍保留主键及其关联反馈,保证既有业务事实可以追溯。长任务与子任务策略:
delete_goal写入请求时,由服务端读取当前全部未软删子任务,将每个item_id + expected_item_version写入 payload 的cascade_subtasks;该完整 payload 参与payload_hash,确认卡片展示级联数量和明细。cascade_subtasks完全一致,才在同一事务内软删除长任务和清单内子任务。确认后新增、删除、改版或改变归属的任一子任务都会触发版本冲突并整单回滚。is_deleted=true、deleted_at=now()、version+1。feedback_records关联仍保留,仅对普通查询不可见(默认is_deleted=false即可过滤),无需再靠 JOIN 父目标判断可见性。ON DELETE物理级联;不在 MVP 引入单独的数据库软删触发器(避免与确认写入路径分叉)。2.4 工作流记录与业务事实
task_items、long_goals、feedback_records、user_profiles、task_profile_snapshots的创建/更新/软删除write_requests、replan_proposals、replan_proposal_changesconversation_messages、task_profile_observations、agent_run_records重排方案可在确认前保存;真正修改事项必须通过
write_requests.action = apply(兼容历史枚举apply_replan)并完成确认。2.5 复盘数据查询边界
复盘不查询历史完整报告,而是在用户发起复盘时实时读取已经落库的业务事实:事项来自
task_items,执行反馈来自feedback_records,关联长任务来自long_goals。复盘 Agent 生成的完整报告只返回前端展示,不写入数据库;从报告中提炼的长任务简洁复盘摘要可以作为成员 3 的补充业务字段long_goals.review_summary保存。查询步骤:
user_id、from_time、to_time和可选goal_id查询时间范围内未软删除的事项;日程按区间重叠,待办/子任务按due_at落入[from_time, to_time),无截止时间的事项不进入本次复盘数据集。feedback_records;同一事项允许返回多条不可变反馈。long_goal_id查询未软删除的关联长任务;传入goal_id时只返回该目标范围内的数据。ReviewDataResponse(items, feedbacks, goals),交给母 AI 编排模块,再传给复盘 Agent。review_summary候选;完整报告只展示,摘要写入候选必须走action=update_goal的确认链,应用后覆盖该长任务的最新摘要,不保存摘要历史版本。MVP 只返回复盘原始数据集,不在全局数据模块计算完成率;允许额外保存长任务最新简洁复盘摘要,但不保存完整报告或摘要历史。若后续需要结构化统计,必须先明确多次反馈、部分完成和无反馈事项的计算规则,再扩展独立统计 DTO。
2.6
update_goalpayload 契约(成员 3 补充)Wiki 和数据库只固定
action + payload外壳;以下字段级结构是成员 3 为避免普通字段、宏观规划与简洁复盘摘要修改歧义而补充的契约。action=update_goal时,修改内容全部放入payload,允许以下四种结构:long_goal_id、changes。changes只包含plan_overview。changes只包含review_summary。changes同时包含普通字段、plan_overview或review_summary中的多项,用于用户明确要求一次修改多项内容。changes只允许title、description、plan_overview、review_summary、start_at、deadline_at、status,且至少包含一个字段;review_summary为空白或超过 500 字时拒绝;未知字段或空修改也应拒绝。四种结构都使用同一个
write_action=update_goal。目标的base_version使用write_requests.base_version顶层字段承载,不在 payload 内重复。完整payload由数据库生成payload_hash,确认卡片必须展示全部变更;组合修改在同一个事务中一次完成,任一字段失败则整体回滚,成功后version只递增一次。3. 前后端 API 表
说明:
user_id仅作文档字段说明;实现时必须从登录态注入,忽略或拒绝客户端伪造值。GET/api/items/todaydate(登录态推导user_id)items: list[TaskItemDTO]task_items、users.timezonedue_at部分索引[from_time, to_time);日程按区间重叠,待办/子任务按due_at落入窗口;默认排除软删和无截止时间事项GET/api/items/{item_id}item_iditem: TaskItemDTOtask_itemsitem_id限定归属;不存在或越权分别返回 404 / 403GET/api/goalsstatus?(登录态推导user_id)goals: list[LongGoalDTO]long_goalsupdated_at DESC返回GET/api/goals/{goal_id}goal_idgoal: LongGoalDTO、items: list[TaskItemDTO]long_goals、task_itemsitem_type=subtask子任务列表;plan_overview仅展示POST/api/write-requestsWriteRequestDraft(无前端伪造确认字段)WriteRequestDTOwrite_requestsaction + payload,此时不改业务事实POST/api/confirmationswrite_request_id、payload_hash、decision、client_event_id?ConfirmWriteResponsewrite_requests、operation_confirmationsPOST/api/write-requests/{write_request_id}/applywrite_request_id、payload_hashApplyConfirmedWriteResponsewrite_requestsAI 对话主链路本身不额外增加成员3专属聊天 API;对话入口由母 AI 编排模块承接,本模块只提供其调用的查询与落盘函数。
长任务简洁复盘摘要不新增独立 HTTP 接口:母 AI 将
review_summary放入action=update_goal的changes,经确认后写回当前长任务;查询长任务列表、详情和复盘关联数据时随LongGoalDTO返回。完整复盘报告仍只展示,不写入数据库。4. 模块对外函数表
user_id、from_time?、to_time?、item_types?、status?、include_deleted=falseitems: list[TaskItemDTO]task_itemsdue_at部分索引[from_time,to_time):日程按start_at < to_time AND end_at > from_time,待办/子任务按due_at >= from_time AND due_at < to_time,无截止时间者排除;默认is_deleted=falseuser_id、item_iditem: TaskItemDTOtask_itemsuser_id + item_id限定归属;只返回未软删除事项;不做指代推理user_id、status?、include_deleted=falsegoals: list[LongGoalDTO]long_goalsupdated_at DESC排序;include_deleted=true仅供恢复管理内部调用user_id、goal_idgoal: LongGoalDTO、items: list[TaskItemDTO]long_goals、task_itemsplan_overview和子任务事实;母 AI 再把结果传给子 Agentuser_idprofile: UserProfileDTO or Noneuser_profilesuser_id、long_goal_idobservations: list[TaskProfileObservationDTO]、current_snapshot: TaskProfileSnapshotDTO or Nonetask_profile_observations、task_profile_snapshotsuser_id、from_time、to_time、item_types?candidates: list[CandidateItemDTO]task_itemsdue_at部分索引due_at落入[from_time,to_time);默认排除软删和无截止时间事项,再交给反馈 Agentuser_id、from_time、to_time、review_type?、goal_id?ReviewDataResponse,含items、feedbacks、goalstask_items、feedback_records、long_goalsdue_at部分索引review_summary;不计算完成率user_id、limit=20messages: list[ConversationMessageDTO]conversation_messagesmessage_index倒序取最近 N 条,再正序返回;支撑“最近 20 条对话 + 当前请求数据库事实”SaveConversationMessageRequestConversationMessageDTOconversation_messagesmessage_index冲突、modality与source_url不一致、用户不存在时拒绝source_url;不存媒体二进制;不需要用户确认user_id、proposal_idReplanProposalDTO、changes: list[ReplanChangeDTO]replan_proposals、replan_proposal_changesuser_id、item_idowned: booltask_itemsowned=false或明确错误码user_id、item_idexists: booltask_itemsis_deleted=falseuser_id、candidate_conditionunique_target/candidates/nonetask_itemsuser_id、write_request_id、payload_hashallowed: bool、拒绝原因write_requests、operation_confirmations、目标表assert_confirmed_write+ 归属 + 版本 + 白名单预检;真正写入仍走事务入口WriteRequestDraftWriteRequestDTOwrite_requestsSaveReplanProposalRequestReplanProposalDTOreplan_proposals、replan_proposal_changesexpected_item_version(update/delete)时拒绝changes使用ReplanChangeDraft(无 id/proposal_id);模块根据input_snapshot生成input_snapshot_hash,调用方不得伪造;确认前可保存,真正改事项必须再走applyAppendTaskProfileObservationRequestTaskProfileObservationDTOtask_profile_observationsConfirmWriteRequestConfirmWriteResponsewrite_requests、operation_confirmationspayload_hash不一致、重复确认时返回错误user_id、write_request_id、payload_hashApplyResultwrite_requests、operation_confirmations、目标业务表action分派到具体确认后写入函数;业务写入与请求状态更新同事务user_id、write_request_id、payload_hash;payload 含title、description?、start_at?、deadline_at?ApplyResult,含新增long_goal_idwrite_requests、operation_confirmations、long_goalscreate_goaluser_id、write_request_id、payload_hash;action=update_goal;payload 含long_goal_id、非空changes;请求顶层base_version必填ApplyResultwrite_requests、operation_confirmations、long_goalschanges可同时包含普通字段与plan_overview;完整变更一次确认并在同一事务执行,成功后版本只递增一次user_id、write_request_id、payload_hash;payload 含long_goal_id、cascade_subtasks: list[{item_id, expected_item_version}];请求顶层base_version必填ApplyResult,含实际级联清单与数量write_requests、operation_confirmations、long_goals、task_itemsuser_id、write_request_id、payload_hash;payload 含item_type、title、start_at?、end_at?、due_at?、long_goal_id?ApplyResult,含新增item_idwrite_requests、operation_confirmations、task_itemsuser_id、write_request_id、payload_hash;payload 含item_id、changes;请求顶层base_version必填ApplyResultwrite_requests、operation_confirmations、task_itemsversionuser_id、write_request_id、payload_hash;payload 含item_id;请求顶层base_version必填ApplyResultwrite_requests、operation_confirmations、task_itemsuser_id、write_request_id、payload_hash;payload 含item_id、execution_status、raw_feedback、normalized_feedback、occurred_at、duration_minutes?ApplyResult,含feedback_idwrite_requests、operation_confirmations、feedback_records、task_itemstask_items.statususer_id、write_request_id、payload_hash;payload 含profile_data、source;如需乐观锁,使用请求顶层base_versionApplyResultwrite_requests、operation_confirmations、user_profilessource限user_form/user_explicit_inputuser_id、write_request_id、payload_hash;payload 含long_goal_id、profile_summary、versionApplyResult,含snapshot_idwrite_requests、operation_confirmations、task_profile_snapshotsis_current=falseuser_id、write_request_id、payload_hash;action=update_goal;payload 含long_goal_id、changes.plan_overview;请求顶层base_version必填ApplyResultwrite_requests、operation_confirmations、long_goalschanges.plan_overview;若还包含普通字段,由「确认后修改长任务」按组合 payload 同事务处理;可执行任务仍来自task_items(item_type=subtask)user_id、write_request_id、payload_hash;payload 含proposal_id;action=apply(兼容apply_replan)ApplyResult,含application_idreplan_proposals、replan_proposal_changes、replan_applications、task_itemssort_order应用全部变更,写入replan_applications,并校验每条expected_item_versionStartAgentRunRequestagent_run_idagent_run_recordsFinishAgentRunRequestok: boolagent_run_records说明:
review_summary需经确认后单独写回long_goals。write_action=update_goal;payload 可只含其中一类,也可在用户明确要求时组合多类,所有字段必须通过白名单并完整展示在同一确认卡片中。5. 模块依赖函数表
本表只填写本模块主动依赖的其他模块能力,不填写「谁依赖本模块」。被依赖关系见第 4 节对外函数表的「调用方」列。
business_user_id?user_id、用户状态user_idtrace_id(可选)trace_idtrace_id时仍可写入运行摘要,但无法跳转完整调用链6. 模块内部函数表
date、from_time、to_time、用户时区[from_time,to_time);校验开始时间小于结束时间;日程使用start_at < to_time AND end_at > from_time,待办/子任务使用due_at >= from_time AND due_at < to_timeusers.timezone、task_itemsReviewDataResponseuser_id、标准化时间范围、goal_id?items、feedbacks、goalstask_items、feedback_records、long_goalsTaskItemDTO、LongGoalDTOtask_items、long_goalsis_deleted给普通只读页;内部校验仍使用该字段action、payloadupdate_goal要求long_goal_id和非空changes,字段使用长任务白名单;delete_goal要求long_goal_id和完整cascade_subtasks条目;禁止外部传入表名或任意 SQL 字段write_action枚举user_idmax(message_index)+1;调用方提供序号时校验唯一conversation_messages(user_id, message_index)唯一;不能用无锁的简单 max+1 保证并发安全write_requests插入user_id、long_goal_id、base_versionitem_id排序的cascade_subtasks(含各自版本);目标或版本不匹配时拒绝创建请求delete_goalpayloadlong_goals、task_itemsWriteRequestDraftwrite_requests,由数据库触发器根据完整 payload 生成payload_hash,设置数据库默认过期时间和幂等约束WriteRequestDTOwrite_requestsuser_id、write_request_id、payload_hashassert_confirmed_writewrite_requests、operation_confirmationstarget_type、target_id、base_versionuser_id + id + version + is_deleted=false检查目标;长任务删除另锁定并逐项比对 payload 中每个cascade_subtasks.expected_item_versiontask_items、long_goals等expected_item_versionaction与 payload 白名单分派 create/update/delete/feedback/profile/apply;update_goal直接应用changes,delete_goal应用完整级联清单target_type、target_id、base_versionis_deleted=true、deleted_at=now()、version+1task_items、long_goalsuser_id、long_goal_id、cascade_subtasksFOR UPDATE锁定当前未软删子任务;要求当前 ID/版本集合与确认 payload 完全一致;逐项更新清单内子任务task_itemsfeedback_records;父目标锁阻止并发绕过确认范围proposal_id、确认请求sort_order依次 create/update/soft-delete,并写replan_applicationsreplan_*、task_itemsApplyResultapplied;失败路径先回滚,再开短事务更新为failedApplyResult或错误write_requestsagent_run_records,状态默认startedagent_run_idagent_run_recordsagent_run_id、status、error_code?finished_atok: boolagent_run_records7. Python 数据结构声明
以下结构用于对齐接口字段,不要求作为独立 Python 文件提交。
8. 数据库查缺补漏表
对照《架构设计MVP阶段数据库设计初稿》逐项检查。结论:核心业务表、确认链路、软删除、重排工作流、画像双表和 Agent 运行摘要表已具备;当前剩余事项主要是成员 3 的实现约定与事务边界,不是 Wiki 或数据库缺表缺字段。
task_items时间字段;users.timezone;task_items_user_time_idx、task_items_user_due_idxdate + timezone推导当天范围due_at部分索引;默认is_deleted=false即可排除已级联软删的子任务task_items;task_items_user_time_idx;成员 3 统一时间谓词due_at窗口谓词;实现迁移新增(user_id, due_at)部分索引(仅 todo/subtask 且未软删)task_items;(user_id, id)复合唯一user_id;已软删返回 404long_goals;long_goals_user_status_idxlist_goals(user_id, status?, include_deleted=false)和/api/goals,按updated_at DESC返回long_goals;task_items_goal_idxlong_goal_id归属,不设计父子树user_profilestask_profile_observations、task_profile_snapshotsis_current=true快照task_itemsdue_at;实现迁移新增(user_id, due_at)部分索引task_items、feedback_records、long_goalsdue_at落窗筛选;无数据返回空列表;完整复盘报告不入库,目标可返回已保存的review_summarysource_urlconversation_messages;conversation_messages_window_idxmessage_index倒序取、正序返回;媒体二进制不进库conversation_messages及 modality/source_url 一致性约束replan_proposals、replan_proposal_changesexpected_item_versionwrite_requests;触发器根据完整payload生成payload_hash;(user_id, idempotency_key)唯一payload_hash可推导;过期时间由数据库默认值生成action + payload,再保存候选请求;update_goal使用long_goal_id + changesreplan_proposals、replan_proposal_changesinput_snapshot_hash由输入快照推导ReplanChangeDraft;模块生成并保存input_snapshot_hash;确认前可写工作流表;真正改事项必须再走applytask_profile_observationsoperation_confirmations;write_request_id唯一assert_confirmed_write+ 目标表 +write_requestsapplied同事务提交;失败先回滚,再开短事务标记请求failedtask_items及关系触发器long_goals、task_itemsdelete_goal应用时锁定目标和当前子任务,要求集合/版本与确认 payload 完全一致;同事务软删下属 subtask;不物理删除,反馈外键仍有效feedback_recordstask_items.statususer_profiles;profile_source枚举user_form/user_explicit_inputtask_profile_snapshotsis_current=false;建议应用层同事务处理plan_overview、version;可选同时修改普通长任务字段long_goals.plan_overview、长任务普通字段update_goal;组合修改一次确认、同事务执行、版本只递增一次replan_*+task_itemsproposal_id;新接口用action=apply,兼容apply_replantask_items、write_requests、operation_confirmationsagent_run_recordslong_goal_id、review_summary、base_versionlong_goals尚无review_summarylong_goals增加可空review_summary文本字段及 500 字限制;通过update_goal确认写入,只保留最新摘要8.1 长任务简洁复盘字段(成员 3 补充)
long_goals.review_summary是成员 3 针对“长任务保留一条简洁复盘”的新增字段级契约,不是三份 Wiki 已定义的固定字段。字段允许为空,最多 500 字;每个长任务只保留最新摘要,更新时覆盖旧值,不保存完整复盘报告和摘要历史。该字段属于长任务业务事实,写入必须使用现有
action=update_goal、changes.review_summary、base_version和用户确认链。数据库设计落地时需在long_goals增加可空文本字段及长度/非空校验,并在LongGoalDTO、长任务详情/列表和复盘关联数据中返回;三份 Wiki 原文保持不变。9. 风险说明
is_confirmed=true就直接写入业务表write_request_id、operation_confirmations、payload_hash、过期时间和用户归属user_id读数据base_version;重排变更带expected_item_version;冲突时返回version_conflictoperation_confirmations.write_request_id唯一;write_requests.idempotency_key对同一用户唯一;已应用请求不可再次应用deleted_at或version;普通查询仍返回已删除对象;误删关联反馈is_deleted=true、deleted_at和version,不物理删除业务对象,也不修改关联反馈;普通查询默认过滤is_deleted=falseupdate_goal变更范围不透明long_goal_id和白名单changes;确认卡片逐项展示全部差异;hash 覆盖完整 payload;组合修改同事务执行review_summary过长、包含完整报告,或覆盖用户未确认的旧摘要agent_run_records只保存组件、函数、状态、错误码、时间和链路 ID;完整调用链交给 LangSmithINSERT/UPDATE/DELETE权限