Filed from the reference app while slimming src/objects/ comments (objectstack-ai/hotcrm#1184). The app built this, measured it in the browser on 17.1.0, and did not ship it — and the note explaining why not is now permanent prose in src/objects/event_attendee.object.ts, warning the next author off a key the spec offers.
The shape
crm_event_attendee is a type-discriminator object: attendee_type names which ONE of four party columns (crm_contact, crm_lead, sys_user, external_name) is live, and two validations enforce it both ways — the named column must be filled, and no other may be.
The obvious form affordance is visibleWhen on each party column, so the three columns the chosen type does not name are hidden. That is precisely what cannot be done.
Measured on 17.1.0, in the browser
The Console hides a populated field without clearing it, and the value stays in form state and is submitted:
- Fill Contact.
- Change Attendee Type to Lead.
- The Contact column leaves the DOM. Its value does not leave form state.
POST {"attendee_type":"lead", …, "crm_contact":"AEwPffbkMvx-OlC4",
"crm_lead":"0AM_zbdjuLcXMdnL"}
400 An attendee names exactly one party — clear every party column
its Attendee Type does not name
The row is refused — correctly — by a message naming a column that is no longer on screen to clear.
On the EDIT path it is not a puzzle, it is a dead end: retyping a stored contact row to user re-sends the stored crm_contact on every attempt, and the Console offers no way to empty a field it is not rendering. The user cannot complete the edit at all.
Why the app cannot pair it into safety
Nothing in @objectstack/spec 17.1.0 or the shipped Console clears a value when its field goes invisible. There is no clearOnHide-shaped key on either surface. So an app that declares visibleWhen here has no way to make the write match what the user can see.
The app's shipped choice is therefore the worse-looking one and the strictly more usable one: leave all four columns visible, so the validation's message names something the person in front of the form can act on.
What would make the mistake impossible
Any one of these, in rough order of preference:
- Clear on hide. When a field's
visibleWhen goes false, drop its value from the submitted payload (and from form state). This is what an author declaring visibleWhen already believes is happening — the current behaviour is fail-open with respect to the author's stated intent.
- An explicit
clearOnHide: true on the field, if changing the default is too breaking. Opt-in is enough to close this; the app would take it today.
- Refuse the combination at author time. If neither is wanted, a
lint rule that flags visibleWhen on a field named by an exclusivity/requiredWhen pairing would at least stop the next author building it, measuring it, and writing the same paragraph again.
⚠️ This is the same fail-open/stale-state family as the note the app carries in src/views/lead.view.ts, so a fix likely wants to cover both.
Refs objectstack-ai/hotcrm#1184.
Filed from the reference app while slimming
src/objects/comments (objectstack-ai/hotcrm#1184). The app built this, measured it in the browser on 17.1.0, and did not ship it — and the note explaining why not is now permanent prose insrc/objects/event_attendee.object.ts, warning the next author off a key the spec offers.The shape
crm_event_attendeeis a type-discriminator object:attendee_typenames which ONE of four party columns (crm_contact,crm_lead,sys_user,external_name) is live, and two validations enforce it both ways — the named column must be filled, and no other may be.The obvious form affordance is
visibleWhenon each party column, so the three columns the chosen type does not name are hidden. That is precisely what cannot be done.Measured on 17.1.0, in the browser
The Console hides a populated field without clearing it, and the value stays in form state and is submitted:
The row is refused — correctly — by a message naming a column that is no longer on screen to clear.
On the EDIT path it is not a puzzle, it is a dead end: retyping a stored
contactrow touserre-sends the storedcrm_contacton every attempt, and the Console offers no way to empty a field it is not rendering. The user cannot complete the edit at all.Why the app cannot pair it into safety
Nothing in
@objectstack/spec17.1.0 or the shipped Console clears a value when its field goes invisible. There is noclearOnHide-shaped key on either surface. So an app that declaresvisibleWhenhere has no way to make the write match what the user can see.The app's shipped choice is therefore the worse-looking one and the strictly more usable one: leave all four columns visible, so the validation's message names something the person in front of the form can act on.
What would make the mistake impossible
Any one of these, in rough order of preference:
visibleWhengoes false, drop its value from the submitted payload (and from form state). This is what an author declaringvisibleWhenalready believes is happening — the current behaviour is fail-open with respect to the author's stated intent.clearOnHide: trueon the field, if changing the default is too breaking. Opt-in is enough to close this; the app would take it today.lintrule that flagsvisibleWhenon a field named by an exclusivity/requiredWhenpairing would at least stop the next author building it, measuring it, and writing the same paragraph again.src/views/lead.view.ts, so a fix likely wants to cover both.Refs objectstack-ai/hotcrm#1184.