Skip to content

[claude] Show homograph numbers on complex form badges - #2886

Closed
myieye wants to merge 1 commit into
claude/activity-6-change-headerfrom
claude/homograph-badges
Closed

myieye wants to merge 1 commit into
claude/activity-6-change-headerfrom
claude/homograph-badges

Conversation

@myieye

@myieye myieye commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator

[Claude, autonomous]

Complex-form and component badges in the entry editor now show the linked entry's homograph number (bank₂), using the shared HomographNumber.svelte. To support this, ComplexFormComponent gets two read-time fields, ComplexFormHomographNumber and ComponentHomographNumber. They are filled on read and are never stored or synced. No change payload, no migration.

Pre-Flight Check

flowchart LR
  M[MiniLcm model<br/>ComplexFormComponent] --> C[LcmCrdt<br/>linq2db expression + EF Ignore]
  M --> F[FwDataMiniLcmBridge<br/>ILexEntry.HomographNumber]
  M --> T[TypeGen<br/>IComplexFormComponent.ts]
  M --> O[LexBoxApi OpenAPI schema]
  T --> V[Viewer badges]
  S[EntrySync / FwLiteProjectSync] -.untouched.-> M
Loading
  • MiniLcm ComplexFormComponent: adds the two int fields, and sets them in FromEntries and Copy(). They are [JsonIgnore(WhenWritingDefault)], so the default 0 isn't written.
  • LcmCrdt LcmCrdtKernel: linq2db computes them with IsExpression(..., isColumn: true) from the existing QueryComponentEntry / QueryComplexFormEntry associations (wrapped in COALESCE(..., 0)), the same way the headwords are computed. EF Ignores them, so there's no column and the EF model snapshot doesn't change. AddEntryComponentChange doesn't set them.
  • LcmCrdt CrdtComplexFormComponentApi.CreateComplexFormComponent: now returns the component from a new linq2db read, MiniLcmRepository.GetComplexFormComponent. The old EF read returned the stored headwords and 0 for the numbers. FwData already returned a live read. The Submit*/Move/Delete paths still use the EF FindComplexFormComponent.
  • FwDataMiniLcmBridge ToEntryReference / ToSenseReference: read HomographNumber from the ILexEntry.
  • Sync (EntrySync, CrdtFwdataProjectSyncService): not changed. Components are still keyed by GUIDs and Replace ignores everything else.
  • TypeGen: a property marked JsonIgnore(WhenWritingDefault) is exported as optional (ForceNullable), because JS gets undefined when the value is 0.

Why [MiniLcmInternal] isn't used

[MiniLcmInternal] hides a member from the external JSON options. Those are the options JS interop uses (FwLiteJson), and the TS generator skips the member too. So the viewer would never see the fields.

Why JsonIgnore(WhenWritingDefault)

Harmony snapshots, the sync ProjectSnapshot and the regression fixtures all serialize this model. If a 0 were written for every component, the snapshot regression data, the migration fixtures and the sena-3 snapshots would all change. Leaving the 0 out means Harmony snapshots, where the fields are always 0, serialize exactly as before. Only a ProjectSnapshot taken from live reads carries non-zero values. That's why the sena-3-live_snapshot fixture gains six lines.

Why the headword strings were left unchanged

  • ComplexFormHeadword is the sort key for complex forms (QueryHelpers.ComplexFormComparer, EntrySearchService), and FieldWorks sorts them alphabetically. A subscript would change that order.
  • The conformance tests require both implementations to return the same headwords (ComplexFormComponentHeadwords_UpdateWhenReferencedEntriesChange). FwData's LexEntryHeadwordOrUnknown and CRDT's QueryHeadwordWithTokens agree on plain headwords. Adding formatting in both would make that harder to keep true.
  • Display formatting stays out of the data. The UI decides how to show the number, as it already does for entries (HomographNumber.svelte, homographSubscript).

