fix(server): stop overwriting users.group with Agnet channelId on every login

NewAPI's `users.group` is the local model-access bucket — it must match a
row in the `abilities` / `channels` group column to expose any models. The
Agnet channelId returned by mcp-server's /api/auth/me is a cross-platform
identity that almost never matches a NewAPI-side group, so blindly assigning
it on every login left users with `data: []` from /v1/models and the
desktop client silently fell back to the static 3-Claude default list.

Symptoms fixed: 4 users (xiaohei, 55@55.com, uwktn, test1) had UUID groups
with zero abilities, so /v1/models returned empty for them. cc-haha desktop
falls back to preset.defaultModels, hiding the 28 real models the channels
expose under group=default.

Change: drop the unconditional overwrite branch. The JIT-create path above
still seeds group from channelId on first login (kept for backward
compat), but admin-set group on existing users is preserved. mcp-server
already tracks Agnet channelId separately (see markBillingProviderNewapi),
so we don't need to mirror it into NewAPI's users.group anymore.

DB hot-fix already applied: 4 affected users moved to group=default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 19:05:33 +08:00
co-authored by Claude Opus 4.7
parent fc2c811e93
commit 578a68f006
+12 -4
View File
@@ -281,10 +281,18 @@ func syncLocalUserFromAgnet(me agnetMeEnvelope) (*model.User, error) {
user.DisplayName = name user.DisplayName = name
changed = true changed = true
} }
if ch := strings.TrimSpace(me.Data.ChannelID); ch != "" && user.Group != ch { // Don't overwrite the existing user's group with the Agnet channelId on
user.Group = ch // every login: NewAPI's `users.group` is the **local model-access bucket**
changed = true // (must match a row in the `abilities` / `channels` group column to expose
} // any models). The Agnet channelId is a cross-platform identity that
// rarely matches a NewAPI-side group, so overwriting strands the user
// with zero models. mcp-server side already tracks channelId separately
// (see markBillingProviderNewapi), so we don't need it duplicated here.
//
// Only seed the group on the JIT-create path above (when the user record
// is new and has no admin-set group yet). After that, NewAPI admins own
// the group via the dashboard.
_ = me.Data.ChannelID
// Promote role from Agnet / email whitelist on every login (never demote). // Promote role from Agnet / email whitelist on every login (never demote).
desiredRole := roleFromAgnetWithEmail(me.Data.Role, email) desiredRole := roleFromAgnetWithEmail(me.Data.Role, email)
if desiredRole > user.Role { if desiredRole > user.Role {