Skip to content

Feat/namespace member display username#236

Open
Rsweater wants to merge 2 commits intoiflytek:mainfrom
Rsweater:feat/namespace-member-display-username
Open

Feat/namespace member display username#236
Rsweater wants to merge 2 commits intoiflytek:mainfrom
Rsweater:feat/namespace-member-display-username

Conversation

@Rsweater
Copy link
Copy Markdown
Contributor

@Rsweater Rsweater commented Apr 3, 2026

feat(namespace): display username and email in namespace member management

Summary

  • What changed?(改了什么?)

    命名空间成员管理页面当前只显示用户 ID(userId),不方便人类阅读。本 PR 在成员列表中增加了 displayName(用户名)和 email(邮箱)字段,使管理员可以快速识别成员身份。

    后端改动(3 个文件)

    文件 改动 说明
    MemberResponse.java 新增 displayName + email 字段 DTO 扩展,向后兼容(原有 from(member) 方法保留,新增 from(member, user) 方法)
    NamespacePortalQueryAppService.java 注入 UserAccountRepositorylistMembers 批量查询用户信息 使用 findByIdIn 批量查询,避免 N+1 问题
    NamespacePortalCommandAppService.java 注入 UserAccountRepositoryaddMember / updateMemberRole 填充用户信息 新增/修改成员时也返回用户名和邮箱

    后端测试(3 个文件)

    文件 改动
    NamespacePortalControllerTest.java 新增 UserAccountRepository mock,addMember / updateMemberRole 测试添加 stub
    NamespacePortalCommandAppServiceTest.java 构造函数新增 UserAccountRepository 参数
    NamespacePortalQueryAppServiceTest.java 构造函数新增 UserAccountRepository 参数

    前端改动(4 个文件)

    文件 改动
    namespace-members.tsx 表格列从 "User ID" 改为 "Username" + "Email",Username 列显示 displayName(大字)+ userId(小字副标题)
    types.ts NamespaceMember 接口新增 displayName?: string + email?: string
    schema.d.ts OpenAPI schema 同步更新
    en.json / zh.json 新增 colUsername + colEmail 翻译 key

    总计:11 个文件变更,+84 行新增,-9 行删除

  • Why is this needed?(为什么需要?)

    当前成员管理页面只显示 userId(如 docker-admin),管理员无法快速识别成员身份。加上 displayName 和 email 后,管理员可以直观看到"Platform Admin (admin@skillhub.local)"这样的信息,大幅提升管理效率。同时,该需求与管理员账户的用户管理页面保持一致,后者已经正确显示了用户名和邮箱。

Validation

  • Backend tests passed — NamespacePortalControllerTest 全部通过
  • Frontend typecheck/build passed — pnpm typecheckpnpm build 均通过
  • OpenAPI SDK regenerated — schema.d.ts 已更新 displayName? + email?
  • Smoke test run — 见下方完整测试方案

Commands run:

# 后端编译 + 测试
cd server && ./mvnw compile -pl skillhub-app -am -q
./mvnw test -pl skillhub-app -am -Dtest=NamespacePortalControllerTest -q

# 前端 typecheck + build
cd web && pnpm typecheck && pnpm build

Risk

  • User-facing impact(用户可见影响):
    命名空间成员表格列从 "User ID" 改为 "Username" + "Email"。现有功能完全不受影响(向后兼容 — 新字段为可选,from(member) 方法保留返回 null)。
  • Deployment or migration impact(部署/迁移影响):
    无。无数据库 migration,无配置变更,无 API 路径变更。
  • Rollback approach(回滚方案):
    直接 revert 此 PR。MemberResponse.from(member) 工厂方法已保留并返回 null,回滚安全无风险。

Notes

  • Related issue(相关问题): 命名空间成员管理只显示 userId,不方便识别
  • Follow-up work(后续工作): 考虑在成员列表中添加按用户名或邮箱搜索/过滤功能
  • Docs or operator runbooks updated when behavior changed(文档/运维手册更新): N/A — 纯 UI 变更,无运维影响

完整测试方案

一、自动化测试

1. 后端单元测试

cd /mnt/cfs/chenbaowang/skillhub/server

# 运行成员管理相关测试
./mvnw test -pl skillhub-app -am -Dtest=NamespacePortalControllerTest -q

