Files
vscode-workbench/PLANNING/PROGRESS_D-01.md
T

3.9 KiB
Raw Blame History

PROGRESS — D-01 · 用户-租户 membership + 跨租户切换

  • 状态:done

日期 2026-09-13 · 范围:只改 gj/dealerhub 目录(后端 core + 前端 tenants/members/切换器)

设计(阶段一,任务卡要求先评审再动手——本轮设计与实现一致,评审记录在此)

  • 模型(存量复用):TenantMembership(user, tenant, role[owner|admin|member], is_active, joined_at), 唯一约束 (user, tenant);存量回填(0002 迁移:超管=全租户,普通=default)iter6 已验证。
  • 授权矩阵:
    角色 切租户/看成员 邀请 改角色/禁用 移除
    owner ✅ ✅(任意角色) ✅ ✅(专属)
    admin ✅ ✅(仅 member) ✅(仅 member) ❌
    member ✅(自己有 membership 的) ❌ ❌ ❌
    非成员 403 403 403 403
    未知租户 400(参数错误,非 403) 400 400 400
    超管 直通(bootstrap 契约) 直通 直通 直通
  • 切换流程:POST /api/v1/tenants/<code>/switch/ 校验 membership → 返回 {code,name,role} + 写审计(tenant_switch);前端换 localStorage.tenant + 整页 reload(会话隔离无脏数据)。
  • 兼容策略:存量 membership 不动;最后一个 owner 禁止移除/降级/禁用(服务端事务内强保)。

现状 vs 差距(接手时)

  • 已有:membership 模型 + 迁移回填 + TenantMembershipPermission 服务端强制(iter6,8 用例)+ 注册建 owner(P0-3)+ 前端 localStorage 租户头。
  • 缺口:无切换端点、无成员管理接口、无前端切换器/成员页/无权限页。

改动

后端(backend/apps/core/ + backend/tests/):

  1. tenants.py(新建):my_tenants(我的租户+role)、switch_tenant(校验+审计)、 tenant_members(GET 列表 / POST 邀请:admin 仅 member,新用户≥8位密码事务创建)、 tenant_member_detail(PATCH 改角色/禁用 / DELETE 移除:admin 不动 owner/admin, 移除仅 owner,最后一个 owner 三禁)。
  2. urls.py:四条路由挂 core_urlpatterns(即 /api/v1/tenants/...)。
  3. tests/test_tenant_switch.py(新建,12 条):切换 200+role/无权 403/未知 400/mine 双租户/ member 邀 403/owner 邀 201+被邀可切/admin 邀 owner 403/admin 动 owner 403/ 跨租户成员页 403/删最后 owner 400/owner 删 member/禁用后资源 403。

前端(frontend/src/): 4. api/tenants.js(新建):mine/switchTo/members/invite/updateMember/removeMember。 5. pages/Members.vue(新建):成员表(角色/状态标签)+ 邀请 dialog(新老用户兼容)+ 改角色/禁用启用/移除(owner 专属按钮)+ 403 跳无权限页。 6. pages/NoPermission.vue(新建):无权限页 + 我的租户一键进入。 7. layouts/MainLayout.vue:租户 tag → 下拉切换器(mine() 列表,切后整页 reload)+ “成员”按钮 + 菜单加“租户成员”;router/index.js 加 /members + /no-permission。

边界遵守

  • 无计费/套餐;单据/库存业务零改;权限全在服务端(前端只做展示与跳转)。

验证

pytest tests/test_tenant_switch.py tests/test_membership.py   # 20 passed(12 新增 + 8 存量)
pytest -p no:cacheprovider                                     # 524 passed, 4 skipped(512 基线 + 12 新增)
npm test    # 17 pass / 0 fail
npm run build                                                 # ✓ built in 6.13s
manage.py makemigrations --check --dry-run                    # No changes detected
manage.py check                                               # 0 issues

状态

done。遗留:切换端到端(前端下拉 → switch → reload 无脏数据)需 dev 服务联调时录屏补证据; demo token 流不走 membership(既有旁路,未动)。