Skip to content

Field designer offers a formula control for formula fields — a key FieldSchema rejects by name (spec spells it expression), so saving a formula field hard-blocks the object #6043

Description

@yinlianghui-tw

Surfaced by the key-level parity gate built for #5761 (scripts/check-designer-field-key-parity.mjs). Filed rather than fixed, per #5761's ruling: the gate surfaces instances and each surfaced key gets its own card, because #4644indexed, #4687distance_metric and #4676placeholder took three different correct resolutions.

The key

formula is not in FieldSchema's accept set. Measured against the installed @objectstack/spec 17.2.0:

FieldSchema.safeParse({ type:'formula', label:'Tax', formula:'price * quantity' })
=> success = false
=> [{ code: 'unrecognized_keys', keys: ['formula'] }]

The spec carries two keys for this concept, and that is what makes it non-mechanical:

expression — Formula expression (CEL). e.g. F`record.amount * 0.1`
returnType — Inferred value type of a formula field (number/text/boolean/date)

Why this is live

  • packages/plugin-designer/src/FieldDesigner.tsx:312 — live textarea control, visibleWhen: "record.type == 'formula'", placeholder e.g. price * quantity.
  • packages/plugin-designer/src/FieldDesigner.tsx:222,243 — create and update paths both write it.
  • fromDesignerField (MetadataFieldsPage.tsx) and toFieldPayload (MetadataService.ts:105) both write it onto the shape that is PUT.

An author creating a formula field and typing an expression writes a key the API refuses: PUT /api/v1/meta/object/:name returns a hard 422 INVALID_METADATA that blocks every subsequent save of that object until the key is cleared.

Why a rename is not obviously the answer

Three things a resolver has to settle, none of which this tooling card can:

  1. Expression language. The designer's placeholder is price * quantity; the spec's expression is CEL, documented as F`record.amount * 0.1` — bare field names and a different root. Renaming the key alone would ship syntactically invalid expressions under a valid key name, trading a loud 422 for a silent runtime failure. That is strictly worse.
  2. returnType. The spec models it as a separate key the designer has no control for. Whether it is authored, inferred, or omitted is a design decision.
  3. The formulafield type itself (FieldDesigner.tsx:91,120) needs to be checked against the spec's FieldType vocabulary in the same pass.

The read direction is broken symmetrically too: toDesignerField reads raw.formula, but a spec-parsed server sends expression, so an existing formula field loads with an empty box.

Verification

pnpm check:designer-field-key-parity reports it; it is recorded in that gate's KNOWN_UNPARSEABLE_KEYS ledger pointing here. The ledger ratchets both ways, so a fix that leaves the entry behind is also red.

Refs: #5761 (the gate) · #4644 · #4687 · #4676

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingdomain: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