Fix syncing components referencing moved senses#2250
Conversation
Reproduces a real sync failure where the snapshot has a component pointing to sense S on entry A, but in current FwData sense S has moved to entry B (e.g. after a merge). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The diff was using ComponentSenseId as the identity key, so when a sense moved to a different entry (same sense ID, different entry ID) it called Replace instead of remove+add, throwing "changing complex form components is not supported". Make IOrderableCollectionDiffApi generic over TId (matching CollectionDiffApi), so ComplexFormComponentsDiffApi can use (ComplexFormEntryId, ComponentEntryId, ComponentSenseId) as a composite key. Also relaxes the IOrderable constraint to IOrderableNoId, eliminating the OrderableWs wrapper. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
📝 WalkthroughWalkthroughThis PR refactors the orderable collection diffing system to support arbitrary non-nullable ID types beyond Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~55 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 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 docstrings
🧪 Generate unit tests (beta)
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 |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@backend/FwLite/MiniLcm/SyncHelpers/WritingSystemSync.cs`:
- Around line 78-82: The Remove(WritingSystem value) method in WritingSystemSync
currently returns Task.FromResult(0) which silently ignores deletion; change it
to fail fast by throwing an appropriate exception (e.g., throw new
NotSupportedException("Deleting writing systems is not supported during sync.")
wrapped in a Task) so callers see the limitation; update the
Remove(WritingSystem value) implementation to return a failed Task (or use
Task.FromException) with a clear message and remove the misleading TODO/comment
if desired.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
Run ID: 5130c46b-d1fe-47c5-bcd5-49cdd63eccb3
📒 Files selected for processing (7)
backend/FwLite/FwLiteProjectSync.Tests/EntrySyncTests.csbackend/FwLite/MiniLcm.Tests/DiffCollectionTests.csbackend/FwLite/MiniLcm.Tests/TestOrderableDiffApi.csbackend/FwLite/MiniLcm/SyncHelpers/DiffCollection.csbackend/FwLite/MiniLcm/SyncHelpers/EntrySync.csbackend/FwLite/MiniLcm/SyncHelpers/ExampleSentenceSync.csbackend/FwLite/MiniLcm/SyncHelpers/WritingSystemSync.cs
|
I just checked in FieldWorks Language Explorer. If an entry has more than one sense then each of its senses has a submenu "Move Sense to a New Entry". This creates a new entry with the same lexeme form and citation form (in fact, it copies all the entry-level fields), making the new entry a homograph of the old one and assigning homograph numbers immediately. You cannot move a sense to a different existing entry, though: it has to be "create a new entry for this sense". The intended purpose appears to be "Wait, I have 'bank' as a verb, to tilt an airplane, and 'bank' as a noun, a place to store money, in the same dictionary entry. Those aren't really the same word, they're two different words that happen to be spelled the same. I should separate those meanings." I had not realized that the sense's GUID would remain the same when that happens, but it does make sense now that I think about it, because other objects (like the grammatical categories and example sentences) depend on that sense (and reference it by GUID), so if the sense's GUID changed then all those other objects would need to be updated as well, which would potentially balloon in complexity. |
|
This also means that the design we had for Language Forge, where senses did not have a truly independent ID of their own but only hung off their parent entry, was subtly wrong. And the MiniLcm API will probably need to change the |
rmunn
left a comment
There was a problem hiding this comment.
LGTM. Good work figuring that out.
Resolves: #2234
Apparently senses can sometimes/somehow move to a different entry.
That breaks an assumption I had made that senseId could be used to uniquely and consistently identify a complex-form-component. So, this PR does 3 things:
IOrderableCollectionDiffApito accept an ID type param, rather than only supporting Guids