Skip to content

lims: the schema-driven RegisterClient/RegisterSample path never attaches the shared handler, so the GUI breaks after a form registration #309

Description

@Yaraslaut

Summary

In the shipped lims GUI, registering a client or a sample through the schema-driven form leaves the app in a broken state: the client id is never populated, the sample's shared handler is never attached, and every subsequent dispatch on it fails with handler not bound.

SamplePresenter::submitIfValid routes both RegisterClient and RegisterSample to the plain _creator handler, then calls refresh() on the shared _handler — which nothing ever attached.

Found while fixing #304 §A3 (silently swallowed form failures). Reported rather than folded in, per AGENTS.md: this is a routing defect, not an error-surface one.

Reproduction

Driven against the real bridges with a temporary probe (since removed):

clientId property after form-path RegisterClient: -1
sample reply ok=1 payload={"id":1,"clientId":1,"reference":"WW-1","state":"Registered",...}
after refresh: changes=0 fails=2 lastFail=handler not bound sampleMap=0

The action itself succeeds — the model creates the row and returns a correct payload. What fails is everything downstream of it in the client.

Why the typed invokables were masking it

SampleBridge::registerClient is the only dispatch that emits clientRegistered, and therefore the only thing that ever sets the clientId property that SampleView.qml:77 binds ("Latest client id: "). SampleBridge::registerSample is the only dispatch that leaves the shared handler attached.

Both look like redundant duplicates of the form path — morph#287 lists them as such — but they are not: they are the only paths that work. The form path is the broken one.

Consequences in the running app

  • SampleView's "Latest client id" label is permanently -1.
  • Registering a sample from the form never populates the sample property, so Main.qml's onSampleChanged cross-wiring never fires and the result surface never attaches.
  • Every form-path registration produces a spurious handler not bound error.

That last one was invisible before. The fix for #304 §A3 binds replyReceived, so these failures now reach the operator as a red error — correct behaviour surfacing a pre-existing defect, not a regression introduced by that change. Expect the error to become visible the moment that branch lands.

Interaction with morph#287

The two exemptions surviving on the #287 branch are keyed to exactly this: registerClient and registerSample remain exempt because they are the working paths, with reason strings naming the mechanism. Fixing this issue is what would let those two exemptions go.

Suggested fix direction

Route RegisterClient and RegisterSample through the shared handler in submitIfValid — the same handler the typed invokables use — so the form path leaves the client in the same state the typed path does. Then the typed invokables genuinely do become redundant and can be deleted, closing #287 to zero exemptions.

What would change the verdict

Close it if the form path is intended to be create-only, with attachment always driven separately — in which case SampleView.qml:77's clientId binding and Main.qml's onSampleChanged wiring are the things that need changing, and the intent belongs in examples/lims/README.md.

Related doc drift, already corrected

examples/lims/README.md claimed registerSample "does two dispatches: create on the plain handler, then attach the shared one". The code does one dispatch on the shared handler and relies on BridgeHandler::execute's ResultKeyed branch — gui_lib/sample_presenter.cpp:76-84 says so explicitly. Corrected on the #287 branch, since the exemption text there cites the same mechanism.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area: formsSubsystem: formsbugSomething isn't workingtriage: validWell-framed; implement as written

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions