Skip to content

Auth & Workspace

Auth & Workspace

1. 目标 & 范围

目标:提供最小可用的多租户认证与 Workspace 管理能力,确保不同团队的研究数据严格隔离,并支持匿名受访者通过公开链接参与访谈。

在范围内(P0 MVP)

  • 用户注册、登录与会话认证(邮箱+密码)
  • Workspace 创建与基本 CRUD
  • Workspace 成员邀请与角色分配(researcher / admin
  • 跨 Workspace 数据隔离(所有业务对象归属 workspace)
  • Participant 匿名访问——通过 public_slug 无需登录进入访谈
  • Participant 记录创建与匿名标识

不在范围内(列入非目标)

  • SSO / OAuth 第三方登录
  • 复杂多团队分级权限(跨 Workspace 共享角色)
  • Viewer 只读角色(P1 可扩展)
  • 细粒度 Project 级权限覆盖(P1)
  • SAML / SCIM 企业目录同步

2. 用户故事

researcher

  • 作为 researcher,我希望用邮箱注册并创建 Workspace,以便开始管理研究项目。
  • 作为 researcher,我希望邀请同事加入 Workspace 并分配角色,以便团队协作。
  • 作为 researcher,我希望在 Workspace 内创建的 Projects 和 Studies 对其他 Workspace 不可见,以便保护研究数据安全。

admin

  • 作为 admin,我希望能修改 Workspace 名称、管理成员(含移除),以便维护租户配置。
  • 作为 admin,我希望查看成员列表及其角色,以便审计权限状态。
  • 作为 admin,我希望所有关键操作都写入审计日志,以便事后追溯。

participant(受访者)

  • 作为 participant,我希望通过 public link 直接进入访谈,无需注册账号,以便降低参与门槛。
  • 作为 participant,我希望在访谈开始前看到数据使用说明与退出方式,以便知情同意。
  • 作为 participant,我希望自己的身份在 Workspace 内用匿名 ID 标识,以便保护隐私。

3. 功能需求

3.1 认证

编号优先级描述验收要点
FR-01-01P0邮箱+密码注册邮箱格式校验;密码强度不低于 8 位含字母+数字;同一邮箱不可重复注册(返回 409);注册后自动登录并颁发会话 token
FR-01-02P0邮箱+密码登录凭证错误返回 401(不区分邮箱/密码哪个错);连续失败 5 次触发 30 秒冷却;登录成功颁发 JWT(含 user_idworkspace_id 列表、exp
FR-01-03P0会话 token 刷新access token 有效期 15 分钟;refresh token 有效期 7 天;刷新端点在 access token 过期后仍可用;refresh token 单次消费(rotation)
FR-01-04P0登出服务端使 refresh token 失效;前端清除本地存储 token
FR-01-05P0密码重置发送重置邮件(含带时效签名链接,有效期 1 小时);重置后所有已有 session 失效

3.2 Workspace 管理

编号优先级描述验收要点
FR-01-06P0创建 Workspace注册流程后自动提示创建或加入 Workspace;name 必填,slug 自动生成(可手动改,全局唯一,仅含小写字母/数字/连字符);创建者自动成为 admin 角色
FR-01-07P0查询 & 切换 Workspace已登录用户可查看所有已加入的 Workspace 列表;切换 Workspace 时重新获取该 Workspace 的 context;同一用户可同时属于多个 Workspace
FR-01-08P0更新 Workspaceadmin 可修改 nameslugslug 变更需确认,影响公开链接);researcher 无权修改
FR-01-09P0删除 Workspaceadmin 可软删除;删除前要求输入 Workspace 名称确认;删除后该 Workspace 的所有 project / study / session / KB 数据不对外可见;写入 audit_logs

3.3 成员管理

编号优先级描述验收要点
FR-01-10P0邀请成员admin 可通过邮箱发送邀请;被邀请者尚未注册时邀请链接引导注册后自动加入;邀请链接有效期 72 小时;同一邮箱/Workspace 组合已存在时返回提示
FR-01-11P0角色分配支持 admin / researcher 两种角色(见权限矩阵 §4);admin 可更改其他成员角色,但不可降级自己为最后一个 admin;角色变更写入 audit_logs
FR-01-12P0移除成员admin 可将成员从 Workspace 移除;移除后该成员立即失去对该 Workspace 的 API 访问权;写入 audit_logs
FR-01-13P0退出 Workspaceresearcher 可主动退出;Workspace 唯一 admin 不可退出(须先转移 admin 或删除 Workspace)

3.4 数据隔离

编号优先级描述验收要点
FR-01-14P0Workspace 级数据隔离所有 API 查询必须携带 workspace_id scope;projectsstudiessessionsknowledge_basesparticipants 均通过外键归属 workspace;服务层在 SQL 层强制追加 workspace_id = ? 条件,不依赖业务逻辑层过滤
FR-01-15P0Participant 访问边界持有 public_slug 的 participant 只能访问对应 study 的 session(读/写),不能枚举同 Workspace 其他 study/project;participant API 端点与 admin API 端点路径分离,中间件不互通
FR-01-16P0审计日志写入以下操作必须写 audit_logs:Workspace CRUD、成员邀请/移除/角色变更、study 发布/下线、export 操作;actor_id 在 participant 操作时为空,resource_type 标注 participant

3.5 Participant 匿名访问

编号优先级描述验收要点
FR-01-17P0Public link 进入访谈Participant 访问 GET /s/{public_slug} 无需登录;后端校验 study 状态为 publishedpublic_slug 有效且未过期;校验通过后颁发临时 participant_token(JWT,仅含 participant_id + session_id + exp
FR-01-18P0Participant 记录创建首次进入时在 participants 表创建记录,workspace_id 来自 study 归属链(study → project → workspace);external_id 可选(由 URL query 参数传入,如招募平台 ID);匿名场景下 external_id 为空
FR-01-19P0Public link 安全控制public_slug 使用 URL-safe 随机字符串(不可枚举);study 支持设置最大 session 数上限(超出拒绝新建);参见 06_ops/02_security_privacy 的 Public Link 安全节
FR-01-20P0Consent 页面Participant 首次进入时展示知情同意页(调研目的、AI 主持说明、录音/记录说明、退出方式);同意前不创建 session;拒绝则跳出,不写 participants 记录

4. 关键流程

4.1 用户注册 & Workspace 创建

用户填写邮箱+密码
→ POST /auth/register(创建 users 记录)
→ 返回 access_token + refresh_token
→ 前端跳转「创建或加入 Workspace」
→ POST /workspaces(创建 workspaces 记录)
→ 创建 workspace_members 记录(role=admin)
→ 跳转 Workspace Dashboard

4.2 成员邀请 & 加入

admin 输入被邀请者邮箱 + 选择角色
→ POST /workspaces/{workspace_id}/invitations
→ 系统发送邀请邮件(含签名链接)
→ 被邀请者点击链接
→ 若未注册:引导注册 → 自动加入
→ 若已注册:直接加入(创建 workspace_members 记录)
→ 角色分配写入 audit_logs

4.3 Participant 访问流程

研究人员发布 study(生成 public_slug)
→ 受访者访问 /s/{public_slug}
→ 后端校验 study 状态 & slug 有效性
→ 前端展示 Consent 页面
→ Participant 同意
→ 后端创建 participants 记录(匿名或带 external_id)
→ 后端创建 sessions 记录
→ 颁发 participant_token
→ 进入 Interview Runtime(见 [04_interview_runtime](/02_product/prd/04_interview_runtime))

5. 数据

本模块涉及以下 data_model.md 中定义的表:

表名本模块用途
users存储已注册的研究人员/admin 账号(邮箱、密码哈希、创建时间)
workspaces顶层租户容器(idnameslug、时间戳)
workspace_members多对多关联 users ↔ workspaces,含 roleadmin / researcher
participants受访者记录,workspace_id FK,含可选 external_idmetadata JSONB
audit_logs记录所有关键操作,含 actor_id(可空)、actionresource_typeresource_idbefore/after

users 表未在 data_model.md 中显式定义,MVP 实现时需补充(至少含 id UUIDemail TEXT UNIQUEpassword_hash TEXTcreated_atupdated_at)。

workspace_members 表需补充(至少含 id UUIDworkspace_id UUID FKuser_id UUID FKrole TEXTinvited_by UUIDjoined_at TIMESTAMPTZ)。


6. 接口

方法路径描述认证
POST/auth/register注册新用户
POST/auth/login邮箱+密码登录,返回 JWT
POST/auth/refresh刷新 access tokenrefresh token
POST/auth/logout使 refresh token 失效access token
POST/auth/password-reset/request发送密码重置邮件
POST/auth/password-reset/confirm提交新密码签名链接 token
POST/workspaces创建 Workspaceaccess token
GET/workspaces查询当前用户所属 Workspace 列表access token
GET/workspaces/{workspace_id}获取单个 Workspace 详情access token + member
PATCH/workspaces/{workspace_id}更新 Workspace(admin 权限)access token + admin
DELETE/workspaces/{workspace_id}软删除 Workspace(admin 权限)access token + admin
GET/workspaces/{workspace_id}/members查询成员列表access token + member
POST/workspaces/{workspace_id}/invitations发送邀请access token + admin
PATCH/workspaces/{workspace_id}/members/{user_id}变更角色access token + admin
DELETE/workspaces/{workspace_id}/members/{user_id}移除成员access token + admin
GET/s/{public_slug}Participant 入口,校验 slug,返回 study 基本信息
POST/s/{public_slug}/sessions创建 session(含创建 participant 记录)无(或 Consent 确认 token)

详细请求/响应结构见 api_contracts


7. 验收标准

编号标准(均可自动化测试)
AC-01-01相同邮箱二次注册返回 HTTP 409,不创建新 user 记录。
AC-01-02登录凭证错误返回 HTTP 401,响应体不透露是邮箱还是密码错误。
AC-01-03access token 过期后使用该 token 访问受保护端点返回 HTTP 401;使用有效 refresh token 换取新 access token 返回 HTTP 200,旧 refresh token 同时失效。
AC-01-04新注册用户在未加入任何 Workspace 时,GET /workspaces 返回空数组。
AC-01-05创建 Workspace 后,workspace_members 表中存在一条 role=admin 记录;workspaces.slug 在数据库层唯一约束可验证。
AC-01-06researcher 角色调用 PATCH /workspaces/{id} 返回 HTTP 403。
AC-01-07Workspace 唯一 admin 尝试降级自身角色返回 HTTP 422,并附带错误说明。
AC-01-08移除成员后,该成员立即无法访问该 Workspace 的任何端点(下一次请求返回 HTTP 403),无需等待 token 过期。
AC-01-09用 Workspace A 的 member access token 调用 Workspace B 的 GET /workspaces/{B}/members 返回 HTTP 403。
AC-01-10GET /projects?workspace_id=A 在 SQL 层强制过滤,伪造 workspace_id 参数不返回其他 Workspace 的数据(可通过 SQL 查询日志验证)。
AC-01-11访问已下线(status != published)study 的 public link 返回 HTTP 404 或引导页,不进入访谈流程。
AC-01-12持有 participant_token 的请求不能访问 admin API(如 GET /workspaces),返回 HTTP 403。
AC-01-13Participant 拒绝 Consent 后,participantssessions 表中不产生新记录。
AC-01-14study 设置最大 session 数为 N,第 N+1 次 POST /s/{slug}/sessions 请求返回 HTTP 429 或 403 并附带说明。
AC-01-15以下操作在 audit_logs 中各产生一条记录:Workspace 创建、成员邀请、角色变更、成员移除、Workspace 删除。

8. 边界 & 非目标

边界说明

  • 本模块只覆盖认证与 Workspace 层;Project / Study 的创建与管理见 02_projects_studies
  • Participant 的 session 生命周期(进入访谈、transcript、extraction)见 04_interview_runtime
  • Public link 的 public_slug 字段定义在 studies 表,由 03_study_builder 中的发布流程生成;本模块仅负责入口校验与 participant 记录创建。

非目标(MVP 不做)

  • SSO(Google / GitHub / SAML)登录
  • 复杂多团队分级权限(跨 Workspace 角色继承)
  • Viewer 只读角色
  • Project 级权限覆盖(当前权限粒度到 Workspace)
  • SCIM 自动化用户供给
  • 邮箱验证(注册后强制验证)——MVP 注册后直接可用
  • 多因素认证(MFA / TOTP)

9. 依赖 & 风险

依赖

依赖项说明
02_projects_studiesProject / Study 对象的 workspace_id FK 约束由本模块 Workspace 提供
03_study_builderstudy 发布流程生成 public_slug,本模块 participant 入口依赖该字段
04_interview_runtimeparticipant_token 颁发后,interview runtime 验证该 token 并绑定 session
06_ops/02_security_privacyPublic link 安全策略(随机 slug、rate limit、allowed domains)详见安全文档
audit_logs本模块写入量最大,需确保该表有足够的写入性能与索引(resource_typecreated_at

风险

风险影响缓解措施
usersworkspace_members 表尚未在 data_model.md 中显式定义实现阶段可能出现字段对齐问题MVP 开始前补充完整 DDL;与 data_model.md 同步更新
Participant token 无法主动撤销(JWT 无状态)若 study 提前下线,已颁发 token 在 exp 内仍可用运行时校验 sessions.statusstudies.status,不依赖 token 有效期单独判断
邮件发送依赖第三方服务(邀请、密码重置)邮件延迟或失败影响用户体验MVP 允许管理员手动复制邀请链接作为降级方案;记录发送失败 error log
Workspace 软删除后数据可见性已删除 Workspace 的数据若未正确过滤可能泄露所有查询在服务层统一追加 deleted_at IS NULL 条件;写集成测试覆盖