diff --git a/.changeset/24735-expression-form-help.md b/.changeset/24735-expression-form-help.md new file mode 100644 index 00000000000..cb02773d6fe --- /dev/null +++ b/.changeset/24735-expression-form-help.md @@ -0,0 +1,6 @@ +--- +'@objectstack/spec': patch +'@objectstack/platform-objects': patch +--- + +Field and object designer forms: the `expression` help text now states what the engine does instead of claiming the expression "makes it read-only". On a `formula` field the expression is computed on read with no stored column; on any other field the engine computes it from the row each write stores and stores the result, so a client-sent value never stands (only `readonly: true` makes a client value a readonly drop). The object designer's field grid now shows the `expression` row for every field type, as the field designer already did, since `FieldSchema` accepts `expression` on any type. The zh-CN, ja-JP and es-ES translations of both rows are updated to match. diff --git a/packages/lint/src/validate-predicate-path-refs.test.ts b/packages/lint/src/validate-predicate-path-refs.test.ts index 1866c338b79..628cd97b4e4 100644 --- a/packages/lint/src/validate-predicate-path-refs.test.ts +++ b/packages/lint/src/validate-predicate-path-refs.test.ts @@ -682,7 +682,12 @@ describe('#7010 corpus — shipped METADATA_FORM_REGISTRY', () => { // It is 89 today, an ADDITION of ONE: #23735 offered the field form's // `referenceDeletedWhen` composite row, gated like `referenceVia` on // `data.type == 'text'`. It reaches the literal-comparison census below. - expect(predicates, 'the shipped metadata forms carry no predicates at all').toBe(89); + // It is 88 today, a REMOVAL of ONE: #24735 dropped the object form's + // `object :: expression :: data.type == 'formula'` gate. `FieldSchema` + // accepts `expression` on every type and the engine computes and stores it + // on a non-formula field, so the formula-only row hid a live key; the row + // is now shown for every type, as the field form's own row already was. + expect(predicates, 'the shipped metadata forms carry no predicates at all').toBe(88); const findings = validatePredicatePathRefs(corrupted); expect(findings).toHaveLength(predicates); @@ -793,7 +798,9 @@ describe('#7010 corpus — shipped METADATA_FORM_REGISTRY', () => { // `data.type == 'email'`, a single-quoted literal comparison. // It is 66 today: #23735's `field :: referenceDeletedWhen` row is gated on // `data.type == 'text'`, a single-quoted literal comparison. - expect(comparisons, 'no shipped predicate carries an `==`/`!=` literal comparison').toBe(66); + // It is 65 today: #24735 removed the object form's `expression` gate, + // `data.type == 'formula'`, one single-quoted literal comparison. + expect(comparisons, 'no shipped predicate carries an `==`/`!=` literal comparison').toBe(65); const rhsFindings = validatePredicatePathRefs(corrupted) .filter((f) => f.rule === PREDICATE_RHS_PATH_SHAPED); @@ -822,7 +829,9 @@ describe('#7010 corpus — shipped METADATA_FORM_REGISTRY', () => { // tree adds over its merge base — the two corpora were enumerated and // differenced by `