You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#4329 (closed by #4338) found <ListView searchableFields> unchecked on the react page surface and fixed that one prop by exporting the metadata rule's core (indexObjectSearchTargets + checkSearchableFieldList in validate-searchable-fields.ts) and running it from validate-react-page-props.ts — the gate that owns React block dataProps. But searchableFields was an instance, not the class. This issue is the central worklist for the class: every field-bearing prop in REACT_BLOCKS (packages/spec/src/ui/react-blocks.ts) that a react page can author and nothing resolves.
Today validate-react-page-props.ts checks: required bindings, prop typos, <ObjectChart> bindings (#3701/#3729), and <ListView searchableFields> (#4329). Everything else a block binds by field name ships exactly as typed — the same silent-skip-or-mismatch drift validate-page-field-bindings.ts already closes for the page-component properties bag, one surface over.
record:related_list branch of validate-page-field-bindings
renewals-pipeline.page.ts:125
<Block type="…"> (whole props bag, by registered type)
per type
COMPONENT_FIELD_SPECS table
none today
All live instances above resolve — like #4329, this is a gap to close before it bites, not a live bug.
⚠️ A contract conflict blocks one row
RecordRelatedListProps.objectName in the spec is the related object (component.zod.ts:86: "Related object name"), but the react overlay in react-blocks.ts declares objectName as "The parent object" — and the live page authors it the overlay's way: objectName="showcase_account" with columns={['name','status','total']} naming invoice fields. A naive resolve-columns-against-objectName would false-positive on total. Settle which object the react block's objectName names (and how the related object is bound on the react surface) before linting this block — that ambiguity is arguably an authoring-contract bug in its own right, since the generated contract (build-react-blocks-contract.ts) currently publishes both meanings under one prop name.
Method (established by #4338 — follow it, don't re-derive)
Share the core with the metadata twin wherever one exists, so the two surfaces agree on what counts as a field by construction — the way checkSearchableFieldList is now shared. A descriptor table keyed by tag (mirroring COMPONENT_FIELD_SPECS) keeps the sweep one-table-per-block.
Static literals only: a value from a variable, call, or behind a spread skips silently (ADR-0072 D1 — unresolvable is not wrong). Note the filters nuance: ['status','=',stage] has a static field position beside a non-static value, and staticValue currently bails on the whole array — per-position resolution is needed to check the common case.
Severity per the established calls: render-degrading props (columns/fields/sort) skip unknowns gracefully → warning, matching page-field-unknown. filters field-position misses widen or refuse the query → candidate for error, matching the validate-flow-template-paths filter-position call and the REST 读路径:searchFields / groupBy / aggregations 指向不存在的字段时被静默降级(#4226 收口后剩下的三条轴) #4254 request-time behavior.
Unify the system-fields set while sweeping: validate-react-page-props.ts and validate-page-field-bindings.ts still hand-copy SYSTEM_FIELDS, while validate-searchable-fields.ts derives it from the spec's FIELD_GROUP_SYSTEM_FIELDS + SystemFieldName (排查「手抄 spec 清单 + "keep in sync" 注释」模式:一天内确认三例,全部曾静默漂移 #3786's lesson). The copies should migrate to the derived set.
Suggested order
Settle the RecordRelatedListobjectName contract conflict (its own fix; unblocks that row).
Descriptor-table pass for the unambiguous props (ListView fields/columns/sort/grouping/userFilters, ObjectForm fields, RecordHighlights/Details/Path) at warning.
<Block type="…"> escape hatch, reusing COMPONENT_FIELD_SPECS by registered type.
SYSTEM_FIELDS derivation cleanup.
Acceptance: every field-bearing prop in REACT_BLOCKS is either resolved against its object or explicitly ledgered as skipped-with-reason; the example corpus stays green.
#4329 (closed by #4338) found
<ListView searchableFields>unchecked on the react page surface and fixed that one prop by exporting the metadata rule's core (indexObjectSearchTargets+checkSearchableFieldListinvalidate-searchable-fields.ts) and running it fromvalidate-react-page-props.ts— the gate that owns React block dataProps. ButsearchableFieldswas an instance, not the class. This issue is the central worklist for the class: every field-bearing prop inREACT_BLOCKS(packages/spec/src/ui/react-blocks.ts) that a react page can author and nothing resolves.Today
validate-react-page-props.tschecks: required bindings, prop typos,<ObjectChart>bindings (#3701/#3729), and<ListView searchableFields>(#4329). Everything else a block binds by field name ships exactly as typed — the same silent-skip-or-mismatch driftvalidate-page-field-bindings.tsalready closes for the page-componentpropertiesbag, one surface over.Inventory
<ListView fields>(interaction,string[])interfaceConfig.columns→page-field-unknowncrm-workbench.page.ts:74,task-desk.page.ts:45<ListView columns>(dataProp;string[]|{field}[])interfaceConfig.columnsrenewals-pipeline.page.ts:96<ListView sort / grouping / userFilters.fields>(+ legacyfilterableFields)interfaceConfig.sort/.userFilters.fields<ListView filters>(FilterArray — field positions)validate-flow-template-paths)renewals-pipeline.page.ts:95(['status','=',stage])<ObjectForm fields>,initialValueskeyselement:form→form-field-unknownfamily<RecordHighlights fields>objectNamerecord:highlightsinCOMPONENT_FIELD_SPECSrenewals-pipeline.page.ts:115<RecordDetails fields / hideFields / sections[].fields>objectNamerecord:details<RecordPath statusField>objectNamerecord:path<RecordRelatedList columns / sort / relationshipField>record:related_listbranch ofvalidate-page-field-bindingsrenewals-pipeline.page.ts:125<Block type="…">(whole props bag, by registered type)COMPONENT_FIELD_SPECStableAll live instances above resolve — like #4329, this is a gap to close before it bites, not a live bug.
RecordRelatedListProps.objectNamein the spec is the related object (component.zod.ts:86: "Related object name"), but the react overlay inreact-blocks.tsdeclaresobjectNameas "The parent object" — and the live page authors it the overlay's way:objectName="showcase_account"withcolumns={['name','status','total']}naming invoice fields. A naive resolve-columns-against-objectNamewould false-positive ontotal. Settle which object the react block'sobjectNamenames (and how the related object is bound on the react surface) before linting this block — that ambiguity is arguably an authoring-contract bug in its own right, since the generated contract (build-react-blocks-contract.ts) currently publishes both meanings under one prop name.Method (established by #4338 — follow it, don't re-derive)
checkSearchableFieldListis now shared. A descriptor table keyed by tag (mirroringCOMPONENT_FIELD_SPECS) keeps the sweep one-table-per-block.filtersnuance:['status','=',stage]has a static field position beside a non-static value, andstaticValuecurrently bails on the whole array — per-position resolution is needed to check the common case.warning, matchingpage-field-unknown.filtersfield-position misses widen or refuse the query → candidate forerror, matching thevalidate-flow-template-pathsfilter-position call and the REST 读路径:searchFields/groupBy/aggregations指向不存在的字段时被静默降级(#4226 收口后剩下的三条轴) #4254 request-time behavior.validate-react-page-props.tsandvalidate-page-field-bindings.tsstill hand-copySYSTEM_FIELDS, whilevalidate-searchable-fields.tsderives it from the spec'sFIELD_GROUP_SYSTEM_FIELDS+SystemFieldName(排查「手抄 spec 清单 + "keep in sync" 注释」模式:一天内确认三例,全部曾静默漂移 #3786's lesson). The copies should migrate to the derived set.Suggested order
RecordRelatedListobjectNamecontract conflict (its own fix; unblocks that row).ListView fields/columns/sort/grouping/userFilters,ObjectForm fields,RecordHighlights/Details/Path) atwarning.filtersper-position static resolution + severity decision.<Block type="…">escape hatch, reusingCOMPONENT_FIELD_SPECSby registered type.SYSTEM_FIELDSderivation cleanup.Acceptance: every field-bearing prop in
REACT_BLOCKSis either resolved against its object or explicitly ledgered as skipped-with-reason; the example corpus stays green.