Skip to content

fix(group-chat): create group first when starting group chat from private chat#52

Open
a652 wants to merge 1 commit into
Mininglamp-OSS:mainfrom
a652:fix/group-chat-from-private-400
Open

fix(group-chat): create group first when starting group chat from private chat#52
a652 wants to merge 1 commit into
Mininglamp-OSS:mainfrom
a652:fix/group-chat-from-private-400

Conversation

@a652
Copy link
Copy Markdown

@a652 a652 commented May 19, 2026

Summary

Fix the 400 error when starting a group chat from the private chat three-dots menu. The action now correctly creates a new group first before navigating to it, instead of incorrectly trying to add members to a non-existent group.

Related Issue

Fixes #51

Changes

  • In onOK() AddMember branch, added a channelType check:
    • ChannelTypePerson: build uid list [self, otherPerson, ...selected], call createChannel(), then navigate to the new group via showConversation()
    • Group channel: keep the original addSubscribers() logic (unchanged)

Testing

  • Unit tests added/updated
  • Manually verified

Steps to verify:

  1. Open any private chat conversation
  2. Click ⋯ → Start Group Chat
  3. Select one or more members → confirm
  4. Group chat is created successfully and UI navigates to it ✅

Previously: POST /groups/{userUID}/members → 400 Bad Request
After fix: POST /group/create → success → navigate to new group

Checklist

  • I have read CONTRIBUTING.md
  • PR description is in English
  • Added tests for my changes
  • Followed commit message conventions (Conventional Commits)

…vate chat

The AddMember branch in onOK() unconditionally called addSubscribers() using the current channelID. When launched from a private chat (channelType=ChannelTypePerson), channelID is a user UID, not a group ID, causing POST /groups/{uid}/members to return 400.

Fix: check channelType in the AddMember branch. For ChannelTypePerson, create a new group (self + other person + selected members) first, then navigate to it. For group channels, keep the existing addSubscribers logic.

Fixes Mininglamp-OSS#51
@a652 a652 requested a review from a team as a code owner May 19, 2026 09:39
@github-actions github-actions Bot added the size/S PR size: S label May 19, 2026
Copy link
Copy Markdown
Contributor

@yujiawei yujiawei left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review — PR #52 (octo-web)

Summary

This PR updates the add-member flow so that when it is launched from a private chat, it creates a new group containing the current user, the private-chat peer, and the selected contacts, then opens that group conversation. The existing group-chat path continues to call addSubscribers on the current group.

Findings

No blocking findings.

Verdict

APPROVED — The change matches the existing private-chat group creation pattern and keeps the existing group add-member behavior intact.

Copy link
Copy Markdown
Contributor

@Jerry-Xin Jerry-Xin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR is relevant to octo-web and fixes the private-chat “start group chat” path using the project’s existing create-then-navigate pattern.

💬 Non-blocking

🟡 Warning: No regression test was added for the new private-chat AddMember branch in packages/dmworkcontacts/src/Organizational/GroupNew/index.tsx:482. A focused test should mock createChannel, addSubscribers, and showConversation to verify private chats call createChannel([self, peer, selected...]), while group chats still call addSubscribers.

🔵 Suggestion: packages/dmworkcontacts/src/Organizational/GroupNew/index.tsx:490 silently closes the modal if createChannel() resolves without group_no. Consider showing an error and returning before this.onCancel() so the user does not see a false success state.

🔵 Suggestion: packages/dmworkcontacts/src/Organizational/GroupNew/index.tsx:485 could defensively filter/dedupe empty or repeated UIDs before calling createChannel(), especially because WKApp.loginInfo.uid || "" can introduce an empty member ID.

✅ Highlights

🟢 The private-chat branch correctly avoids the previous invalid addSubscribers() call against a person channel and creates a group first at packages/dmworkcontacts/src/Organizational/GroupNew/index.tsx:482.

🟢 The group-channel behavior remains unchanged at packages/dmworkcontacts/src/Organizational/GroupNew/index.tsx:494, limiting the fix’s blast radius.

🟢 The implementation matches an existing project pattern in packages/dmworkbase/src/module.tsx:1306.

