Skip to content

Feat/namespace member display username#236

Merged
wowo-zZ merged 2 commits intoiflytek:mainfrom
Rsweater:feat/namespace-member-display-username
Apr 8, 2026
Merged

Feat/namespace member display username#236
wowo-zZ merged 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 无错误

@XiaoSeS XiaoSeS self-assigned this Apr 7, 2026
@XiaoSeS
Copy link
Copy Markdown
Collaborator

XiaoSeS commented Apr 7, 2026

  1. 需要 Rebase 到最新 main

PR 的 diff 中包含了 ClawHubCompatAppService.java 和
ClawHubCompatControllerTest.java 的改动(resolveQueryCoordinate
方法及测试),但这些已在 #227 (0b84e4e) 合入 main。分支需要
rebase,否则会产生冗余 diff 或冲突。

  1. Controller 测试缺少新字段断言

NamespacePortalControllerTest.java 的 addMember_returnsCreatedMember(第 188
行)和 updateMemberRole_returnsUpdatedMember(第 224 行)都 mock 了
UserAccount("user-2", "Alice", "alice@example.com", null),但断言只验证了
userId 和 role,没有验证 displayName 和 email 是否正确返回。Mock
了但不断言等于没测。

  1. Service 层测试缺少新逻辑覆盖

NamespacePortalCommandAppServiceTest 和 NamespacePortalQueryAppServiceTest
只是在构造函数加了 userAccountRepository
参数让编译通过,没有新增任何测试用例覆盖:

  • 批量查询组装 displayName/email
  • 用户不存在时降级返回 null

Rsweater added a commit to Rsweater/skillhub that referenced this pull request Apr 7, 2026
- Controller: add displayName and email assertions to addMember and updateMemberRole tests
- QueryAppService: add listMembers tests for batch user enrichment and null degradation
- CommandAppService: add addMember/updateMemberRole tests for displayName/email population and graceful degradation

Addresses PR iflytek#236 review feedback comments:
- Issue 2: Controller tests now assert displayName and email from mocked UserAccount
- Issue 3: Service layer tests now cover batch query and null user degradation
Rsweater added 2 commits April 7, 2026 19:39
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.
- Controller: add displayName and email assertions to addMember and updateMemberRole tests
- QueryAppService: add listMembers tests for batch user enrichment and null degradation
- CommandAppService: add addMember/updateMemberRole tests for displayName/email population and graceful degradation

Addresses PR iflytek#236 review feedback comments:
- Issue 2: Controller tests now assert displayName and email from mocked UserAccount
- Issue 3: Service layer tests now cover batch query and null user degradation
@Rsweater Rsweater force-pushed the feat/namespace-member-display-username branch from 3b5f3ba to 79140f3 Compare April 7, 2026 11:41
@Rsweater
Copy link
Copy Markdown
Contributor Author

Rsweater commented Apr 7, 2026

感谢 Review!


Issue 1:✅ 已 Rebase

Rebase 到 upstream/main 最新代码,冗余的 ClawHubCompatAppService.java 和 ClawHubCompatControllerTest.java 改动已自然消除。PR diff 现在只包含 namespace member 功能相关的 11 个文件,0 个冗余。
根本原因:skillhub/main(Rsweater fork)落后 upstream/main 447 commits,#227 的 ClawHub 改动在 fork 中不存在,导致 PR 自带了重复改动。Rebase 后 ClawHub 文件自动跟随 upstream/main 合入,无冗余 diff。


Issue 2 & 3:✅ 测试已补充

Commit 79140f3 新增完整测试覆盖:

Controller 层(NamespacePortalControllerTest.java):

  • 补充 addMember_returnsCreatedMember 的 displayName + email 断言
  • 补充 updateMemberRole_returnsUpdatedMember 的 displayName + email 断言

Command Service 层(NamespacePortalCommandAppServiceTest.java):

  • addMember_populatesDisplayNameAndEmail:验证用户存在时字段被填充
  • addMember_withoutUserAccount_degradesGracefully:验证幽灵用户降级返回 null
  • updateMemberRole_populatesDisplayNameAndEmail:同上
  • updateMemberRole_withoutUserAccount_degradesGracefully:同上

Query Service 层(NamespacePortalQueryAppServiceTest.java):

  • listMembers_withUserAccount_returnsDisplayNameAndEmail:验证批量查询 + 组装
  • listMembers_withoutUserAccount_returnsNullFields:验证用户不存在时降级
    测试结果:20/20 通过 ✅

@wowo-zZ wowo-zZ merged commit 739e21e into iflytek:main Apr 8, 2026
3 checks passed
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.

3 participants