From 466585cdebd3ec2f731b24512cf167ccfa3cf211 Mon Sep 17 00:00:00 2001 From: Tim Haasdyk Date: Tue, 25 Nov 2025 10:57:20 +0100 Subject: [PATCH 1/6] Set PartOfSpeech object in snapshots --- backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs | 5 ++++- backend/FwLite/LcmCrdt/Changes/SetPartOfSpeechChange.cs | 4 ++-- backend/FwLite/MiniLcm/Models/Sense.cs | 3 +++ 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs b/backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs index 3e139e9f55..a4b166b066 100644 --- a/backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs +++ b/backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs @@ -35,6 +35,8 @@ private CreateSenseChange(Guid entityId, Guid entryId) : base(entityId) public override async ValueTask NewEntity(Commit commit, IChangeContext context) { + var partOfSpeech = PartOfSpeechId is null ? null : await context.GetCurrent(PartOfSpeechId.Value); + partOfSpeech = partOfSpeech is { DeletedAt: not null } ? partOfSpeech : null; return new Sense { Id = EntityId, @@ -42,7 +44,8 @@ public override async ValueTask NewEntity(Commit commit, IChangeContext c Order = Order, Definition = Definition ?? new(), Gloss = Gloss ?? new MultiString(), - PartOfSpeechId = await context.DeletedAsNull(PartOfSpeechId), + PartOfSpeech = partOfSpeech, + PartOfSpeechId = partOfSpeech?.Id, SemanticDomains = await context.FilterDeleted(SemanticDomains ?? []).ToArrayAsync(), DeletedAt = await context.IsObjectDeleted(EntryId) ? commit.DateTime : (DateTime?)null }; diff --git a/backend/FwLite/LcmCrdt/Changes/SetPartOfSpeechChange.cs b/backend/FwLite/LcmCrdt/Changes/SetPartOfSpeechChange.cs index 4e3f9b53e1..2e79232068 100644 --- a/backend/FwLite/LcmCrdt/Changes/SetPartOfSpeechChange.cs +++ b/backend/FwLite/LcmCrdt/Changes/SetPartOfSpeechChange.cs @@ -13,6 +13,7 @@ public override async ValueTask ApplyChange(Sense entity, IChangeContext context if (PartOfSpeechId is null) { entity.PartOfSpeechId = null; + entity.PartOfSpeech = null; return; } @@ -24,7 +25,6 @@ public override async ValueTask ApplyChange(Sense entity, IChangeContext context return; } entity.PartOfSpeechId = partOfSpeech.Id; - //don't set the part of speech, it may trigger an insert of that part of speech - //I wasn't able to figure out how to write a test to cover this sadly, I only saw it live. + entity.PartOfSpeech = partOfSpeech; } } diff --git a/backend/FwLite/MiniLcm/Models/Sense.cs b/backend/FwLite/MiniLcm/Models/Sense.cs index dc6b301277..3c4016f13e 100644 --- a/backend/FwLite/MiniLcm/Models/Sense.cs +++ b/backend/FwLite/MiniLcm/Models/Sense.cs @@ -31,7 +31,10 @@ public void RemoveReference(Guid id, DateTimeOffset time) if (id == EntryId) DeletedAt = time; if (id == PartOfSpeechId) + { PartOfSpeechId = null; + PartOfSpeech = null; + } SemanticDomains = [..SemanticDomains.Where(sd => sd.Id != id)]; } From b1215faee21214f99c2e97618ea767d1221e8002 Mon Sep 17 00:00:00 2001 From: Tim Haasdyk Date: Tue, 25 Nov 2025 11:24:42 +0100 Subject: [PATCH 2/6] Add PartOfSpeech to sense tests base --- backend/FwLite/MiniLcm.Tests/SenseTestsBase.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/backend/FwLite/MiniLcm.Tests/SenseTestsBase.cs b/backend/FwLite/MiniLcm.Tests/SenseTestsBase.cs index 78d4d93e35..4d957b276b 100644 --- a/backend/FwLite/MiniLcm.Tests/SenseTestsBase.cs +++ b/backend/FwLite/MiniLcm.Tests/SenseTestsBase.cs @@ -4,10 +4,13 @@ public abstract class SenseTestsBase : MiniLcmTestBase { private static readonly Guid _entryId = Guid.NewGuid(); private static readonly Guid _senseId = Guid.NewGuid(); + private static readonly Guid _nounPosId = Guid.NewGuid(); public override async Task InitializeAsync() { await base.InitializeAsync(); + var nounPos = new PartOfSpeech() { Id = _nounPosId, Name = { { "en", "Noun" } } }; + await Api.CreatePartOfSpeech(nounPos); await Api.CreateEntry(new Entry() { Id = _entryId, @@ -15,7 +18,9 @@ await Api.CreateEntry(new Entry() Senses = [new() { Id = _senseId, - Gloss = { { "en", "new-sense-gloss" } } + Gloss = { { "en", "new-sense-gloss" } }, + PartOfSpeech = nounPos, + PartOfSpeechId = _nounPosId, }] }); } @@ -33,6 +38,10 @@ public async Task Get_ExistingSense_ReturnsSense() var sense = await Api.GetSense(_entryId, _senseId); sense.Should().NotBeNull(); sense.Gloss["en"].Should().Be("new-sense-gloss"); + sense.PartOfSpeech.Should().NotBeNull(); + sense.PartOfSpeech.Name["en"].Should().Be("Noun"); + sense.PartOfSpeech.Id.Should().Be(_nounPosId); + sense.PartOfSpeechId.Should().Be(_nounPosId); } /// From b3ab5ef98e86a68c866d2f7ba72af7e7b4f09d18 Mon Sep 17 00:00:00 2001 From: Tim Haasdyk Date: Tue, 25 Nov 2025 15:32:06 +0100 Subject: [PATCH 3/6] bump harmony --- backend/harmony | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/harmony b/backend/harmony index 0998577a4e..42209dea55 160000 --- a/backend/harmony +++ b/backend/harmony @@ -1 +1 @@ -Subproject commit 0998577a4e98acac2e33571a02a5c676abe143a0 +Subproject commit 42209dea552fabd332451c7e8d46fd0feaab2e03 From a8fbd903282088e625615ae34a9d945761533304 Mon Sep 17 00:00:00 2001 From: Tim Haasdyk Date: Fri, 28 Nov 2025 09:28:42 +0100 Subject: [PATCH 4/6] Fix part of speech deleted logic --- backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs b/backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs index a4b166b066..1043da4912 100644 --- a/backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs +++ b/backend/FwLite/LcmCrdt/Changes/CreateSenseChange.cs @@ -36,7 +36,7 @@ private CreateSenseChange(Guid entityId, Guid entryId) : base(entityId) public override async ValueTask NewEntity(Commit commit, IChangeContext context) { var partOfSpeech = PartOfSpeechId is null ? null : await context.GetCurrent(PartOfSpeechId.Value); - partOfSpeech = partOfSpeech is { DeletedAt: not null } ? partOfSpeech : null; + partOfSpeech = partOfSpeech is { DeletedAt: null } ? partOfSpeech : null; return new Sense { Id = EntityId, From d6fbae57080b39ca7cd8655d3d45b0fed8de8aec Mon Sep 17 00:00:00 2001 From: Tim Haasdyk Date: Fri, 28 Nov 2025 11:09:04 +0100 Subject: [PATCH 5/6] Verify new snapshot result --- ...dSnapshotsAfterMigrationFromScriptedDb.v2.verified.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/backend/FwLite/LcmCrdt.Tests/Data/VerifyRegeneratedSnapshotsAfterMigrationFromScriptedDb.v2.verified.json b/backend/FwLite/LcmCrdt.Tests/Data/VerifyRegeneratedSnapshotsAfterMigrationFromScriptedDb.v2.verified.json index 8b7c997c09..e3132fbc9f 100644 --- a/backend/FwLite/LcmCrdt.Tests/Data/VerifyRegeneratedSnapshotsAfterMigrationFromScriptedDb.v2.verified.json +++ b/backend/FwLite/LcmCrdt.Tests/Data/VerifyRegeneratedSnapshotsAfterMigrationFromScriptedDb.v2.verified.json @@ -688,6 +688,13 @@ "en": "Fruit", "fr": "fr" }, + "PartOfSpeech": { + "Id": "Guid_36", + "Name": { + "en": "Adverb" + }, + "Predefined": true + }, "PartOfSpeechId": "Guid_36", "SemanticDomains": [ { From 03f8ae6016a8565c3eadfc73c1ec0136dd7390a3 Mon Sep 17 00:00:00 2001 From: Tim Haasdyk Date: Fri, 28 Nov 2025 14:02:13 +0100 Subject: [PATCH 6/6] Reference harmony main --- backend/harmony | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/harmony b/backend/harmony index 42209dea55..1ac746273d 160000 --- a/backend/harmony +++ b/backend/harmony @@ -1 +1 @@ -Subproject commit 42209dea552fabd332451c7e8d46fd0feaab2e03 +Subproject commit 1ac746273dd4e46f68a7dc3006cd23c30cf9ae81