36ffe2713f
新建 backend/packages/harness/deerflow/persistence/workspace_membership/sql.py,方法:
- add(workspace_id, user_id, role, invited_by=None) 校验 role ∈
{owner, admin, member}(Stage 0 仅写 owner,schema 已支持其余)
- remove(workspace_id, user_id) → bool(rowcount > 0)
- list_by_user(user_id) 按 joined_at desc
- list_by_workspace(workspace_id) 按 joined_at asc
- get_role(workspace_id, user_id) → str | None
- change_role(workspace_id, user_id, new_role) → bool
MembershipValidationError 自定义异常(role 非法)。
8 test 覆盖:
- add → get_role round-trip
- remove 命中/未命中返回 True/False
- 同 workspace 第 2 个 owner 触发 IntegrityError(partial unique)
- 同 workspace 多个 admin 不触发(Stage 2 forward compat)
- CASCADE: 删 user 自动清理 memberships
- list_by_user 按 joined_at desc 排序(多 workspace)
- role 校验拒绝 'viewer'
- change_role 命中改值 + 未命中返 False
注:owner 转让需要事务内两行原子 swap(先把现 owner 改 admin,再把新 owner
插 owner),放 PR4+ auth router 内做带权限检查的版本;本仓储不暴露
transfer_ownership 方法以保持单一职责。
Stage 0 PR3 T3.7。
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>