Hand-edited generated files

There is no .NET SDK in the authoring environment, so these were edited by hand to match what the generators should produce. task check-generated / fw-lite:has-stale-generated-types on CI will confirm or correct them:

  • frontend/viewer/.../MiniLcm/Models/IComplexFormComponent.ts: complexFormHomographNumber?: number and componentHomographNumber?: number, in declaration order. They are optional because of the ForceNullable rule above.
  • backend/LexBoxApi/openapi/public.yaml: the two properties, copied from Entry.homographNumber's int32 schema.
  • FwLiteProjectSync.Tests/sena-3-live_snapshot.verified.txt: the six components whose linked entry has a non-zero homograph number, computed from the entries in the same file.

Tests

  • ComplexFormComponentTestsBase (runs against CRDT and FwData):
    • ComplexFormComponentHomographNumbers_ComeFromReferencedEntries covers the create return value, both link directions, and a stale FromEntries input.
    • ComplexFormComponentHomographNumbers_UpdateWhenAHomographIsAdded covers promotion from 0 to 1.
  • MiniLcm.Tests/Models/ComplexFormComponentTests covers FromEntries, Copy() and JSON (0 is left out, other values round-trip).
  • The two fields are excluded in the global FluentAssertions config, next to Id/MaybeId. Faker-built expectations go stale when the APIs renumber homographs: CRDT promotes 0 to 1, and FwData runs CorrectHomographNumbers. Without the exclusion, every faker-based entry comparison would need its own exclusion. This also covers SyncTests, so no per-test SyncTests exclusion was added. The numbers are checked directly in the tests above.

Test plan

  • Viewer: svelte-check, eslint (only a warning in vitest.config.ts, which this PR doesn't touch), vitest unit (281 passed), and i18n extract with no en.po drift
  • CI (fw-lite.yaml, dispatched by hand because this PR is stacked): build, ComplexFormComponentTests (CRDT + FwData), ComplexFormComponentTests model tests, EntityCopyMethodTests, regression/Verified fixtures, Sena3SyncTests.LiveSena3Sync, stale generated types
  • task check-generated (OpenAPI drift)
  • Manual check: link two homograph entries as components / complex forms and confirm the subscripts appear on the badges

Not covered: the #2885 activity-header fallback and the diff-view badges read Harmony snapshots, which never carry these numbers. Where the current entry is available, the header already shows its homograph number through Headwords.


Generated by Claude Code

ComplexFormComponent gets read-time ComplexFormHomographNumber and
ComponentHomographNumber fields. LcmCrdt computes them with linq2db from
the referenced entries (EF ignores them, so no column or migration),
FwData reads them from ILexEntry.HomographNumber. No change sets them and
JSON skips the default 0, so Harmony snapshots don't carry them. CRDT's
CreateComplexFormComponent now returns a linq2db read so its result has
the numbers, as FwData's does.

The editor badges render them with HomographNumber, and adding a link
fills them optimistically from the picked entry.

Generated TS types and the public OpenAPI schema are hand-edited (no .NET
SDK in this environment); the sena-3 live snapshot fixture gains the six
non-zero values.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AM78WBzrZB97vduoZFtHSr
@coderabbitai

coderabbitai Bot commented Oct 31, 2026

Copy link
Copy Markdown
Contributor

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • 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

@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 🔩 FW Lite Core Shared MiniLcm, CRDT and sync libraries that ship in both FW Lite and FwHeadless labels Oct 31, 2026
@myieye
myieye added this pull request to stack #2887 October 31, 2026 10:27

myieye commented Oct 31, 2026

Copy link
Copy Markdown
Collaborator Author

[Claude, autonomous]

Combined into #2889 with #2883 and #2885.


Generated by Claude Code

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

Labels

🔩 FW Lite Core Shared MiniLcm, CRDT and sync libraries that ship in both FW Lite and FwHeadless 💻 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.

2 participants