From ced1f11cf473915e1071a1d5e747d5d3d9cdac5a Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 2 Sep 2026 13:51:13 +0000 Subject: [PATCH] docs(objectql): the ADR-0061 `$search` expansion over source columns is `$icontains`, and the `__search` reader is `expandSearchToFilter` MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two independent comment-only corrections in `packages/objectql/src/search-companion.ts`, zero behaviour: 1. The module docblock opened "`$search` (ADR-0061 Tier 1) is a `$contains` over source columns". Source-column clauses compile to `$icontains` (`search-filter.ts:109` / `:111`), adjudicated at `search-filter.ts:23`: "[#7641] The case-insensitive operator is `$icontains`, NOT `$contains`." Operator spelling only — the argument the sentence carries survives the correction unchanged (case folding does not transliterate, so `zhangwei` cannot hit a stored CJK original under either operator). 2. `provisionSearchCompanion`'s docblock named the companion column's only reader `buildSearchFilter`, which is not an export of `search-filter.ts`. The reader is `expandSearchToFilter`. The two remaining `$contains` in this file (`:237`, `:286`) describe the hidden `__search` companion clause, where the case-SENSITIVE operator is correct and deliberate (`search-filter.ts:137-143`, "Do not 'align' the two"). Untouched. Co-Authored-By: Claude Fable 5.1 Claude-Session: https://claude.ai/code/session_0112hMx9hjJ9BgB28X97DS68 --- .changeset/search-companion-docblock.md | 38 +++++++++++++++++++++++ packages/objectql/src/search-companion.ts | 4 +-- 2 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 .changeset/search-companion-docblock.md diff --git a/.changeset/search-companion-docblock.md b/.changeset/search-companion-docblock.md new file mode 100644 index 0000000000..0a9e7e68ce --- /dev/null +++ b/.changeset/search-companion-docblock.md @@ -0,0 +1,38 @@ +--- +'@objectstack/objectql': patch +--- + +docs(objectql): `search-companion.ts` — the ADR-0061 `$search` expansion over source columns is `$icontains`, and the companion column's reader is `expandSearchToFilter` (#13984) + +Comment-only, zero behaviour. Two independent corrections in one file, listed +separately because they are distinct claims: + +1. The module docblock opened with "`$search` (ADR-0061 Tier 1) is a `$contains` + over source columns". The source-column clauses compile to `$icontains`: + `fieldClausesForTerm` returns `{ [field]: { $icontains: term } }` + (`search-filter.ts:109` / `:111`), and the adjudication is recorded in that + file's own header at `:23` — "[#7641] The case-insensitive operator is + `$icontains`, NOT `$contains`." Only the operator spelling changed. The + argument the sentence carries is untouched and still holds: typing `zhangwei` + cannot hit a stored `张伟` under EITHER operator, because case folding does not + transliterate. That is why a false spelling survived inside a correct + argument. +2. `provisionSearchCompanion`'s docblock named the companion column's only + reader `buildSearchFilter`. That is not an export of `search-filter.ts` — or + of anything else in the repo. The reader is `expandSearchToFilter`, the name + the same file already uses 50 lines above. + +The two remaining `$contains` mentions in this file (`:237` and `:286`) describe +the hidden `__search` companion clause, where the case-SENSITIVE operator is +correct and deliberate: the column is a normalized blob already lowercase on +both sides, so `$contains` over two folded values is exact. `search-filter.ts` +says so in the imperative at `:137-143` — "Do not 'align' the two." A whole-file +find-and-replace here would turn two correct sentences false. They stay. + +Published rather than skipped because correction 2 reaches the shipped +declarations: it sits inside the JSDoc of the exported `provisionSearchCompanion`, +and the build emits it into `dist/util-*.d.ts` and `dist/util-*.d.mts` (measured, +with a positive control on an exported symbol's own doc line). Correction 1 does +not reach any declaration file — a floating module-level block followed by an +`import` is dropped by the declaration emitter — so on its own it would have been +a `skip-changeset` diff. diff --git a/packages/objectql/src/search-companion.ts b/packages/objectql/src/search-companion.ts index 0ec8c7f341..57b358a8d0 100644 --- a/packages/objectql/src/search-companion.ts +++ b/packages/objectql/src/search-companion.ts @@ -3,7 +3,7 @@ /** * Search-normalization companion column (`__search`) — pinyin recall (#2486). * - * `$search` (ADR-0061 Tier 1) is a `$contains` over source columns, so typing + * `$search` (ADR-0061 Tier 1) is a `$icontains` over source columns, so typing * the full pinyin (`zhangwei`) or initials (`zw`) of a CJK name ("张伟") can * never hit — the stored value is the CJK original. This module provides the * additive fix: a single hidden companion column per object that stores @@ -283,7 +283,7 @@ function isDdlManaged(schema: CompanionObjectMeta): boolean { * Unlike #6810 the index is NOT re-declared in the object's `indexes[]`, and * that is a measured difference rather than an omission. #6810's predicate is * `organization_id = ?` — equality, which a B-tree serves. This column's ONLY - * reader is `buildSearchFilter`, which emits `{ __search: { $contains: term } }` + * reader is `expandSearchToFilter`, which emits `{ __search: { $contains: term } }` * (`search-filter.ts`) — a leading-wildcard `LIKE '%term%'` that no B-tree can * answer, and `IndexSchema` spells nothing else (`name` / `fields` / `unique`; * no trigram/GIN method). Declaring one would buy write amplification on every