Skip to content

core: fix: upsert each user when setting roles in bulk - #1224

Merged
hydrodevbot[bot] merged 2 commits into
hydro-dev:masterfrom
AntaresQAQ:fix/domain-user-role-upsert
Oct 14, 2026
Merged

hydrodevbot[bot] merged 2 commits into
hydro-dev:masterfrom
AntaresQAQ:fix/domain-user-role-upsert

Conversation

@AntaresQAQ

@AntaresQAQ AntaresQAQ commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #1223.

The array branch of DomainModel.setUserRole currently uses updateMany with an $in filter and upsert: true. This does not create a record for each missing UID: partially matching batches leave missing users untouched, while entirely unmatched batches can create a document without a UID and trigger a duplicate-key error.

Replace this with a single bulkWrite containing an updateOne upsert for each { domainId, uid } pair.

  • Return early for empty UID arrays to avoid an empty-batch error.
  • Preserve existing cache invalidation and autojoin behavior.
  • Leave the single-UID branch unchanged.
  • Do not modify or remove existing malformed records.

This PR contains only the model fix; no test code or test data is included.

Validation

Verified with temporary regression tests against MongoDB 8.0:

  • All target records missing, partially missing, and all existing.
  • Repeated calls and empty UID arrays.
  • autojoin enabled and disabled, including preservation of existing join status.
  • Existing documents without a UID.
  • set_users with join: true through the HTTP handler.

The original implementation failed six of the eight regression cases; the fixed implementation passed all eight.

Targeted ESLint and backend TypeScript checks with --skipLibCheck passed. Without --skipLibCheck, the type check is blocked by an existing third-party declaration error involving @types/koa and content-disposition.

Summary by CodeRabbit

  • Bug Fixes
    • Improved role assignment for multiple users by applying updates individually and avoiding duplicate user IDs.
    • Refreshed affected users’ cached data after role changes.

Use per-UID bulk upserts for batch role assignment and skip empty batches while preserving cache invalidation and autojoin behavior.

Fixes hydro-dev#1223

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@coderabbitai

coderabbitai Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4a0a1f81-9889-4be3-b742-d123651532d1
📥 Commits

Reviewing files that changed from the base of the PR and between b6b1b25 and 9f14c63.

📒 Files selected for processing: 1
  • packages/hydrooj/src/model/domain.ts

Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 6 remain after this review.

Walkthrough

For an empty UID array, DomainModel.setUserRole now returns undefined. For a nonempty array, it preserves the affected-user lookup and cache deletion, then uses bulkWrite to upsert one record per distinct UID instead of issuing a single upserting updateMany.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~8 minutes

Change: Bug fix · Severity of issue fixed: Medium

Merge Risk: ⚪ Minimal · up to 9f14c

Bulk role assignment now creates or updates a record for each distinct target UID. No actionable merge risk was established in the inspected behavior.

Pre-merge checks: Passed 5
Passed Passed checks: 5 passed
Check name Status Explanation
Linked Issues check Passed The change addresses issue #1223. The array branch deduplicates UIDs and uses one bulkWrite updateOne upsert per { domainId, uid }. It returns for an empty array, preserves cache invalidation an…
Out of Scope Changes check Passed The change is limited to packages/hydrooj/src/model/domain.ts. The modified code directly fixes the bulk upsert behavior required by issue #1223. No unrelated implementation, test-data, or cleanup c…
Docstring Coverage Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 1…
Description Check Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check Passed The title clearly and concisely describes the main change: creating or updating each user record during bulk role assignment.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@AntaresQAQ AntaresQAQ changed the title fix(domain): upsert each user when setting roles in bulk core: fix upsert each user when setting roles in bulk Oct 14, 2026
@AntaresQAQ AntaresQAQ changed the title core: fix upsert each user when setting roles in bulk core: fix: upsert each user when setting roles in bulk Oct 14, 2026
@hydrodevbot
hydrodevbot Bot merged commit 851e167 into hydro-dev:master Oct 14, 2026
3 checks passed
@AntaresQAQ
AntaresQAQ deleted the fix/domain-user-role-upsert branch October 14, 2026 10:26
@AntaresQAQ
AntaresQAQ restored the fix/domain-user-role-upsert branch October 14, 2026 10:37
@AntaresQAQ
AntaresQAQ deleted the fix/domain-user-role-upsert branch October 14, 2026 10:39
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.

域用户管理:批量设置角色的 updateMany upsert 无法为缺失 UID 创建记录,可能触发 E11000

1 participant