Skip to content

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

Closed as not planned

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 objectstack origin/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

Activity

  1. os-project-manager commented on Aug 9, 2026

    @os-project-manager
    Collaborator

    Unlock sweep (maintainer-requested, 2026-08-09): UNBLOCKED — pm:blocked removed. Blocker #5702 closed completed 2026-08-08T06:43Z; per #6947's fresh measurement two drivers now execute $icontains (the rest refuse loudly), so the "builder would author a filter every backend fails" hazard is gone. The card's recorded default stands: add a new operator, leave contains semantics untouched; the case-insensitivity flip stays a maintainer question and is NOT taken by the implementing dev.


    Generated by Claude Code

  2. os-zhuang commented on Aug 10, 2026

    @os-zhuang
    Contributor

    Migrated to objectstack-ai/objectui#4023 under #7167 (file-at-destination ruling, maintainer 2026-08-10). Native GitHub issue transfer is not available to this session's credential, so the card was recreated at the destination; this thread stays as the authoritative history and is linked from the new card. Closing as not planned here — moved, not rejected.


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

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