Copy link
Copy Markdown
Contributor

@lml2468 lml2468 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — PR #52 fix(group-chat): create group first when starting group chat from private chat

Verdict: APPROVE


Analysis

Root cause — when starting a group chat from a private chat's ⋯ menu, the code entered the AddMember branch and called addSubscribers(channel, members) where channel was the person channel (not a group). This tried to POST /groups/{userUID}/members which returns 400 because a person channel isn't a group.

Fix — adds a channelType check in the AddMember branch:

  • ChannelTypePerson → create a new group with [self, otherPerson, ...selected], navigate to it
  • Group channel → keep original addSubscribers() logic

Verification against existing patterns:

The new person-chat path mirrors the createGroup branch exactly (lines 462-478):

// createGroup (existing):
createChannel([...getOptPersonnelData], { categoryId })
// AddMember + person (new):
createChannel([self, chatPartner, ...getOptPersonnelData])

Same createChannel() call, same result?.group_no guard, same showConversation() navigation. The only difference is the UID list composition (includes self + chat partner) and no categoryId (correct — private chat has no category context).

createChannel implementation verified (packages/dmworkdatasource/src/datasource.ts): posts to group/create with { members: uids }. Backend handles member deduplication.

Imports verified: Channel, ChannelTypeGroup, ChannelTypePerson are all imported from wukongimjssdk at line 3.

⚠️ CI note

Build check has NOT run — CI status is action_required (fork contributor a652 needs maintainer workflow approval). Do not merge until CI Build passes.

💬 Non-blocking

  1. No regression test (Allen's finding) — agree. The two onOK() branches (person → createChannel vs group → addSubscribers) would benefit from a test that mocks channelDataSource and verifies the correct method is called for each channelType.

  2. WKApp.loginInfo.uid || "" — empty string fallback is a no-op guard (user must be logged in to reach this flow), but a more explicit assert/throw would be safer than silently passing "" as a member UID.


REVIEW_STATE: APPROVED

@botshen
Copy link
Copy Markdown
Contributor

botshen commented May 19, 2026

补充 Review 意见

感谢 @a652 的修复,逻辑方向是正确的。不过我注意到之前几位 reviewer 都提到了一些问题但标记为 non-blocking,我认为其中有两个应该在合并前修复:

🔴 建议修复

1. group_no 为空时的静默失败 (第 489-491 行)

当前代码在 createChannel 成功但 group_no 为空时,会直接关闭 modal,用户看不到任何反馈——以为群创建成功了,实际上没有。

// 当前
if (result?.group_no) {
  WKApp.endpoints.showConversation(new Channel(result.group_no, ChannelTypeGroup));
}
// modal 关闭,用户一脸懵

// 建议
if (result?.group_no) {
  WKApp.endpoints.showConversation(new Channel(result.group_no, ChannelTypeGroup));
} else {
  Toast.error("创建群组失败,请重试");
  return; // 不关闭 modal,让用户可以重试
}

2. uid || "" 的防御性处理 (第 485 行)

虽然用户必须登录才能到达这个流程,但传空字符串给后端仍然是潜在风险:

// 建议
const selfUid = WKApp.loginInfo.uid;
if (!selfUid) {
  Toast.error("登录状态异常");
  return;
}
const uids = [selfUid, this.props.channel.channelID, ...getOptPersonnelData];

以上只是补充意见,PR 的核心逻辑是对的。如果作者觉得这些可以在后续 PR 处理也 OK,只是想明确表达一下:这两个问题值得重视。

— Review by Hermes Agent

Copy link
Copy Markdown
Contributor

@botshen botshen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review — PR #52

Verdict: APPROVE

核心修复逻辑正确,符合项目现有的 create-then-navigate 模式。

💬 Non-blocking(已在评论中详述)

  1. group_no 为空时建议显示错误而非静默关闭
  2. uid || "" 建议加防御性校验

这两个可以在后续 PR 处理,不阻塞本次合并。


Reviewed by Hermes Agent on behalf of @pstrings

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/S PR size: S

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Starting group chat from private chat three-dots menu returns 400 'Group does not exist'

5 participants