Use Mongodb replica set and transactions#4198
Conversation
This comment has been minimized.
This comment has been minimized.
📝 WalkthroughWalkthroughAdds MongoDB replica-set startup and local orchestration, exposes explicit transaction APIs on the Mongo DB context, refactors frontier operations to action-driven, transactional flows across repository and service layers, adds an ephemeral Mongo test runner and integration tests, updates controllers/interfaces/frontend contracts, and replaces local DB startup scripts. Changes
Sequence Diagram(s)sequenceDiagram
participant Client
participant WordService as WordService
participant WordRepository as WordRepository
participant MongoDbContext as MongoDbContext
participant MongoDB as MongoDB
Note over Client,MongoDB: Transactional frontier update flow (high-level)
Client->>WordService: MergeReplaceFrontier / Update(userId, Word)
WordService->>WordRepository: ReplaceFrontier / UpdateFrontier (passes action callbacks)
WordRepository->>MongoDbContext: ExecuteInTransaction(operation)
MongoDbContext->>MongoDB: BeginTransaction (start session)
MongoDbContext->>MongoDB: Execute operation with session (modify frontier, update words)
MongoDB-->>MongoDbContext: Operation result
MongoDbContext->>MongoDB: CommitTransactionAsync()
MongoDB-->>MongoDbContext: Commit confirmation
MongoDbContext-->>WordRepository: result
WordRepository-->>WordService: result
WordService-->>Client: Ok / result
Estimated Code Review Effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
📝 Coding Plan
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. Comment |
f1a173d to
d389fb3
Compare
d389fb3 to
ec53acb
Compare
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## master #4198 +/- ##
==========================================
+ Coverage 75.15% 75.70% +0.55%
==========================================
Files 302 303 +1
Lines 11099 11332 +233
Branches 1394 1411 +17
==========================================
+ Hits 8341 8579 +238
+ Misses 2357 2352 -5
Partials 401 401
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
47a7db2 to
d457901
Compare
jasonleenaylor
left a comment
There was a problem hiding this comment.
@jasonleenaylor reviewed 38 files and all commit messages, and made 1 comment.
Reviewable status:complete! all files reviewed, all discussions resolved (waiting on imnasnainaec).
Backend/Repositories/WordRepository.cs line 384 at r6 (raw file):
} // WITH-SESSION HELPER METHODS
Either remove this ugly comment, or alternatively turn it into a #region if you want to document this group of methods idiomatically.
There was a problem hiding this comment.
♻️ Duplicate comments (1)
Backend/Repositories/WordRepository.cs (1)
336-338:⚠️ Potential issue | 🟡 MinorXML exception contract still overstates missing-id failures in replace flow.
The
<exception>docs still say missing old IDs throw, but replacements run withcreateIfNotFound: true(Line 549), so some “missing old id” cases intentionally create instead of throwing. Please narrow these exception docs to guaranteed throw cases only.✏️ Suggested doc fix
- /// Thrown when an old word id doesn't exist in Frontier or a replacement word has a different project id. + /// Thrown when a replacement word has a different project id, or when a delete-target old id + /// cannot be found in Frontier.Based on learnings: In
Backend/Repositories/WordRepository.cs,ReplaceFrontierWithSessionintentionally allows silent create/replace behavior viacreateIfNotFound: true; this behavior is accepted by the maintainer.Also applies to: 531-532
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Backend/Repositories/WordRepository.cs` around lines 336 - 338, The XML <exception> on ReplaceFrontierWithSession overstates missing-old-id failures: update the documentation for the ReplaceFrontierWithSession method (and any duplicate exception tags for the same method/overload) to only document guaranteed throw cases — e.g., when a replacement word has a different ProjectId — and remove or rephrase the claim that missing old IDs always throw, since the implementation calls createIfNotFound: true and may create missing entries instead.
🧹 Nitpick comments (1)
Backend.Tests/Repositories/WordRepositoryTests.cs (1)
349-368: Consider extracting repeated “repo unchanged” assertions into a helper.Several tests repeat the same post-failure state checks; a small helper would reduce duplication and make intent clearer.
♻️ Optional refactor sketch
+ private async Task AssertRepoUnchanged( + string expectedOnlyWordId, + int expectedFrontierCount = 1) + { + Assert.That((await _repo.GetAllWords(_projectId)).Select(w => w.Id), + Is.EqualTo([expectedOnlyWordId])); + Assert.That(await _repo.GetFrontierCount(_projectId), Is.EqualTo(expectedFrontierCount)); + Assert.That(await _repo.IsInFrontier(_projectId, expectedOnlyWordId), Is.True); + }Also applies to: 432-451, 566-587, 590-602, 680-696
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@Backend.Tests/Repositories/WordRepositoryTests.cs` around lines 349 - 368, Multiple tests repeat the same post-failure assertions checking the repo was unchanged; extract those assertions into a reusable helper to reduce duplication. Create a private helper method (e.g., AssertRepositoryUnchangedAfterFailedOperation) that takes the project id and word id (and optionally the original created word) and performs the checks currently repeated: calling _repo.GetAllWords(_projectId) and comparing Ids, _repo.GetFrontierCount(_projectId), _repo.GetFrontier(_projectId, createdId) and asserting frontierWord is not null and frontierWord.Accessibility is not Status.Deleted; then replace the duplicated assertion blocks in TestDeleteFrontierModifyActionThrowsLeavesRepoUnchanged and the other indicated tests with a single call to this helper. Use the existing symbols CreateWord, _repo.DeleteFrontier, _repo.GetAllWords, GetFrontierCount, and GetFrontier to implement and verify the helper.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@Backend/Repositories/WordRepository.cs`:
- Around line 336-338: The XML <exception> on ReplaceFrontierWithSession
overstates missing-old-id failures: update the documentation for the
ReplaceFrontierWithSession method (and any duplicate exception tags for the same
method/overload) to only document guaranteed throw cases — e.g., when a
replacement word has a different ProjectId — and remove or rephrase the claim
that missing old IDs always throw, since the implementation calls
createIfNotFound: true and may create missing entries instead.
---
Nitpick comments:
In `@Backend.Tests/Repositories/WordRepositoryTests.cs`:
- Around line 349-368: Multiple tests repeat the same post-failure assertions
checking the repo was unchanged; extract those assertions into a reusable helper
to reduce duplication. Create a private helper method (e.g.,
AssertRepositoryUnchangedAfterFailedOperation) that takes the project id and
word id (and optionally the original created word) and performs the checks
currently repeated: calling _repo.GetAllWords(_projectId) and comparing Ids,
_repo.GetFrontierCount(_projectId), _repo.GetFrontier(_projectId, createdId) and
asserting frontierWord is not null and frontierWord.Accessibility is not
Status.Deleted; then replace the duplicated assertion blocks in
TestDeleteFrontierModifyActionThrowsLeavesRepoUnchanged and the other indicated
tests with a single call to this helper. Use the existing symbols CreateWord,
_repo.DeleteFrontier, _repo.GetAllWords, GetFrontierCount, and GetFrontier to
implement and verify the helper.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c3549509-20db-44df-95cc-fa7d5b09ac2d
📒 Files selected for processing (2)
Backend.Tests/Repositories/WordRepositoryTests.csBackend/Repositories/WordRepository.cs
Resolves #4183
Combines #4184, #4194, and #4196 for full testing and review.
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>https://app.devin.ai/review/sillsdev/TheCombine/pull/4198
This change is
Summary by CodeRabbit
New Features
Bug Fixes
Refactor
Tests
Documentation