Skip to content

finding(app-shell): saveFields rebuilds every field entry from the designer model, so per-FIELD server keys are dropped on every field save #6488

Description

@claude

Found while implementing objectui#6240 (the object payload's fields array-to-map conversion). Filed, not fixed — a different level from the container shape that card is about, and a different level from objectui#6480.

What it is

MetadataService.saveFields preserves unknown keys of the fetched OBJECT document by spreading it:

constupdatedObject={ ...existingObject,name: objectName,fields: <rebuilt>};

That spread is object-level only. The fields value is rebuilt entirely from DesignerFieldDefinitions via toFieldPayload, so every key the SERVER sent inside a field and the designer does not model is dropped: expression (a formula authored in metadata-admin), precision / scale, system, sortable, and anything a plugin registered.

Why now

The loss is not new, but it was unreachable. While fields went out as an ARRAY the whole body was refused 422 INVALID_METADATA (invalid_type @ fields) before persistence, so nothing saveFields dropped ever reached storage. objectui#6240 makes the body parse, so from that fix onward the drop lands.

The correct form is already in the repo

The sibling writer solves exactly this. MetadataFieldsPage.handleFieldsChange carries the previous server entry into the new one:

nextFields[f.name]=fromDesignerField(f,prevFields[f.name]);// fromDesignerField spreads carryOver(prev)

saveFields already fetches the same document (client.meta.getItem('object', objectName)) for the object-level spread, so the per-field previous entries are in hand at the same moment — there is nothing extra to fetch.

Not objectui#6480

objectui#6480 is the OBJECT-level spread: read decorations (_diagnostics, _draft) that the served document carries and ObjectSchema refuses by name. This is the FIELD level and the opposite direction — keys that should survive and do not. The two edit neighbouring expressions and should not be folded together.

Refs: objectui#6240 (the conversion that makes this reachable) · objectui#6480 (the object-level half)


Generated by Claude Code

Metadata

Metadata

Assignees

Labels

domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:dispatched

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions