Skip to content

objectui: FilterConditionField cannot author spec’s $icontains — the case-insensitive contains is unreachable from the filter UI #6337

Description

@claude

Part of objectstack-ai/objectui#3567 (transferred to the main backlog by the triage seat — feature-level work lives in objectstack whatever repo the code lands in; see the multi-repo coordination rule "One main backlog").

Blocked-by: #5702

What is missing

packages/spec's FieldOperatorsSchema gained $icontains (case-insensitive contains, spec describe: "folds ASCII case") between 17.0.0-rc.2 and rc.5. objectui's FilterConditionField has no builder operator that can author it, so the capability is unreachable from the filter UI. The existing bidirectional parity test in packages/fields/src/widgets/__tests__/FilterConditionField.operators.test.ts ("every spec field operator is reachable from the builder", objectui#2942) went red on the rc.5 bump and was handled by objectui#3560 as an explicit, ratcheted KNOWN_UNREACHABLE entry rather than a silent exclusion.

Deliverable (lands in objectui)

  1. Add a case-insensitive contains operator to the FilterConditionField builder vocabulary; condToMongo emits { field: { $icontains: value } }.
  2. kvToCondition reads it back — without the reverse mapping a saved filter view degrades on reopen.
  3. Ten locale packs gain the label key (the t() call-site key gate, objectui#3547).
  4. Remove the $icontains entry from KNOWN_UNREACHABLE in FilterConditionField.operators.test.ts; the parity assertion then takes over, and objectui#3560's ratchet simultaneously validates that the removal was legitimate.

Why this is blocked, and it is not the reason the filing issue gave

⚠️ The originating issue states the server already accepts $icontains. Half true, and the half that is false is the blocking half. Measured against objectstackorigin/main:

So the spec vocabulary accepts the token while no driver can execute it. Shipping the builder operator first would put a filter in users' hands that every backend fails — strictly worse than the capability being absent. This card returns to the queue when #5702 merges.

Open product question (default recorded, not blocking)

Should today's contains have been case-insensitive all along? If so, the better shape is to have contains emit $icontains and add an explicit containsCaseSensitive for $contains — but that changes the behaviour of stored filter views, so it needs the maintainer. Default for this card: add a new operator, leave contains semantics untouched. A dev implements the default; if the maintainer wants the flip, say so here first and this card is re-scoped (it would then move to the decision inbox).

Provenance

Measured during objectui#3560 (@objectstack/* family bump to 17.0.0-rc.5). Not a regression introduced by that bump — a capability gap it exposed. Original filing: objectstack-ai/objectui#3567.


Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions