Projects & Studies
1. 目标 & 范围
本模块覆盖研究人员在 AgentSurvey 中组织与管理研究任务的核心操作:
- Project:同一研究主题下多个 Study 的逻辑容器,承载研究背景与默认语言配置。
- Study:单次具体研究任务;包含 Research Brief、目标(Objectives)、Agent 行为、工具集、输出 Schema 等全部配置。
- Study Version:每次发布或手动保存时生成的配置快照;Session 绑定具体 Version,确保历史解释不被新配置覆盖。
- 状态机:
draft → published → archived,及取消发布(published → draft)。
- 发布:生成
public_slug 与公开访谈链接;受访者凭链接进入访谈。
不在本模块范围内:Study Builder 详细配置界面(见 03_study_builder);Session 运行时(见 04_interview_runtime);结构化抽取(见 06_extraction_evidence);Auth & Workspace(见 01_auth_workspace)。
2. 用户故事
researcher(研究人员)
- 作为研究人员,我希望创建 Project 并填写研究背景,以便把同主题的多个 Study 归组管理。
- 作为研究人员,我希望在 Project 下创建多个 Study,以便对同一主题进行多轮或多维访谈。
- 作为研究人员,我希望编辑 Study 的 Research Brief、语言、时长、轮数上限等字段,以便精细控制访谈范围。
- 作为研究人员,我希望发布 Study 并获得公开链接,以便将链接分享给受访者。
- 作为研究人员,我希望取消发布已发布的 Study,以便在配置有误时临时下线。
- 作为研究人员,我希望归档不再需要的 Study,以便保持工作区整洁且历史数据不丢失。
- 作为研究人员,我希望查看 Study 的版本历史,以便了解每次发布时的配置快照。
- 作为研究人员,我希望在迭代配置后发布新版本,而旧 Session 仍引用旧版本,以便跨版本对比分析。
3. 功能需求
Project CRUD
| 编号 | 优先级 | 描述 | 验收要点 |
|---|
| FR-02-1 | P0 | 创建 Project | 提交 name(必填)、description(可选)、research_context(可选)、default_language(默认 zh-CN)后,生成 Project 记录;workspace_id 从当前 Workspace 上下文注入 |
| FR-02-2 | P0 | 列出 Project | 返回当前 Workspace 下所有 Project;支持按 name 模糊搜索;按 created_at 降序 |
| FR-02-3 | P0 | 查看 Project 详情 | 返回 Project 基本字段及其下 Study 列表(id、name、status) |
| FR-02-4 | P0 | 编辑 Project | 可更新 name、description、research_context、default_language;workspace_id 不可修改 |
| FR-02-5 | P0 | 删除 Project | 仅允许删除无任何 Study的 Project;否则返回 409 Conflict |
Study CRUD
| 编号 | 优先级 | 描述 | 验收要点 |
|---|
| FR-02-6 | P0 | 创建 Study | 在指定 Project 下创建 Study,初始状态为 draft;name 必填,其余字段可留空后续在 Study Builder 补填 |
| FR-02-7 | P0 | 列出 Study | 返回指定 Project 下所有 Study;支持按 status 过滤 |
| FR-02-8 | P0 | 查看 Study 详情 | 返回 Study 基本字段 + active_version_id + public_slug(若已发布) |
| FR-02-9 | P0 | 更新 Study 基本信息 | 可更新 name、description;其余配置(research_brief、objectives 等)通过 PUT /studies/{id}/config 更新(见 FR-02-10) |
| FR-02-10 | P0 | 更新 Study 配置 | 通过 PUT /api/studies/{study_id}/config 写入 research_brief、objectives、enabled_tools、output_schema_id、agent_config_id;仅 draft 状态允许直接覆盖;published 状态下变更会在下次发布时生效 |
| FR-02-11 | P0 | 删除 Study | 仅允许删除无任何 Session 的 Study;否则返回 409 Conflict |
Study 状态机
| 编号 | 优先级 | 描述 | 验收要点 |
|---|
| FR-02-12 | P0 | 初始状态为 draft | 新建 Study 的 status = draft,active_version_id = null,public_slug = null |
| FR-02-13 | P0 | draft → published(发布) | 触发条件:研究人员调用 POST /api/studies/{id}/publish;系统创建新 Study Version 快照、设置 active_version_id、生成 public_slug、更新 status = published;发布失败时回滚所有变更 |
| FR-02-14 | P0 | published → draft(取消发布) | 触发条件:调用 POST /api/studies/{id}/unpublish;清空 public_slug(链接立即失效)、保留 Version 历史、active_version_id 保留指向最后一次版本(仅用于查看历史,不可继续收集 Session) |
| FR-02-15 | P0 | draft / published → archived(归档) | 触发条件:调用 POST /api/studies/{id}/archive;published Study 归档前自动取消发布(public_slug 清空);archived 状态不可再编辑、不可发布、不可收集新 Session;历史 Session 数据保留可查 |
| FR-02-16 | P0 | 禁止非法状态跳转 | archived → draft / published 不允许;违规操作返回 422 Unprocessable Entity + 明确错误信息 |
状态机摘要:
draft ──publish──> published
draft <──unpublish── published
draft ──archive──> archived
published ──archive──> archived (隐式先 unpublish)
Study Version 版本化
| 编号 | 优先级 | 描述 | 验收要点 |
|---|
| FR-02-17 | P0 | 发布时创建版本快照 | 每次 publish 操作生成一条 study_versions 记录;version_number 自增;快照内容包括:research_brief、objectives、interview_guide、agent_config_version_id、output_schema_version_id、enabled_tool_ids、kb_version_refs |
| FR-02-18 | P0 | 版本不可变 | study_versions 记录创建后不得修改;如需更改配置须发布新版本 |
| FR-02-19 | P0 | Session 绑定具体版本 | 新建 Session 时系统自动将 sessions.study_version_id 设为发布时的 active_version_id;Session 启动后不随后续发布改变绑定关系 |
| FR-02-20 | P0 | 查看版本历史 | 提供 GET /api/studies/{id}/versions 列表接口;返回版本号、创建时间、创建人 |
| FR-02-21 | P1 | 版本 diff | 可比较两个版本间配置差异(research_brief、objectives 字段层级) |
发布与公开链接
| 编号 | 优先级 | 描述 | 验收要点 |
|---|
| FR-02-22 | P0 | 生成 public_slug | 发布时自动生成全局唯一的 public_slug(建议 8-12 位 URL 安全字符串);写入 studies.public_slug |
| FR-02-23 | P0 | 公开链接格式 | 公开链接为 https://<host>/interview/<public_slug>;返回于 publish 响应体 public_url 字段 |
| FR-02-24 | P0 | 链接有效性 | published 状态链接可访问、可创建 Session;draft / archived 状态或取消发布后链接返回 404 |
4. 关键流程
4.1 创建 Project 与首个 Study
参考 02_user_flows Flow 1 & Flow 2:
-> 填写 name / description / research_context / default_language
-> POST /api/projects [创建 Project]
-> Project 详情页 -> New Study
-> POST /api/projects/{id}/studies [创建 Study, status=draft]
-> 进入 Study Builder 完善配置(见 03_study_builder)
4.2 发布 Study
-> POST /api/studies/{id}/publish
系统: 校验配置完整性(name 非空、至少一个 objective)
系统: 生成 study_versions 快照 (version_number++)
系统: 设置 active_version_id = 新版本 id
-> 返回 { public_url, public_slug, status }
4.3 版本迭代
参考 02_user_flows Flow 9:
-> 修改 objectives / agent config / output schema
-> PUT /api/studies/{id}/config(draft 缓存,不影响当前 active_version)
-> 再次 POST /api/studies/{id}/publish
系统: 生成新 study_versions 快照(version_number++ = 2)
系统: 更新 active_version_id = 新版本 id
-> 新 Session 绑定 version 2
-> 历史 Session 仍引用 version 1
5. 数据
涉及实体引用自 03_data_model:
projects 表(核心字段)
| 字段 | 类型 | 说明 |
|---|
id | UUID | 主键 |
workspace_id | UUID FK | 所属 Workspace |
name | TEXT NOT NULL | 项目名称 |
description | TEXT | 项目描述 |
research_context | TEXT | 研究背景(等价于 user_flows 的 business_context) |
default_language | TEXT | 默认语言,如 zh-CN |
status | TEXT | active(默认) |
studies 表(核心字段)
| 字段 | 类型 | 说明 |
|---|
id | UUID | 主键 |
project_id | UUID FK | 所属 Project |
name | TEXT NOT NULL | Study 名称 |
description | TEXT | 描述 |
status | TEXT | draft / published / archived |
active_version_id | UUID | 当前生效的版本 ID,发布后写入 |
public_slug | TEXT UNIQUE | 公开链接标识,仅 published 时非空 |
study_versions 表(核心字段)
| 字段 | 类型 | 说明 |
|---|
id | UUID | 主键 |
study_id | UUID FK | 所属 Study |
version_number | INTEGER | 自增版本号 |
research_brief | JSONB | 研究摘要快照(包含 target_participants、language、max_duration、max_turns 等) |
objectives | JSONB | 目标列表快照 |
agent_config_version_id | UUID | Agent 配置版本引用(不可变) |
output_schema_version_id | UUID | 输出 Schema 版本引用(不可变) |
enabled_tool_ids | JSONB | 启用工具 ID 列表快照 |
created_by | UUID | 发布操作人 |
created_at | TIMESTAMPTZ | 创建时间(不可变) |
版本不可变原则:study_versions 行创建后只读;后续配置变更须触发新的发布操作以创建新行。
6. 接口
涉及端点引用自 02_api_contracts:
| 方法 | 路径 | 说明 |
|---|
POST | /api/projects | 创建 Project |
GET | /api/projects | 列出 Project |
GET | /api/projects/{project_id} | 查看 Project 详情 |
PUT | /api/projects/{project_id} | 编辑 Project |
DELETE | /api/projects/{project_id} | 删除 Project(无 Study 时) |
POST | /api/projects/{project_id}/studies | 创建 Study |
GET | /api/projects/{project_id}/studies | 列出 Study |
GET | /api/studies/{study_id} | 查看 Study 详情 |
PUT | /api/studies/{study_id} | 编辑 Study 基本信息 |
PUT | /api/studies/{study_id}/config | 更新 Study 配置(进入 draft 暂存区) |
DELETE | /api/studies/{study_id} | 删除 Study(无 Session 时) |
POST | /api/studies/{study_id}/publish | 发布:创建 Version 快照 + 生成 slug |
POST | /api/studies/{study_id}/unpublish | 取消发布:清空 slug,状态回 draft |
POST | /api/studies/{study_id}/archive | 归档(含隐式 unpublish) |
GET | /api/studies/{study_id}/versions | 查看版本历史列表 |
GET | /api/studies/{study_id}/versions/{version_id} | 查看指定版本快照详情 |
公开端点(无需鉴权):
| 方法 | 路径 | 说明 |
|---|
POST | /api/public/studies/{public_slug}/sessions | 受访者凭 slug 创建 Session |
7. 验收标准
Project CRUD
- AC-02-01:
POST /api/projects 传入合法 name 后,返回 201 及新建 Project 的 id、created_at;数据库记录 workspace_id 正确。
- AC-02-02:
name 为空时 POST /api/projects 返回 422。
- AC-02-03:
GET /api/projects 仅返回当前 Workspace 下的 Project,不泄露其他 Workspace 数据。
- AC-02-04:
DELETE /api/projects/{id} 在 Project 下存在任意 Study 时返回 409,Project 不被删除。
- AC-02-05:
DELETE /api/projects/{id} 在 Project 无 Study 时返回 204,数据库记录消失。
Study CRUD
- AC-02-06:
POST /api/projects/{project_id}/studies 创建后 studies.status = draft,active_version_id = null,public_slug = null。
- AC-02-07:
GET /api/projects/{project_id}/studies?status=published 只返回已发布 Study。
- AC-02-08:
DELETE /api/studies/{id} 在 Study 存在至少一个 Session 时返回 409。
状态机
- AC-02-09:新建 Study 初始
status = draft,调用 publish 后 status = published,public_slug 非空。
- AC-02-10:
unpublish 后 public_slug = null,status = draft;此前 public_slug 对应的公开链接返回 404。
- AC-02-11:
archive 后 status = archived;若之前为 published,public_slug 同时清空。
- AC-02-12:对
archived Study 调用 publish 或 unpublish 返回 422,状态不变。
- AC-02-13:
archived Study 下不接受新 POST /api/public/studies/{slug}/sessions(即使曾有 slug,也已清空返回 404)。
版本快照
- AC-02-14:每次
publish 在 study_versions 表生成一条新记录;version_number 单调递增;已有版本记录不被修改。
- AC-02-15:新创建的 Session 的
study_version_id 等于 publish 时写入的 active_version_id。
- AC-02-16:对已有 Session 的历史版本 Study 执行再次
publish(生成 version 2)后,旧 Session 的 study_version_id 仍指向 version 1。
- AC-02-17:
GET /api/studies/{id}/versions/{version_id} 返回该版本的完整 research_brief、objectives、enabled_tool_ids 等字段;任意字段不为 null(发布时未配置的字段以空值快照)。
发布链接
- AC-02-18:
public_slug 在所有 Study 中全局唯一(数据库唯一约束);重复则重试生成。
- AC-02-19:
publish 响应体包含 public_url、public_slug、status = published。
- AC-02-20:受访者通过
POST /api/public/studies/{public_slug}/sessions 成功创建 Session 后,sessions.study_version_id 等于当前 active_version_id。
8. 边界 & 非目标
- 不在本模块:Study 内部 objectives、interview guide、output schema 字段的详细配置界面 → 见 03_study_builder。
- 不在本模块:Session 运行时行为、AG-UI 事件流 → 见 04_interview_runtime。
- 不在本模块:结构化字段抽取与 Evidence 链 → 见 06_extraction_evidence。
- 不在本模块:知识库(KB)管理 → 见 [08_knowledge_base](P1)。
- 不做(MVP):Project / Study 级别的多人协作权限(Owner / Editor / Viewer 分离)。
- 不做(MVP):Study 的定时发布 / 定时归档。
- 不做(MVP):跨 Workspace 复制 Project 或 Study。
- 版本回滚:暂不支持将
active_version_id 手动回退到历史版本(避免 Session 绑定逻辑复杂化)。
9. 依赖 & 风险
依赖
风险
| 风险 | 影响 | 缓解措施 |
|---|
publish 操作非原子(Version 快照写入与 active_version_id 更新之间宕机) | Session 绑定错误版本 | 使用数据库事务包裹:Version 插入 + Study 字段更新在同一事务中提交 |
public_slug 碰撞 | 发布失败或链接覆盖 | 数据库唯一约束 + 后端生成冲突时最多重试 3 次;重试耗尽返回 500 |
| 归档后历史 Session 数据访问 | 研究人员误以为数据丢失 | 归档仅改变 Study 状态,不删除任何 Session / Version 数据;UI 展示「已归档,数据只读」提示 |
| Study 配置不完整时发布 | Agent 启动无有效 objective | 发布前校验:objectives 非空、name 非空;否则返回 422 + 具体缺失字段列表 |