3.8 KiB
3.8 KiB
PROGRESS_D-01 · 用户-租户 membership + 跨租户切换
日期 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/):
tenants.py(新建):my_tenants(我的租户+role)、switch_tenant(校验+审计)、tenant_members(GET 列表 / POST 邀请:admin 仅 member,新用户≥8位密码事务创建)、tenant_member_detail(PATCH 改角色/禁用 / DELETE 移除:admin 不动 owner/admin, 移除仅 owner,最后一个 owner 三禁)。urls.py:四条路由挂core_urlpatterns(即/api/v1/tenants/...)。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(既有旁路,未动)。