# 运行 Service 层测试
./mvnw test -pl skillhub-app -am -Dtest=NamespacePortalCommandAppServiceTest,NamespacePortalQueryAppServiceTest -q

预期:全部通过,无编译错误。

2. 前端类型检查 + 构建

cd /mnt/cfs/chenbaowang/skillhub/web

# TypeScript 类型检查
pnpm typecheck

# 生产构建
pnpm build

预期:无类型错误,构建成功。

3. API 响应验证

# 启动后端(跳过 scanner 见下方说明)
make dev
make dev-server

# 请求成员列表接口
curl -s -H "X-Mock-User-Id: local-admin" http://localhost:8080/api/v1/namespaces/global/members | python3 -m json.tool

预期响应

{
  "code": 0,
  "data": {
    "items": [
      {
        "id": 1,
        "namespaceId": 1,
        "userId": "local-admin",
        "displayName": "Local Admin",
        "email": "admin@skillhub.local",
        "role": "OWNER",
        "createdAt": "...",
        "updatedAt": "..."
      }
    ]
  }
}

二、人工测试

1. UI 验证

# 操作 预期
1 启动全栈环境(make dev-all 或跳过 scanner 见下方) 后端/前端正常启动
2 浏览器打开 http://localhost:3000 页面正常加载
3 使用 bootstrap admin 登录:admin / ChangeMe!2026 登录成功,进入 Dashboard
4 导航:Dashboard → Namespaces → 选择命名空间 → Members 页面正常加载
5 查看表格列头 显示:Username | Email | Role | Joined At | Actions
6 检查 Username 列 显示 displayName(大字),下方小字显示 userId
7 检查 Email 列 显示邮箱地址或 "-"
8 点击 "Add Member" 添加成员 添加成功后列表自动刷新,新成员显示用户名和邮箱
9 修改成员角色 修改成功后列表刷新,信息正确
10 移除成员 移除成功后列表刷新

2. 回归测试

# 场景 预期
1 全局命名空间(GLOBAL 类型)成员列表 正常加载,只读
2 冻结(FROZEN)命名空间成员列表 正常加载,只读
3 归档(ARCHIVED)命名空间成员列表 正常加载,只读
4 非成员访问命名空间 返回 403 或跳转到无权限页面
5 其他页面(Skills, Search, Settings 等) 不受影响,正常加载

三、冒烟测试(5 分钟快速验证)

基于 Local Development Setup 官方文档:

# 1. 前置检查
docker --version && java -version && node --version && pnpm --version

# 2. 启动开发环境
cd /mnt/cfs/chenbaowang/skillhub
make dev-all  # 或跳过 scanner 见下方

# 3. API 验证
curl -s -H "X-Mock-User-Id: local-admin" http://localhost:8080/api/v1/namespaces/global/members | python3 -c "
import sys, json
d = json.load(sys.stdin)
items = d.get('data', {}).get('items', [])
if items and 'displayName' in items[0] and 'email' in items[0]:
    print('✅ PASS: API returns displayName and email')
else:
    print('❌ FAIL: Missing displayName or email')
    sys.exit(1)
"

# 4. 前端验证
curl -sf http://localhost:3000 >/dev/null && echo "✅ PASS: Frontend accessible"

# 5. 后端测试
make test-backend-app

# 6. 前端类型检查
make typecheck-web

# 7. 服务状态
make dev-status

通过标准

检查项 通过标准
开发环境启动 make dev-all 成功
后端 API 返回 displayNameemail 字段
前端访问 http://localhost:3000 可访问
后端测试 make test-backend-app 通过
前端类型检查 make typecheck-web 无错误

Rsweater added 2 commits April 3, 2026 10:53
MemberResponse DTO now includes displayName and email fields.
NamespacePortalQueryAppService batch-loads UserAccount data via
findByIdIn to avoid N+1 queries. Frontend member table shows
username (with userId as fallback subtitle) and email columns
instead of raw user IDs.
…ement

MemberResponse DTO now includes displayName and email fields.
NamespacePortalQueryAppService batch-loads UserAccount data via
findByIdIn to avoid N+1 queries. Frontend member table shows
username (with userId as fallback subtitle) and email columns
instead of raw user IDs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant