Skip to content

Add variant support to FwLite (model, CRDT, FwData bridge, sync)#2408

Closed
myieye wants to merge 10 commits into
developfrom
feat/variants-backend
Closed

Add variant support to FwLite (model, CRDT, FwData bridge, sync)#2408
myieye wants to merge 10 commits into
developfrom
feat/variants-backend

Conversation

@myieye

@myieye myieye commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator

Adds variants end-to-end in the backend: one MiniLcm Variant link = one FieldWorks LexEntryRef (RefType=Variant), carrying per-link Types, HideMinorEntry and Comment so FLEx data round-trips losslessly. Entry gains VariantOf/Variants; VariantType is a first-class synced object. Design, decisions and behavioral differences vs complex forms are documented in backend/FwLite/VARIANTS.md.

  • Cycle guard mirrors liblcm's acyclicity over the combined complex-form + variant component graph (LexEntryRef.ValidateAddObjectInternal); chains are allowed, cycles/self-refs are not.
  • GetVariantTypes reads the possibility list flattened so the Irregularly Inflected Form subtypes (Plural/Past) are assignable — the headline use case (forum thread).
  • Sena-3 verified live db/snapshot regenerated: the project's real variants (custom "Pronunciation Variant" type) now import — diff inspected, purely additive. Blank-project template regenerated so new projects seed the 7 standard variant types.
  • Rollout: new Harmony change types — FwHeadless must deploy before/with a client release that writes variants; pre-variant clients can't deserialize them (same story as MorphTypes/Publications).
  • UI lands in the stacked follow-up PR.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Jul 4, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

This PR introduces variant relationships across the FieldWorks Lite stack: new Variant/VariantType domain models, CRDT storage/change types and migrations, FwData bridge mapping, bidirectional sync helpers, validators/normalization, API exposure (write API, notify wrapper, JS invokable, SignalR hub), and frontend TypeScript types with demo wiring, backed by extensive tests.

Changes

Variant relationship feature

Layer / File(s) Summary
Domain model and API contracts
MiniLcm/Models/Variant.cs, .../VariantType.cs, .../Entry.cs, .../IObjectWithId.cs, ProjectSnapshot.cs, IMiniLcmReadApi.cs, IMiniLcmWriteApi.cs, CreateEntryOptions.cs
Adds Variant/VariantType records, extends Entry with VariantOf/Variants, updates ProjectSnapshot with VariantTypes, and declares CRUD/link methods on read/write API interfaces.
CRDT changes, storage, migrations
LcmCrdt/Changes/*Variant*.cs, CrdtMiniLcmApi.cs, MiniLcmRepository.cs, LcmCrdtDbContext.cs, LcmCrdtKernel.cs, QueryHelpers.cs, EntryQueryHelpers.cs, Migrations/20260703134525_AddVariants.*, Templates/blank-project-template.json
Implements AddVariantChange/AddVariantTypeChange/RemoveVariantTypeChange/CreateVariantType, wires variant CRUD/linking into CrdtMiniLcmApi, EF model/migration for Variant/VariantType tables, and seeds default variant types.
FwData bridge mapping
FwDataMiniLcmApi.cs, UpdateProxy/UpdateVariantProxy.cs, UpdateProxy/UpdateVariantTypeProxy.cs, LfClassicMiniLcmApi.cs
Maps LCM LexEntryRef variant data to/from the new model, implements variant/variant-type CRUD and link management, and stubs classic API variant reads.
Sync orchestration
SyncHelpers/VariantSync.cs, .../VariantTypeSync.cs, .../EntrySync.cs, CrdtFwdataProjectSyncService.cs, DryRunMiniLcmApi.cs, Import/ResumableImportApi.cs, Import/ProjectImporter.cs, MiniLcmApiExtensions.cs
Adds variant/variant-type diffing and sync stages between CRDT and FwData, dry-run support, resumable-import caching, and project-import handling of VariantTypes.
Validation and normalization
Validators/VariantValidator.cs, .../VariantTypeValidator.cs, .../EntryValidator.cs, .../MiniLcmValidators.cs, .../MiniLcmApiValidationWrapper.cs, Normalization/MiniLcmApiWriteNormalizationWrapper.cs
Adds validation rules for variant self-references, duplicates, and content, plus NFD normalization of variant text fields.
Notification, JS invokable, hub
MiniLcmApiNotifyWrapper.cs, MiniLcmJsInvokable.cs, MiniLcmApiHubBase.cs
Exposes variant CRUD/link operations with change notifications, JS-callable wrappers, and a SignalR endpoint.
Backend tests and verified fixtures
*.Tests/**/Variant*.cs, *.verified.txt, *.verified.json
Adds unit/integration coverage for variant behavior across bridge, CRDT, sync, and validators, and regenerates verified migration/regression snapshots.
Frontend types and demo wiring
dotnet-types/generated-types/MiniLcm/Models/IVariant*.ts, IEntry.ts, IMiniLcmJsInvokable.ts, project/data/variant-types.ts, demo-entry-data.ts, in-memory-demo-api.ts, tests
Adds generated TS interfaces, useVariantTypes hook, demo variant data, and updates test/story fixtures with variant fields.

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related PRs

Suggested labels: 💻 FW Lite, 📦 Lexbox

Suggested reviewers: hahn-kev

Poem

A rabbit hops through fields of forms,
Linking variants past the norms,
CRDT and FwData now agree,
One link, two entries, types all free.
🐇✨ Hop, sync, and cheer—
Variants have landed here!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly summarizes the main change: adding variant support across FwLite backend layers.
Description check ✅ Passed The description is directly related to the changeset and accurately describes the end-to-end variant support work.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/variants-backend

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.

@github-actions github-actions Bot added 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included labels Jul 4, 2026
@argos-ci

argos-ci Bot commented Jul 4, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Jul 4, 2026, 2:08 PM

myieye and others added 9 commits July 4, 2026 15:37
One Variant link = one LexEntryRef (RefType=Variant) with per-link Types,
HideMinorEntry and Comment (LCM Summary), per VARIANTS.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Conformance suites for both IMiniLcmApi implementations, change/usage/serialization
tests, verified-file regens, AutoFaker support. LCM enforces acyclicity over the
combined complex-form + variant graph, so AddVariantChange mirrors that check.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Regenerated via ProjectTemplateTests.GenerateTemplate; new CRDT projects get the
7 standard FLEx variant types (well-known guids), matching FieldWorks.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Variant lists sort by composite key on both sides (deterministic, culture-free);
BulkCreateEntries emits variant links; regenerated Sena3 live db + snapshots —
sena-3's real variants (custom Pronunciation Variant type) now round-trip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A sense-targeted variant link is identified by its full composite key; the FwData
bridge matched by sense guid alone, so a moved sense made the sync drop the link
(new regression test covers both implementations).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@myieye myieye force-pushed the feat/variants-backend branch from 4722098 to a5a336f Compare July 4, 2026 13:38
@myieye myieye marked this pull request as ready for review July 4, 2026 13:38

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
frontend/viewer/src/project/demo/demo-entry-data.ts (2)

348-352: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Reuse UNSPECIFIED_VARIANT_TYPE_ID instead of re-hardcoding the guid.

variant-types.ts already exports UNSPECIFIED_VARIANT_TYPE_ID = '3942addb-99fd-43e9-ab7d-99025ceb0d4e'. This array re-declares the same literal, so if the well-known guid ever changes it must be updated in two places.

♻️ Proposed fix
+import {UNSPECIFIED_VARIANT_TYPE_ID} from '$project/data/variant-types';
+
 export const variantTypes: IVariantType[] = [
-  {id: '3942addb-99fd-43e9-ab7d-99025ceb0d4e', name: {en: 'Unspecified Variant'}},
+  {id: UNSPECIFIED_VARIANT_TYPE_ID, name: {en: 'Unspecified Variant'}},
   {id: '024b62c9-93b3-41a0-ab19-587a0030219a', name: {en: 'Dialectal Variant'}},
   {id: '0c4663b3-4d9a-47af-b9a1-c8565d8112ed', name: {en: 'Spelling Variant'}},
 ];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/viewer/src/project/demo/demo-entry-data.ts` around lines 348 - 352,
The `variantTypes` demo data is hardcoding the same UUID used by
`UNSPECIFIED_VARIANT_TYPE_ID`, so replace the literal in `demo-entry-data.ts`
with the exported constant from `variant-types.ts`. Update the `variantTypes`
array to reference `UNSPECIFIED_VARIANT_TYPE_ID` for the “Unspecified Variant”
entry and keep the other variant entries unchanged.

354-368: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Hardcoded array indices for seeding the demo variant pair are fragile.

entries[2]/entries[3] assume a fixed entries ordering. A later reorder or insertion earlier in the array would silently link the wrong entries as variant/main. Since this is demo-only seed data the impact is limited, but consider selecting entries by a stable id instead of index.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/viewer/src/project/demo/demo-entry-data.ts` around lines 354 - 368,
The demo variant seeding in demo-entry-data is relying on fragile fixed array
positions for entries[2] and entries[3]. Update the logic around
demoVariantEntry and demoMainEntry to select the intended entries by a stable
identifier or other explicit property instead of index, then keep the existing
demoVariant wiring to variantOf and variants using those resolved entries.
frontend/viewer/src/project/data/variant-types.ts (1)

1-11: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

UNSPECIFIED_VARIANT_TYPE_ID duplicated as a literal elsewhere.

The same GUID ('3942addb-99fd-43e9-ab7d-99025ceb0d4e') is hardcoded again in demo-entry-data.ts's variantTypes array instead of referencing this constant. Consider importing UNSPECIFIED_VARIANT_TYPE_ID there to avoid drift if the well-known guid ever needs updating.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/viewer/src/project/data/variant-types.ts` around lines 1 - 11, The
well-known variant GUID is duplicated as a hardcoded string instead of reusing
the shared constant. Update the `variantTypes` array in `demo-entry-data.ts` to
import and reference `UNSPECIFIED_VARIANT_TYPE_ID` from `variant-types.ts` so
the `useVariantTypes`/`UNSPECIFIED_VARIANT_TYPE_ID` source of truth stays
consistent and avoids drift.
backend/FwLite/MiniLcm.Tests/AutoFakerHelpers/EntryFakerHelper.cs (1)

31-47: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Inconsistent "false" handling vs. sibling flags.

The new createVariants: false branch explicitly clears entry.VariantOf/entry.Variants, but the sibling flags (createComponents, createComplexForms, createComplexFormTypes, createPublications) have no equivalent clearing when disabled — they leave AutoFaker-generated, uncommitted references in the entry. Worth confirming whether the other flags should behave the same way for consistency, or whether variants specifically need this due to the new cycle/reference validators added in this PR.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@backend/FwLite/MiniLcm.Tests/AutoFakerHelpers/EntryFakerHelper.cs` around
lines 31 - 47, The false-branch handling in EntryFakerHelper is inconsistent:
CreateVariantLinkEntry clears VariantOf/Variants when createVariants is
disabled, but the sibling flags in the same helper do not clear their
AutoFaker-generated collections. Review the CreateComplexFormComponentEntry,
CreateComplexFormTypes, and CreatePublications paths in EntryFakerHelper and
make their disabled behavior match the intended contract—either clear the
corresponding entry collections too, or keep the variant-only clearing if it is
required for the new validators and document that distinction.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs`:
- Around line 1479-1481: Add a validation in AddVariant before resolving target
so that when variant.MainSenseId is present it confirms the sense belongs to
variant.MainEntryId; otherwise reject the request before any mutation. Use the
existing AddVariant flow in FwDataMiniLcmApi and the
SenseRepository/EntriesRepository lookup path to compare the sense’s owning
entry against variant.MainEntryId, then only create the variant link if they
match so CreateVariant and UpdateVariant keep working with the same composite
key.

In `@backend/FwLite/LcmCrdt/Changes/Entries/AddVariantChange.cs`:
- Around line 45-54: The shouldBeDeleted check in AddVariantChange.NewEntity
does not treat a missing mainSense the same way as missing or deleted entry
records, so a dangling MainSenseId can keep the variant alive. Update the
condition around MainSenseId/MainSenseId.Value to consider mainSense being null
as deletion-equivalent, consistent with the variantEntry and mainEntry checks,
so the variant is marked deleted whenever the referenced sense is absent or
deleted.

In `@backend/FwLite/LcmCrdt/Migrations/20260703134525_AddVariants.cs`:
- Around line 95-107: Update the unique index definitions in AddVariants so
soft-deleted rows are excluded from uniqueness checks. In
20260703134525_AddVariants.cs, adjust both CreateIndex calls for
IX_Variants_VariantEntryId_MainEntryId and
IX_Variants_VariantEntryId_MainEntryId_MainSenseId to include DeletedAt IS NULL
in their filter alongside the existing MainSenseId condition. This keeps
AddVariantChange from failing when it writes a duplicate Variant with DeletedAt
set.

In `@backend/FwLite/MiniLcm/Validators/EntryValidator.cs`:
- Around line 25-31: The EntryValidator rules for e.Variants currently rely on
VariantValidator, which still permits an empty endpoint and lets VariantEntryId
be left blank. Add an explicit non-empty validation for the variant side in
EntryValidator alongside the existing NotBeVariantSelfReference and
HaveCorrectMainEntryReference checks, using the e.Variants RuleForEach chain so
incomplete variant links are rejected before SetValidator(new
VariantValidator()) runs.

In `@backend/FwLite/MiniLcm/Validators/MiniLcmApiValidationWrapper.cs`:
- Around line 132-155: The submit write paths are bypassing validation because
MiniLcmApiValidationWrapper only overrides the before/after update methods and
not the patch-based submit members. Add explicit overrides for
SubmitUpdateVariant and SubmitUpdateVariantType in MiniLcmApiValidationWrapper
so they validate the incoming update payload through VariantValidator-related
checks before forwarding to _api, and make sure the submit variants do not rely
on the default IMiniLcmWriteApi implementation path that skips this wrapper.

---

Nitpick comments:
In `@backend/FwLite/MiniLcm.Tests/AutoFakerHelpers/EntryFakerHelper.cs`:
- Around line 31-47: The false-branch handling in EntryFakerHelper is
inconsistent: CreateVariantLinkEntry clears VariantOf/Variants when
createVariants is disabled, but the sibling flags in the same helper do not
clear their AutoFaker-generated collections. Review the
CreateComplexFormComponentEntry, CreateComplexFormTypes, and CreatePublications
paths in EntryFakerHelper and make their disabled behavior match the intended
contract—either clear the corresponding entry collections too, or keep the
variant-only clearing if it is required for the new validators and document that
distinction.

In `@frontend/viewer/src/project/data/variant-types.ts`:
- Around line 1-11: The well-known variant GUID is duplicated as a hardcoded
string instead of reusing the shared constant. Update the `variantTypes` array
in `demo-entry-data.ts` to import and reference `UNSPECIFIED_VARIANT_TYPE_ID`
from `variant-types.ts` so the `useVariantTypes`/`UNSPECIFIED_VARIANT_TYPE_ID`
source of truth stays consistent and avoids drift.

In `@frontend/viewer/src/project/demo/demo-entry-data.ts`:
- Around line 348-352: The `variantTypes` demo data is hardcoding the same UUID
used by `UNSPECIFIED_VARIANT_TYPE_ID`, so replace the literal in
`demo-entry-data.ts` with the exported constant from `variant-types.ts`. Update
the `variantTypes` array to reference `UNSPECIFIED_VARIANT_TYPE_ID` for the
“Unspecified Variant” entry and keep the other variant entries unchanged.
- Around line 354-368: The demo variant seeding in demo-entry-data is relying on
fragile fixed array positions for entries[2] and entries[3]. Update the logic
around demoVariantEntry and demoMainEntry to select the intended entries by a
stable identifier or other explicit property instead of index, then keep the
existing demoVariant wiring to variantOf and variants using those resolved
entries.
🪄 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: 61e6aa41-388a-410b-aa71-150855376533

📥 Commits

Reviewing files that changed from the base of the PR and between a9cf4ca and a5a336f.

📒 Files selected for processing (87)
  • backend/FwLite/FwDataMiniLcmBridge.Tests/MiniLcmTests/VariantTests.cs
  • backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs
  • backend/FwLite/FwDataMiniLcmBridge/Api/UpdateProxy/UpdateVariantProxy.cs
  • backend/FwLite/FwDataMiniLcmBridge/Api/UpdateProxy/UpdateVariantTypeProxy.cs
  • backend/FwLite/FwLiteProjectSync.Tests/EntrySyncTests.cs
  • backend/FwLite/FwLiteProjectSync.Tests/Import/ResumableTests.cs
  • backend/FwLite/FwLiteProjectSync.Tests/Snapshots/sena-3_snapshot.2026-06-18.verified.txt
  • backend/FwLite/FwLiteProjectSync.Tests/SyncTests.cs
  • backend/FwLite/FwLiteProjectSync.Tests/UpdateDiffTests.cs
  • backend/FwLite/FwLiteProjectSync.Tests/VariantSyncTests.cs
  • backend/FwLite/FwLiteProjectSync.Tests/sena-3-live.verified.sqlite
  • backend/FwLite/FwLiteProjectSync.Tests/sena-3-live_snapshot.verified.txt
  • backend/FwLite/FwLiteProjectSync/CrdtFwdataProjectSyncService.cs
  • backend/FwLite/FwLiteProjectSync/DryRunMiniLcmApi.cs
  • backend/FwLite/FwLiteProjectSync/Import/ResumableImportApi.cs
  • backend/FwLite/FwLiteShared/Services/MiniLcmApiNotifyWrapper.cs
  • backend/FwLite/FwLiteShared/Services/MiniLcmJsInvokable.cs
  • backend/FwLite/FwLiteWeb/Hubs/MiniLcmApiHubBase.cs
  • backend/FwLite/LcmCrdt.Tests/Changes/ChangeDeserializationRegressionData.latest.verified.txt
  • backend/FwLite/LcmCrdt.Tests/Changes/UseChangesTests.cs
  • backend/FwLite/LcmCrdt.Tests/Changes/VariantChangeTests.cs
  • backend/FwLite/LcmCrdt.Tests/Data/MigrationTests.cs
  • backend/FwLite/LcmCrdt.Tests/Data/MigrationTests_FromScriptedDb.v1.ProjectSnapshot.verified.txt
  • backend/FwLite/LcmCrdt.Tests/Data/MigrationTests_FromScriptedDb.v1.Snapshots.verified.txt
  • backend/FwLite/LcmCrdt.Tests/Data/MigrationTests_FromScriptedDb.v2.ProjectSnapshot.verified.txt
  • backend/FwLite/LcmCrdt.Tests/Data/MigrationTests_FromScriptedDb.v2.Snapshots.verified.txt
  • backend/FwLite/LcmCrdt.Tests/Data/SnapshotDeserializationRegressionData.latest.verified.txt
  • backend/FwLite/LcmCrdt.Tests/Data/SnapshotDeserializationRegressionData.legacy.verified.txt
  • backend/FwLite/LcmCrdt.Tests/Data/VerifyRegeneratedSnapshotsAfterMigrationFromScriptedDb.v1.verified.json
  • backend/FwLite/LcmCrdt.Tests/Data/VerifyRegeneratedSnapshotsAfterMigrationFromScriptedDb.v2.verified.json
  • backend/FwLite/LcmCrdt.Tests/DataModelSnapshotTests.VerifyChangeModels.verified.txt
  • backend/FwLite/LcmCrdt.Tests/DataModelSnapshotTests.VerifyDbModel.verified.txt
  • backend/FwLite/LcmCrdt.Tests/DataModelSnapshotTests.VerifyIObjectWithIdModels.verified.txt
  • backend/FwLite/LcmCrdt.Tests/MiniLcmTests/VariantTests.cs
  • backend/FwLite/LcmCrdt.Tests/SnapshotAtCommitServiceTests.cs
  • backend/FwLite/LcmCrdt/Changes/CreateVariantType.cs
  • backend/FwLite/LcmCrdt/Changes/Entries/AddVariantChange.cs
  • backend/FwLite/LcmCrdt/Changes/Entries/AddVariantTypeChange.cs
  • backend/FwLite/LcmCrdt/Changes/Entries/RemoveVariantTypeChange.cs
  • backend/FwLite/LcmCrdt/CrdtMiniLcmApi.cs
  • backend/FwLite/LcmCrdt/Data/EntryQueryHelpers.cs
  • backend/FwLite/LcmCrdt/Data/MiniLcmRepository.cs
  • backend/FwLite/LcmCrdt/LcmCrdtDbContext.cs
  • backend/FwLite/LcmCrdt/LcmCrdtKernel.cs
  • backend/FwLite/LcmCrdt/Migrations/20260703134525_AddVariants.Designer.cs
  • backend/FwLite/LcmCrdt/Migrations/20260703134525_AddVariants.cs
  • backend/FwLite/LcmCrdt/Migrations/LcmCrdtDbContextModelSnapshot.cs
  • backend/FwLite/LcmCrdt/QueryHelpers.cs
  • backend/FwLite/LcmCrdt/Templates/blank-project-template.json
  • backend/FwLite/MiniLcm.Tests/AutoFakerHelpers/EntryFakerHelper.cs
  • backend/FwLite/MiniLcm.Tests/FluentAssertGlobalConfig.cs
  • backend/FwLite/MiniLcm.Tests/Validators/VariantTypeValidationTests.cs
  • backend/FwLite/MiniLcm.Tests/Validators/VariantValidationTests.cs
  • backend/FwLite/MiniLcm.Tests/VariantTestsBase.cs
  • backend/FwLite/MiniLcm/CreateEntryOptions.cs
  • backend/FwLite/MiniLcm/IMiniLcmReadApi.cs
  • backend/FwLite/MiniLcm/IMiniLcmWriteApi.cs
  • backend/FwLite/MiniLcm/Import/ProjectImporter.cs
  • backend/FwLite/MiniLcm/MiniLcmApiExtensions.cs
  • backend/FwLite/MiniLcm/Models/Entry.cs
  • backend/FwLite/MiniLcm/Models/IObjectWithId.cs
  • backend/FwLite/MiniLcm/Models/Variant.cs
  • backend/FwLite/MiniLcm/Models/VariantType.cs
  • backend/FwLite/MiniLcm/Normalization/MiniLcmApiWriteNormalizationWrapper.cs
  • backend/FwLite/MiniLcm/ProjectSnapshot.cs
  • backend/FwLite/MiniLcm/SyncHelpers/EntrySync.cs
  • backend/FwLite/MiniLcm/SyncHelpers/VariantSync.cs
  • backend/FwLite/MiniLcm/SyncHelpers/VariantTypeSync.cs
  • backend/FwLite/MiniLcm/Validators/EntryValidator.cs
  • backend/FwLite/MiniLcm/Validators/MiniLcmApiValidationWrapper.cs
  • backend/FwLite/MiniLcm/Validators/MiniLcmValidators.cs
  • backend/FwLite/MiniLcm/Validators/VariantTypeValidator.cs
  • backend/FwLite/MiniLcm/Validators/VariantValidator.cs
  • backend/FwLite/VARIANTS.md
  • backend/LfClassicData/LfClassicMiniLcmApi.cs
  • frontend/viewer/src/lib/dotnet-types/generated-types/FwLiteShared/Services/IMiniLcmJsInvokable.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/MiniLcm/Models/IEntry.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/MiniLcm/Models/IVariant.ts
  • frontend/viewer/src/lib/dotnet-types/generated-types/MiniLcm/Models/IVariantType.ts
  • frontend/viewer/src/lib/dotnet-types/index.ts
  • frontend/viewer/src/lib/utils.ts
  • frontend/viewer/src/project/data/index.ts
  • frontend/viewer/src/project/data/variant-types.ts
  • frontend/viewer/src/project/demo/demo-entry-data.ts
  • frontend/viewer/src/project/demo/in-memory-demo-api.ts
  • frontend/viewer/src/stories/editor/entity-primitives/entry-editor-primitive.stories.svelte
  • frontend/viewer/tests/entry-api-helper.ts

Comment thread backend/FwLite/FwDataMiniLcmBridge/Api/FwDataMiniLcmApi.cs Outdated
Comment thread backend/FwLite/LcmCrdt/Changes/Entries/AddVariantChange.cs
Comment thread backend/FwLite/LcmCrdt/Migrations/20260703134525_AddVariants.cs
Comment thread backend/FwLite/MiniLcm/Validators/EntryValidator.cs
Comment thread backend/FwLite/MiniLcm/Validators/MiniLcmApiValidationWrapper.cs
…riant entry id

Both implementations now reject a MainSenseId that belongs to a different entry
(fail before mutation); EntryValidator requires VariantEntryId on Variants items.
Also corrects the stale cycle-guard decision text in VARIANTS.md.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@myieye

myieye commented Jul 4, 2026

Copy link
Copy Markdown
Collaborator Author

Closing per the iterative review workflow (not merged, not abandoned): this backend step is now CodeRabbit-handled, Devin-clean and CI-green at 55d4485. The next PR carries this step plus the viewer UI on top; the steps will be reopened/merged one by one when review completes. See backend/FwLite/VARIANTS.md for the feature log.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related 📦 Lexbox issues related to any server side code, fw-headless included

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant