@open-mercato/core 0.6.3-develop.3753.1.29e9a20dde → 0.6.3-develop.3755.1.84e4410d84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -740,6 +740,7 @@ class HybridQueryEngine {
740
740
  const dekKeyCache = /* @__PURE__ */ new Map();
741
741
  if (encSvc?.decryptEntityPayload) {
742
742
  const decrypt = encSvc.decryptEntityPayload.bind(encSvc);
743
+ const fallbackOrgId = opts.organizationId ?? (Array.isArray(opts.organizationIds) && opts.organizationIds.length === 1 ? opts.organizationIds[0] : null);
743
744
  items = await Promise.all(
744
745
  items.map(async (item) => {
745
746
  try {
@@ -747,7 +748,7 @@ class HybridQueryEngine {
747
748
  entity,
748
749
  item,
749
750
  item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,
750
- item?.organization_id ?? item?.organizationId ?? null
751
+ item?.organization_id ?? item?.organizationId ?? fallbackOrgId ?? null
751
752
  );
752
753
  return { ...item, ...decrypted };
753
754
  } catch (err) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/query_index/lib/engine.ts"],
4
- "sourcesContent": ["import type { QueryEngine, QueryOptions, QueryResult, FilterOp, Filter, QueryCustomFieldSource, PartialIndexWarning, QueryExtensionsConfig } from '@open-mercato/shared/lib/query/types'\nimport { SortDir } from '@open-mercato/shared/lib/query/types'\nimport type { EntityId } from '@open-mercato/shared/modules/entities'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { BasicQueryEngine, resolveEntityTableName } from '@open-mercato/shared/lib/query/engine'\nimport { type Kysely, sql, type RawBuilder } from 'kysely'\nimport type { EventBus } from '@open-mercato/events'\nimport { readCoverageSnapshot, refreshCoverageSnapshot } from './coverage'\nimport { createProfiler, shouldEnableProfiler, type Profiler } from '@open-mercato/shared/lib/profiler'\nimport type { VectorIndexService } from '@open-mercato/search/vector'\nimport { decryptIndexDocCustomFields } from '@open-mercato/shared/lib/encryption/indexDoc'\nimport { parseBooleanToken, parseBooleanWithDefault } from '@open-mercato/shared/lib/boolean'\nimport {\n applyJoinFilters,\n normalizeFilters,\n partitionFilters,\n resolveJoins,\n type BaseFilter,\n type ResolvedJoin,\n} from '@open-mercato/shared/lib/query/join-utils'\nimport { resolveSearchConfig, type SearchConfig } from '@open-mercato/shared/lib/search/config'\nimport { tokenizeText } from '@open-mercato/shared/lib/search/tokenize'\nimport { runBeforeQueryPipeline, runAfterQueryPipeline, type QueryExtensionContext } from '@open-mercato/shared/lib/query/query-extension-runner'\n\nfunction buildFilterableCustomFieldJoins(\n sources: QueryCustomFieldSource[] | undefined,\n): Array<{\n alias: string\n table?: string\n entityId: EntityId\n from: { field: string }\n to: { field: string }\n type: 'left' | 'inner'\n}> {\n if (!sources || sources.length === 0) return []\n return sources.flatMap((source, index) => {\n if (!source.join) return []\n const alias = typeof source.alias === 'string' && source.alias.trim().length > 0\n ? source.alias.trim()\n : `cfs_${index}`\n return [{\n alias,\n table: source.table,\n entityId: source.entityId,\n from: { field: source.join.fromField },\n to: { field: source.join.toField },\n type: source.join.type === 'inner' ? 'inner' : 'left',\n }]\n })\n}\n\nfunction resolveBooleanEnv(names: readonly string[], defaultValue: boolean): boolean {\n for (const name of names) {\n const raw = process.env[name]\n if (raw !== undefined) return parseBooleanWithDefault(raw, defaultValue)\n }\n return defaultValue\n}\n\nfunction resolveDebugVerbosity(): boolean {\n const queryIndexDebug = process.env.OM_QUERY_INDEX_DEBUG\n if (queryIndexDebug !== undefined) {\n return parseBooleanToken(queryIndexDebug) ?? false\n }\n const level = (process.env.LOG_VERBOSITY ?? process.env.LOG_LEVEL ?? '').toLowerCase()\n if (['debug', 'trace', 'silly'].includes(level)) return true\n return false\n}\n\ntype AnyDb = Kysely<any>\ntype AnyBuilder = any\ntype NormalizedFilter = { field: string; op: FilterOp; value?: unknown }\ntype IndexDocSource = { alias: string; entityId: EntityId; recordIdColumn: string }\ntype PreparedCustomFieldSource = {\n alias: string\n indexAlias: string\n entityId: EntityId\n recordIdColumn: string\n organizationField?: string\n tenantField?: string\n table: string\n}\ntype SearchRuntime = {\n enabled: boolean\n config: SearchConfig\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n tenantId?: string | null\n searchSources?: SearchTokenSource[]\n}\n\ntype EncryptionResolver = () => {\n decryptEntityPayload?: (entityId: EntityId, payload: Record<string, unknown>, tenantId?: string | null, organizationId?: string | null) => Promise<Record<string, unknown>>\n isEnabled?: () => boolean\n} | null\n\ntype SearchTokenSource = { entity: string; recordIdColumn: string }\n\nfunction createQueryProfiler(entity: string): Profiler {\n const enabled = shouldEnableProfiler(entity)\n return createProfiler({\n scope: 'query_engine',\n target: entity,\n label: `query_engine:${entity}`,\n loggerLabel: '[qe:profile]',\n enabled,\n })\n}\n\nexport class HybridQueryEngine implements QueryEngine {\n private coverageStatsTtlMs: number\n private customFieldKeysCache = new Map<string, { expiresAt: number; value: string[] }>()\n private customFieldKeysTtlMs: number\n private columnCache = new Map<string, boolean>()\n private debugVerbosity: boolean | null = null\n private sqlDebugEnabled: boolean | null = null\n private forcePartialIndexEnabled: boolean | null = null\n private autoReindexEnabled: boolean | null = null\n private coverageOptimizationEnabled: boolean | null = null\n private pendingCoverageRefreshKeys = new Set<string>()\n private searchAliasSeq = 0\n\n constructor(\n private em: EntityManager,\n private fallback: BasicQueryEngine,\n private eventBusResolver?: () => Pick<EventBus, 'emitEvent'> | null | undefined,\n private vectorServiceResolver?: () => VectorIndexService | null | undefined,\n private encryptionResolver?: EncryptionResolver,\n ) {\n const coverageTtl = Number.parseInt(process.env.QUERY_INDEX_COVERAGE_CACHE_MS ?? '', 10)\n this.coverageStatsTtlMs = Number.isFinite(coverageTtl) && coverageTtl >= 0 ? coverageTtl : 5 * 60 * 1000\n const cfTtl = Number.parseInt(process.env.QUERY_INDEX_CF_KEYS_CACHE_MS ?? '', 10)\n this.customFieldKeysTtlMs = Number.isFinite(cfTtl) && cfTtl >= 0 ? cfTtl : 5 * 60 * 1000\n }\n\n private getEncryptionService() {\n try {\n return this.encryptionResolver?.() ?? null\n } catch {\n return null\n }\n }\n\n private getDb(): AnyDb {\n const emAny = this.em as any\n if (typeof emAny.getKysely === 'function') return emAny.getKysely() as AnyDb\n throw new Error('HybridQueryEngine requires an EntityManager exposing getKysely() (MikroORM v7)')\n }\n\n async query<T = unknown>(entity: EntityId, opts: QueryOptions = {}): Promise<QueryResult<T>> {\n const ext: QueryExtensionsConfig | undefined = opts.extensions\n let hybridExtCtx: QueryExtensionContext | null = null\n const noopDi = { resolve: <R = unknown>(_name: string): R => { throw new Error('No DI context') } }\n\n if (ext) {\n hybridExtCtx = {\n entity: String(entity),\n engine: 'hybrid',\n tenantId: opts.tenantId ?? '',\n organizationId: opts.organizationId,\n userId: ext.userId,\n em: this.em,\n container: ext.container,\n userFeatures: ext.userFeatures,\n }\n const diCtx = ext.resolve ? { resolve: ext.resolve } : noopDi\n const beforeResult = await runBeforeQueryPipeline(opts, hybridExtCtx, diCtx)\n if (beforeResult.blocked) {\n throw new Error(beforeResult.errorMessage ?? 'Query blocked by extension subscriber')\n }\n opts = beforeResult.query\n }\n const { extensions: _stripExt, ...coreOpts } = opts\n opts = coreOpts\n\n const providedProfiler = opts.profiler\n const profiler = providedProfiler && providedProfiler.enabled\n ? providedProfiler\n : createQueryProfiler(String(entity))\n profiler.mark('query:init')\n let profileClosed = false\n const finishProfile = (meta?: Record<string, unknown>) => {\n if (!profiler.enabled || profileClosed) return\n profileClosed = true\n profiler.end(meta)\n }\n\n const applyAfterExtensions = async <R>(queryResult: QueryResult<R>): Promise<QueryResult<R>> => {\n if (!ext || !hybridExtCtx) return queryResult\n const diCtx = ext.resolve ? { resolve: ext.resolve } : noopDi\n return await runAfterQueryPipeline(\n queryResult as QueryResult<Record<string, unknown>>,\n opts,\n hybridExtCtx,\n diCtx,\n ) as QueryResult<R>\n }\n\n try {\n const debugEnabled = this.isDebugVerbosity()\n if (debugEnabled) this.debug('query:start', { entity })\n this.searchAliasSeq = 0\n\n const isCustom = await this.isCustomEntity(entity)\n if (isCustom) {\n if (debugEnabled) this.debug('query:custom-entity', { entity })\n const section = profiler.section('custom_entity')\n try {\n const result = await this.queryCustomEntity<T>(entity, opts)\n section.end({ mode: 'custom_entity' })\n finishProfile({\n result: 'custom_entity',\n total: Array.isArray(result.items) ? result.items.length : undefined,\n })\n return await applyAfterExtensions(result)\n } catch (err) {\n section.end({ error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }\n\n const db = this.getDb()\n profiler.mark('query:db_ready')\n const baseTable = resolveEntityTableName(this.em, entity)\n profiler.mark('query:base_table_resolved')\n const searchConfig = resolveSearchConfig()\n const orgScope = this.resolveOrganizationScope(opts)\n const searchEnabled = searchConfig.enabled && await this.tableExists('search_tokens')\n\n const baseExists = await profiler.measure('base_table_exists', () => this.tableExists(baseTable))\n if (!baseExists) {\n if (debugEnabled) this.debug('query:fallback:missing-base', { entity, baseTable })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'missing_base' })\n return await applyAfterExtensions(fallbackResult)\n }\n\n if (opts.omitAutomaticTenantOrgScope === true) {\n if (debugEnabled) this.debug('query:fallback:omit-automatic-scope', { entity })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'omit_automatic_tenant_org_scope' })\n return await applyAfterExtensions(fallbackResult)\n }\n\n const normalizedFilters = normalizeFilters(opts.filters)\n const cfFilters = normalizedFilters.filter((filter) => filter.field.startsWith('cf:') || filter.field.startsWith('l10n:'))\n const coverageScope = this.resolveCoverageSnapshotScope(opts)\n const wantsCf = (\n (opts.fields || []).some((field) => typeof field === 'string' && (field.startsWith('cf:') || field.startsWith('l10n:'))) ||\n cfFilters.length > 0 ||\n (Array.isArray(opts.includeCustomFields) && opts.includeCustomFields.length > 0)\n )\n\n if (debugEnabled) {\n this.debug('query:config', {\n entity,\n wantsCustomFields: wantsCf,\n customFieldSources: Array.isArray(opts.customFieldSources) ? opts.customFieldSources.map((src) => src?.entityId) : undefined,\n fields: opts.fields,\n })\n }\n\n let partialIndexWarning: PartialIndexWarning | null = null\n let entityHasActiveCustomFields = true\n\n if (wantsCf) {\n entityHasActiveCustomFields = await this.entityHasActiveCustomFields(entity, opts.tenantId ?? null)\n const hasIndexRows = await profiler.measure(\n 'index_any_rows',\n () => this.indexAnyRows(entity),\n (value) => ({ hasIndexRows: value })\n )\n if (!hasIndexRows) {\n if (debugEnabled) this.debug('query:fallback:no-index', { entity })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'no_index_rows' })\n return await applyAfterExtensions(fallbackResult)\n }\n if (entityHasActiveCustomFields) {\n const gap = await profiler.measure(\n 'resolve_coverage_gap',\n () => this.resolveCoverageGap(entity, opts, coverageScope),\n (value) => (value\n ? {\n scope: value.scope,\n baseCount: value.stats?.baseCount ?? null,\n indexedCount: value.stats?.indexedCount ?? null,\n }\n : { scope: null })\n )\n if (gap) {\n if (!opts.skipAutoReindex) {\n this.scheduleAutoReindex(entity, opts, gap.stats, coverageScope?.organizationId ?? null)\n }\n const force = this.isForcePartialIndexEnabled()\n if (!force) {\n if (gap.stats) {\n console.warn('[HybridQueryEngine] Partial index coverage detected; falling back to basic engine:', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n if (debugEnabled) this.debug('query:fallback:partial-coverage', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n } else {\n console.warn('[HybridQueryEngine] Partial index coverage detected; falling back to basic engine:', { entity })\n if (debugEnabled) this.debug('query:fallback:partial-coverage', { entity })\n }\n const fallbackResult = await this.fallback.query(entity, opts)\n const resultWithWarning: QueryResult<T> = {\n ...fallbackResult,\n meta: {\n ...(fallbackResult.meta ?? {}),\n partialIndexWarning: {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n },\n },\n }\n finishProfile({\n result: 'fallback',\n reason: 'partial_index',\n scope: gap.scope,\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n })\n return await applyAfterExtensions(resultWithWarning)\n }\n if (gap.stats) {\n console.warn('[HybridQueryEngine] Partial index coverage detected; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n } else {\n console.warn('[HybridQueryEngine] Partial index coverage detected; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity })\n }\n partialIndexWarning = {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n }\n }\n } else if (debugEnabled) {\n this.debug('query:coverage:skip-no-custom-fields', { entity })\n }\n }\n\n const qualify = (col: string) => `b.${col}`\n const columns = await this.getBaseColumnsForEntity(entity)\n const hasOrganizationColumn = await this.columnExists(baseTable, 'organization_id')\n const hasTenantColumn = await this.columnExists(baseTable, 'tenant_id')\n const hasDeletedColumn = await this.columnExists(baseTable, 'deleted_at')\n\n if (!opts.tenantId) throw new Error('QueryEngine: tenantId is required')\n\n const resolvedJoinsConfig = resolveJoins(\n baseTable,\n [...(opts.joins ?? []), ...buildFilterableCustomFieldJoins(opts.customFieldSources)],\n (entityId) => resolveEntityTableName(this.em, entityId as any),\n )\n const joinMap = new Map<string, ResolvedJoin>()\n const aliasTables = new Map<string, string>()\n aliasTables.set('b', baseTable)\n aliasTables.set('base', baseTable)\n aliasTables.set(baseTable, baseTable)\n for (const join of resolvedJoinsConfig) {\n joinMap.set(join.alias, join)\n aliasTables.set(join.alias, join.table)\n }\n const { baseFilters, joinFilters } = partitionFilters(baseTable, normalizedFilters, joinMap)\n\n const searchRuntimeBase = {\n enabled: false,\n config: searchConfig,\n organizationScope: orgScope,\n tenantId: opts.tenantId ?? null,\n }\n\n // Prepare index sources for JSONB custom-field access.\n const indexSources: IndexDocSource[] = [{ alias: 'ei', entityId: entity, recordIdColumn: 'b.id' }]\n let preparedCfSources: PreparedCustomFieldSource[] = []\n const shouldAttachCustomSources = Array.isArray(opts.customFieldSources) && opts.customFieldSources.length > 0 && (wantsCf || searchEnabled)\n if (shouldAttachCustomSources) {\n preparedCfSources = this.prepareCustomFieldSources(opts.customFieldSources ?? [])\n for (const source of preparedCfSources) {\n indexSources.push({ alias: source.indexAlias, entityId: source.entityId, recordIdColumn: `${source.alias}.${source.recordIdColumn}` })\n }\n }\n\n const searchSources: SearchTokenSource[] = indexSources\n .map((src) => ({ entity: String(src.entityId), recordIdColumn: src.recordIdColumn }))\n .filter((src) => src.recordIdColumn && src.entity)\n const hasSearchTokens = searchEnabled && searchSources.length\n ? await this.searchSourcesHaveTokens(searchSources, opts.tenantId ?? null, orgScope)\n : false\n const searchRuntime: SearchRuntime = { ...searchRuntimeBase, searchSources, enabled: searchEnabled && hasSearchTokens }\n const joinSearchAvailability = new Map<string, boolean>()\n const searchFilters = normalizeFilters(opts.filters).filter((filter) => filter.op === 'like' || filter.op === 'ilike')\n if (searchFilters.length) {\n this.logSearchDebug('search:init', {\n entity,\n baseTable,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n fields: searchFilters.map((filter) => String(filter.field)),\n searchEnabled,\n hasSearchTokens,\n searchSources,\n searchConfig: {\n enabled: searchConfig.enabled,\n minTokenLength: searchConfig.minTokenLength,\n enablePartials: searchConfig.enablePartials,\n hashAlgorithm: searchConfig.hashAlgorithm,\n blocklistedFields: searchConfig.blocklistedFields,\n },\n })\n if (!searchEnabled) this.logSearchDebug('search:disabled', { entity, baseTable })\n else if (!hasSearchTokens) this.logSearchDebug('search:no-search-tokens', {\n entity, baseTable,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n searchSources,\n })\n }\n const hasNonBaseSearchSource = searchSources.some(\n (src) => src.entity !== String(entity) || src.recordIdColumn !== 'b.id'\n )\n\n // Additional partial-coverage checks for customFieldSources\n if (!partialIndexWarning && Array.isArray(opts.customFieldSources) && opts.customFieldSources.length > 0 && this.isForcePartialIndexEnabled()) {\n const seen = new Set<string>([entity])\n for (const source of opts.customFieldSources) {\n const targetEntity = source?.entityId ? String(source.entityId) : null\n if (!targetEntity || seen.has(targetEntity)) continue\n seen.add(targetEntity)\n const sourceHasCustomFields = await this.entityHasActiveCustomFields(targetEntity, opts.tenantId ?? null)\n if (!sourceHasCustomFields) {\n if (debugEnabled) this.debug('query:coverage:skip-no-custom-fields', { entity: targetEntity })\n continue\n }\n const sourceTable = source.table ?? resolveEntityTableName(this.em, targetEntity)\n try {\n const gap = await profiler.measure(\n 'resolve_coverage_gap',\n () => this.resolveCoverageGap(targetEntity, opts, coverageScope, sourceTable),\n (value) => (value\n ? {\n entity: targetEntity, scope: value.scope,\n baseCount: value.stats?.baseCount ?? null,\n indexedCount: value.stats?.indexedCount ?? null,\n }\n : { entity: targetEntity, scope: null })\n )\n if (!gap) continue\n if (!opts.skipAutoReindex) {\n this.scheduleAutoReindex(targetEntity, opts, gap.stats, coverageScope?.organizationId ?? null)\n }\n partialIndexWarning = {\n entity: targetEntity,\n entityLabel: this.resolveEntityLabel(targetEntity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n }\n if (debugEnabled) {\n if (gap.stats) this.debug('query:partial-coverage:forced', { entity: targetEntity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n else this.debug('query:partial-coverage:forced', { entity: targetEntity })\n }\n break\n } catch (err) {\n if (debugEnabled) this.debug('query:partial-coverage:check-failed', { entity: targetEntity, error: err instanceof Error ? err.message : err })\n }\n }\n }\n\n if (\n !partialIndexWarning &&\n wantsCf &&\n entityHasActiveCustomFields &&\n this.isForcePartialIndexEnabled() &&\n opts.tenantId\n ) {\n try {\n await this.indexCoverageStats(entity, opts, coverageScope)\n const globalStats = await this.indexCoverageStats(entity, opts, coverageScope)\n if (globalStats) {\n const globalBase = globalStats.baseCount\n const globalIndexed = globalStats.indexedCount\n const globalGap = (globalBase > 0 && globalIndexed < globalBase) || globalIndexed > globalBase\n if (globalGap) {\n console.warn('[HybridQueryEngine] Partial index coverage detected at global scope; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity, baseCount: globalBase, indexedCount: globalIndexed, scope: 'global' })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity, baseCount: globalBase, indexedCount: globalIndexed, scope: 'global' })\n partialIndexWarning = {\n entity, entityLabel: this.resolveEntityLabel(entity),\n baseCount: globalBase, indexedCount: globalIndexed, scope: 'global',\n }\n }\n }\n } catch (err) {\n if (debugEnabled) this.debug('query:partial-coverage:global-check-failed', { entity, error: err instanceof Error ? err.message : err })\n }\n }\n\n const resolveBaseColumn = (field: string): string | null => {\n if (columns.has(field)) return field\n if (field === 'organization_id' && columns.has('id')) return 'id'\n return null\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Build a reusable \"applyQueryShape\" function that applies every\n // WHERE/JOIN/scope to a fresh SelectQueryBuilder. We use this in\n // place of knex's `.clone()` for producing count + data queries.\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const applyBaseScope = (q: AnyBuilder): AnyBuilder => {\n let next = q\n if (orgScope && hasOrganizationColumn) {\n next = this.applyOrganizationScope(next, qualify('organization_id'), orgScope)\n }\n if (hasTenantColumn) {\n next = next.where(qualify('tenant_id'), '=', opts.tenantId)\n }\n if (!opts.withDeleted && hasDeletedColumn) {\n next = next.where(qualify('deleted_at'), 'is', null)\n }\n return next\n }\n\n const applyEntityIndexesJoin = (q: AnyBuilder): AnyBuilder => {\n return q.leftJoin('entity_indexes as ei', (jb: any) => {\n let jc = jb\n .on('ei.entity_type', '=', String(entity))\n .onRef('ei.entity_id', '=', sql<string>`(${sql.ref(qualify('id'))}::text)`)\n if (hasOrganizationColumn) {\n jc = jc\n .onRef('ei.organization_id', '=', qualify('organization_id'))\n .on('ei.organization_id', 'is not', null)\n }\n if (hasTenantColumn) {\n jc = jc\n .onRef('ei.tenant_id', '=', qualify('tenant_id'))\n .on('ei.tenant_id', 'is not', null)\n }\n if (!opts.withDeleted) {\n jc = jc.on('ei.deleted_at', 'is', null)\n }\n return jc\n })\n }\n\n const applyCustomFieldSourceJoins = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const source of preparedCfSources) {\n const join = (opts.customFieldSources ?? []).find((s) => s && (s.alias ?? undefined) === source.alias)?.join\n if (!join) continue\n const joinType = (join.type ?? 'left') === 'inner' ? 'innerJoin' : 'leftJoin'\n next = (next as any)[joinType](`${source.table} as ${source.alias}`, (jb: any) =>\n jb.onRef(`${source.alias}.${join.toField}`, '=', qualify(join.fromField)))\n // Index join for source\n next = next.leftJoin(`entity_indexes as ${source.indexAlias}`, (jb: any) => {\n let jc = jb\n .on(`${source.indexAlias}.entity_type`, '=', String(source.entityId))\n .onRef(`${source.indexAlias}.entity_id`, '=', sql<string>`(${sql.ref(`${source.alias}.${source.recordIdColumn}`)}::text)`)\n const orgRef = source.organizationField\n ? `${source.alias}.${source.organizationField}`\n : (columns.has('organization_id') ? qualify('organization_id') : null)\n if (orgRef) {\n jc = jc\n .onRef(`${source.indexAlias}.organization_id`, '=', orgRef)\n .on(`${source.indexAlias}.organization_id`, 'is not', null)\n }\n const tenantRef = source.tenantField\n ? `${source.alias}.${source.tenantField}`\n : (columns.has('tenant_id') ? qualify('tenant_id') : null)\n if (tenantRef) {\n jc = jc\n .onRef(`${source.indexAlias}.tenant_id`, '=', tenantRef)\n .on(`${source.indexAlias}.tenant_id`, 'is not', null)\n }\n if (!opts.withDeleted) jc = jc.on(`${source.indexAlias}.deleted_at`, 'is', null)\n return jc\n })\n }\n return next\n }\n\n const applyCfFilters = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const filter of cfFilters) {\n next = this.applyCfFilterAcrossSources(\n next, filter.field, filter.op, filter.value, indexSources, searchRuntime,\n )\n }\n return next\n }\n\n const regularBaseFilters = baseFilters.filter((filter) => !filter.orGroup)\n const orGroupFilters = baseFilters.filter((filter) => filter.orGroup)\n\n const applyRegularBaseFilters = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const filter of regularBaseFilters) {\n const fieldName = String(filter.field)\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) {\n next = this.applyIndexDocFilterFromAlias(\n next, 'ei', entity, fieldName, filter.op, filter.value, 'b.id', searchRuntime,\n )\n continue\n }\n const column = qualify(baseField)\n next = this.applyColumnFilter(next, column, filter, {\n ...searchRuntime,\n entity, field: fieldName, recordIdColumn: 'b.id',\n })\n }\n return next\n }\n\n const applyOrGroupedBaseFilters = (q: AnyBuilder): AnyBuilder => {\n if (orGroupFilters.length === 0) return q\n const groups = new Map<string, BaseFilter[]>()\n for (const filter of orGroupFilters) {\n if (!filter.orGroup) continue\n const existing = groups.get(filter.orGroup) ?? []\n existing.push(filter)\n groups.set(filter.orGroup, existing)\n }\n const groupList = Array.from(groups.values()).filter((g) => g.length > 0)\n if (groupList.length === 0) return q\n // Combine all groups in a single WHERE: disjuncts are OR'd together; within\n // each disjunct, fields are AND'd. Building this as separate `.where()` calls\n // would AND the disjuncts (wrong semantics).\n return q.where((eb: any) => eb.or(\n groupList.map((groupFilters) => {\n const parts = groupFilters.map((filter) =>\n this.buildBaseFilterExpression(eb, filter, resolveBaseColumn, qualify, entity, searchRuntime),\n )\n return parts.length === 1 ? parts[0] : eb.and(parts)\n }),\n ))\n }\n\n const applyAliasScopes = async (target: AnyBuilder, aliasName: string): Promise<AnyBuilder> => {\n let next = target\n const tableName = aliasTables.get(aliasName)\n if (!tableName) return next\n if (orgScope && await this.columnExists(tableName, 'organization_id')) {\n next = this.applyOrganizationScope(next, `${aliasName}.organization_id`, orgScope)\n }\n if (opts.tenantId && await this.columnExists(tableName, 'tenant_id')) {\n next = next.where(`${aliasName}.tenant_id`, '=', opts.tenantId)\n }\n if (!opts.withDeleted && await this.columnExists(tableName, 'deleted_at')) {\n next = next.where(`${aliasName}.deleted_at`, 'is', null)\n }\n return next\n }\n\n const applyJoinFilterOpFn = (target: AnyBuilder, column: string, op: FilterOp, value?: unknown): AnyBuilder => {\n switch (op) {\n case 'eq': return target.where(column, '=', value as any)\n case 'ne': return target.where(column, '!=', value as any)\n case 'gt': return target.where(column, '>', value as any)\n case 'gte': return target.where(column, '>=', value as any)\n case 'lt': return target.where(column, '<', value as any)\n case 'lte': return target.where(column, '<=', value as any)\n case 'in': return target.where(column, 'in', this.toArray(value))\n case 'nin': return target.where(column, 'not in', this.toArray(value))\n case 'like': return target.where(column, 'like', value as any)\n case 'ilike': return target.where(column, 'ilike', value as any)\n case 'exists': return value ? target.where(column, 'is not', null) : target.where(column, 'is', null)\n default: return target\n }\n }\n\n const applyJoinSearchFilterOp = async (\n target: AnyBuilder,\n filter: { column: string; op: FilterOp; value?: unknown },\n _qualified: string,\n join: ResolvedJoin,\n ): Promise<boolean> => {\n if (!searchEnabled || !join.entityId) return false\n if (!['like', 'ilike'].includes(filter.op)) return false\n if (typeof filter.value !== 'string' || filter.value.trim().length === 0) return false\n\n let searchAvailable = joinSearchAvailability.get(join.entityId)\n if (searchAvailable === undefined) {\n searchAvailable = await this.hasSearchTokens(String(join.entityId), opts.tenantId ?? null, orgScope)\n joinSearchAvailability.set(join.entityId, searchAvailable)\n }\n if (!searchAvailable) return false\n\n const tokens = tokenizeText(String(filter.value), searchConfig)\n if (!tokens.hashes.length) return false\n\n return this.applySearchTokens(target, {\n entity: String(join.entityId),\n field: filter.column,\n hashes: tokens.hashes,\n recordIdColumn: `${join.alias}.id`,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n })\n }\n\n const applyQueryShape = async (q: AnyBuilder): Promise<AnyBuilder> => {\n let next = applyBaseScope(q)\n next = applyEntityIndexesJoin(next)\n next = applyCustomFieldSourceJoins(next)\n next = applyCfFilters(next)\n next = applyRegularBaseFilters(next)\n next = applyOrGroupedBaseFilters(next)\n // applyJoinFilters is the shared helper that handles `joinFilters` (ALIAS:col -> value).\n next = await applyJoinFilters({\n db,\n baseTable,\n builder: next,\n joinMap,\n joinFilters,\n aliasTables,\n qualifyBase: (column) => qualify(column),\n applyAliasScope: async (target: any, alias: string) => applyAliasScopes(target as AnyBuilder, alias),\n applyFilterOp: (target, column, op, value) => applyJoinFilterOpFn(target as AnyBuilder, column, op, value),\n applyJoinFilterOp: async (target, filter, qualified, join) => {\n const applied = await applyJoinSearchFilterOp(target as AnyBuilder, filter, qualified, join)\n return { applied, builder: target }\n },\n columnExists: (tbl, column) => this.columnExists(tbl, column),\n })\n return next\n }\n\n const hasCustomFieldFilters = cfFilters.length > 0\n const canOptimizeCount = !hasCustomFieldFilters && !hasNonBaseSearchSource\n\n // Selection (for data query)\n const selectFieldSet = new Set<string>((opts.fields && opts.fields.length) ? opts.fields.map(String) : Array.from(columns.keys()))\n if (opts.includeCustomFields === true) {\n const entityIds = Array.from(new Set(indexSources.map((src) => String(src.entityId))))\n try {\n const resolvedKeys = await this.resolveAvailableCustomFieldKeys(entityIds, opts.tenantId ?? null)\n resolvedKeys.forEach((key) => selectFieldSet.add(`cf:${key}`))\n if (this.isDebugVerbosity()) this.debug('query:cf:resolved-keys', { entity, keys: resolvedKeys })\n } catch (err) {\n console.warn('[HybridQueryEngine] Failed to resolve custom field keys for', entity, err)\n }\n } else if (Array.isArray(opts.includeCustomFields)) {\n opts.includeCustomFields.map((key) => String(key)).forEach((key) => selectFieldSet.add(`cf:${key}`))\n }\n const selectFields = Array.from(selectFieldSet)\n\n const applySelection = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const field of selectFields) {\n const fieldName = String(field)\n if (fieldName.startsWith('cf:')) {\n const alias = this.sanitize(fieldName)\n const jsonExpr = this.buildCfJsonExprSql(fieldName, indexSources)\n const exprRaw = jsonExpr ?? sql`NULL::jsonb`\n next = next.select(exprRaw.as(alias))\n } else if (columns.has(fieldName)) {\n next = next.select(`${qualify(fieldName)} as ${fieldName}`)\n }\n }\n return next\n }\n\n const applySort = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const s of opts.sort || []) {\n const fieldName = String(s.field)\n if (fieldName.startsWith('cf:')) {\n const textExpr = this.buildCfTextExprSql(fieldName, indexSources)\n if (textExpr) {\n const direction = sql.raw(String(s.dir ?? SortDir.Asc))\n next = next.orderBy(sql`${textExpr} ${direction}`)\n }\n } else {\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) continue\n next = next.orderBy(qualify(baseField), s.dir ?? SortDir.Asc)\n }\n }\n return next\n }\n\n const page = opts.page?.page ?? 1\n const pageSize = opts.page?.pageSize ?? 20\n const sqlDebugEnabled = this.isSqlDebugEnabled()\n\n let total: number\n\n if (canOptimizeCount) {\n // Optimized count: apply only base-scope + regular filters + or-group filters (no index joins).\n const optimizedRoot = db.selectFrom(`${baseTable} as b` as any)\n let countCore = applyBaseScope(optimizedRoot)\n countCore = applyRegularBaseFilters(countCore)\n countCore = applyOrGroupedBaseFilters(countCore)\n // joinFilters still need to be re-applied in the optimized path\n countCore = await applyJoinFilters({\n db,\n baseTable,\n builder: countCore,\n joinMap,\n joinFilters,\n aliasTables,\n qualifyBase: (column) => qualify(column),\n applyAliasScope: async (target: any, alias: string) => applyAliasScopes(target as AnyBuilder, alias),\n applyFilterOp: (target, column, op, value) => applyJoinFilterOpFn(target as AnyBuilder, column, op, value),\n applyJoinFilterOp: async (target, filter, qualified, join) => {\n const applied = await applyJoinSearchFilterOp(target as AnyBuilder, filter, qualified, join)\n return { applied, builder: target }\n },\n columnExists: (tbl, column) => this.columnExists(tbl, column),\n })\n const sub = countCore.select(sql.ref(qualify('id')).as('id')).groupBy(qualify('id')).as('sq')\n const countQuery = db.selectFrom(sub as any).select(sql<string>`count(*)`.as('count'))\n if (debugEnabled && sqlDebugEnabled) {\n const compiled = countQuery.compile()\n this.debug('query:sql:count', { entity, sql: compiled.sql, bindings: compiled.parameters })\n }\n const countRow = await this.captureSqlTiming(\n 'query:sql:count', entity,\n () => countQuery.executeTakeFirst(),\n { optimized: true }, profiler,\n )\n total = this.parseCount(countRow)\n } else {\n const countRoot = db.selectFrom(`${baseTable} as b` as any)\n const countBuilder = (await applyQueryShape(countRoot))\n .select(sql<string>`count(distinct ${sql.ref(qualify('id'))})`.as('count'))\n if (debugEnabled && sqlDebugEnabled) {\n const compiled = countBuilder.compile()\n this.debug('query:sql:count', { entity, sql: compiled.sql, bindings: compiled.parameters })\n }\n const countRow = await this.captureSqlTiming(\n 'query:sql:count', entity,\n () => countBuilder.executeTakeFirst(),\n { optimized: false }, profiler,\n )\n total = this.parseCount(countRow)\n }\n\n const dataRoot = db.selectFrom(`${baseTable} as b` as any)\n let dataBuilder = await applyQueryShape(dataRoot)\n dataBuilder = applySelection(dataBuilder)\n dataBuilder = applySort(dataBuilder)\n dataBuilder = dataBuilder.limit(pageSize).offset((page - 1) * pageSize)\n\n if (debugEnabled && sqlDebugEnabled) {\n const compiled = dataBuilder.compile()\n this.debug('query:sql:data', { entity, sql: compiled.sql, bindings: compiled.parameters, page, pageSize })\n }\n const itemsRaw = await this.captureSqlTiming(\n 'query:sql:data', entity,\n () => dataBuilder.execute(),\n { page, pageSize }, profiler,\n )\n if (debugEnabled) this.debug('query:complete', { entity, total, items: Array.isArray(itemsRaw) ? itemsRaw.length : 0 })\n\n let items = itemsRaw as any[]\n const encSvc = this.getEncryptionService()\n const dekKeyCache = new Map<string | null, string | null>()\n if (encSvc?.decryptEntityPayload) {\n const decrypt = encSvc.decryptEntityPayload.bind(encSvc) as (\n entityId: EntityId, payload: Record<string, unknown>, tenantId: string | null, organizationId: string | null,\n ) => Promise<Record<string, unknown>>\n items = await Promise.all(\n items.map(async (item) => {\n try {\n const decrypted = await decrypt(\n entity, item,\n item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,\n item?.organization_id ?? item?.organizationId ?? null,\n )\n return { ...item, ...decrypted }\n } catch (err) {\n console.error('Error decrypting entity payload', err)\n return item\n }\n })\n )\n }\n if (encSvc) {\n items = await Promise.all(\n items.map(async (item) => {\n try {\n return await decryptIndexDocCustomFields(\n item,\n {\n tenantId: item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,\n organizationId: item?.organization_id ?? item?.organizationId ?? null,\n },\n encSvc as any, dekKeyCache,\n )\n } catch { return item }\n }),\n )\n }\n\n const typedItems = items as unknown as T[]\n let result: QueryResult<T> = { items: typedItems, page, pageSize, total }\n if (partialIndexWarning) result.meta = { partialIndexWarning }\n\n result = await applyAfterExtensions(result)\n finishProfile({\n result: 'ok', total, page, pageSize,\n itemCount: Array.isArray(items) ? items.length : undefined,\n partialIndexWarning: partialIndexWarning ? true : false,\n })\n return result\n } catch (err) {\n finishProfile({ result: 'error', error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }\n\n private prepareCustomFieldSources(\n sources: QueryCustomFieldSource[],\n ): PreparedCustomFieldSource[] {\n const prepared: PreparedCustomFieldSource[] = []\n sources.forEach((source, index) => {\n if (!source) return\n const joinTable = source.table ?? resolveEntityTableName(this.em, source.entityId)\n const alias = source.alias ?? `cfs_${index}`\n if (!source.join) {\n throw new Error(`QueryEngine: customFieldSources entry for ${String(source.entityId)} requires a join configuration`)\n }\n prepared.push({\n alias,\n indexAlias: `ei_${alias}`,\n entityId: source.entityId,\n recordIdColumn: source.recordIdColumn ?? 'id',\n organizationField: source.organizationField,\n tenantField: source.tenantField,\n table: joinTable,\n })\n })\n return prepared\n }\n\n private async isCustomEntity(entity: string): Promise<boolean> {\n try {\n const db = this.getDb() as any\n const row = await db\n .selectFrom('custom_entities')\n .select('id')\n .where('entity_id', '=', entity)\n .where('is_active', '=', true)\n .executeTakeFirst()\n return !!row\n } catch {\n return false\n }\n }\n\n /**\n * Adds a WHERE EXISTS / OR WHERE EXISTS subquery that matches\n * `search_tokens` for the supplied (entity, field) against the\n * provided record id column.\n *\n * Returns true when the sub-query was applied (i.e. tokens were\n * non-empty). Caller is responsible for the calling context\n * (direct where vs. inside `eb.or([...])`).\n */\n private applySearchTokens(\n q: AnyBuilder,\n opts: {\n entity: string\n field: string\n hashes: string[]\n recordIdColumn: string\n tenantId?: string | null\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n combineWith?: 'and' | 'or'\n }\n ): boolean {\n if (!opts.hashes.length) {\n this.logSearchDebug('search:skip-no-hashes', {\n entity: opts.entity, field: opts.field,\n tenantId: opts.tenantId ?? null, organizationScope: opts.organizationScope,\n })\n return false\n }\n const alias = `st_${this.searchAliasSeq++}`\n this.logSearchDebug('search:apply-search-tokens', {\n entity: opts.entity, field: opts.field, alias,\n tokenCount: opts.hashes.length,\n tenantId: opts.tenantId ?? null,\n organizationScope: opts.organizationScope,\n combineWith: opts.combineWith ?? 'and',\n })\n\n const engine = this\n const buildSub = (eb: any) => {\n let sub = eb\n .selectFrom(`search_tokens as ${alias}`)\n .select(sql<number>`1`.as('one'))\n .where(`${alias}.entity_type`, '=', opts.entity)\n .where(`${alias}.field`, '=', opts.field)\n .where(sql<boolean>`${sql.ref(`${alias}.entity_id`)} = ${sql.ref(opts.recordIdColumn)}::text`)\n .where(`${alias}.token_hash`, 'in', opts.hashes)\n .groupBy([`${alias}.entity_id`, `${alias}.field`])\n .having(sql<boolean>`count(distinct ${sql.ref(`${alias}.token_hash`)}) >= ${opts.hashes.length}`)\n if (opts.tenantId !== undefined) {\n sub = sub.where(sql<boolean>`${sql.ref(`${alias}.tenant_id`)} is not distinct from ${opts.tenantId ?? null}`)\n }\n if (opts.organizationScope) {\n sub = engine.applyOrganizationScope(sub, `${alias}.organization_id`, opts.organizationScope)\n }\n return sub\n }\n\n if (opts.combineWith === 'or') {\n // When called inside an .or([...]) array the caller supplied `eb`.\n // `q` is the ExpressionBuilder callable (eb) itself in that case.\n // We return the expression node rather than mutating q.\n ;(q as any).__pendingOrExists = buildSub(q)\n return true\n }\n\n // Default: append WHERE EXISTS (...) to the outer builder.\n ;(q as any).__applied = true\n const built = buildSub(q)\n // If q is a Kysely builder (has .where), use eb => eb.exists(sub)\n if (typeof q.where === 'function') {\n ;(q as any) = q.where((eb: any) => eb.exists(built))\n }\n return true\n }\n\n /** SQL fragment for `cf:<key>` (or legacy bare key) as JSON across a single alias. */\n private jsonbSqlAlias(alias: string, key: string): RawBuilder<unknown> {\n if (key.startsWith('cf:')) {\n const bare = key.slice(3)\n return sql`coalesce(${sql.ref(alias + '.doc')} -> ${key}, ${sql.ref(alias + '.doc')} -> ${bare})`\n }\n return sql`${sql.ref(alias + '.doc')} -> ${key}`\n }\n\n /** SQL fragment for `cf:<key>` (or legacy bare key) as text across a single alias. */\n private cfTextExprAlias(alias: string, key: string): RawBuilder<string | null> {\n if (key.startsWith('cf:')) {\n const bare = key.slice(3)\n return sql<string | null>`coalesce((${sql.ref(alias + '.doc')} ->> ${key}), (${sql.ref(alias + '.doc')} ->> ${bare}))`\n }\n return sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${key})`\n }\n\n /** Build JSON/text SQL expressions across multiple index alias sources (coalesce over them). */\n private buildCfJsonExprSql(key: string, sources: IndexDocSource[]): RawBuilder<unknown> | null {\n if (!sources.length) return null\n const parts = sources.map((src) => this.jsonbSqlAlias(src.alias, key))\n if (parts.length === 1) return parts[0]\n return sql`coalesce(${sql.join(parts, sql`, `)})`\n }\n\n private buildCfTextExprSql(key: string, sources: IndexDocSource[]): RawBuilder<string | null> | null {\n if (!sources.length) return null\n const parts = sources.map((src) => this.cfTextExprAlias(src.alias, key))\n if (parts.length === 1) return parts[0]\n return sql<string | null>`coalesce(${sql.join(parts, sql`, `)})`\n }\n\n private applyCfFilterAcrossSources(\n builder: AnyBuilder,\n key: string,\n op: FilterOp,\n value: unknown,\n sources: IndexDocSource[],\n search?: SearchRuntime\n ): AnyBuilder {\n if (!sources.length) return builder\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = this.applyMultiSourceSearchExists(builder, sources, key, hashes, search)\n this.logSearchDebug('search:cf-filter-across', {\n entity: sources.map((src) => src.entityId),\n field: key, tokens: tokens.tokens, hashes, applied,\n tenantId: search.tenantId ?? null, organizationScope: search.organizationScope,\n })\n if (applied.builder !== builder) return applied.builder\n } else {\n this.logSearchDebug('search:cf-skip-empty-hashes', {\n entity: sources.map((src) => src.entityId), field: key, value,\n })\n }\n return builder\n }\n\n const textExpr = this.buildCfTextExprSql(key, sources)\n const jsonExpr = this.buildCfJsonExprSql(key, sources)\n if (!textExpr || !jsonExpr) return builder\n\n const arrContains = (val: unknown) => sql<boolean>`${jsonExpr} @> ${JSON.stringify([val])}::jsonb`\n\n switch (op) {\n case 'eq':\n return builder.where((eb: any) => eb.or([\n sql<boolean>`${textExpr} = ${value}`,\n arrContains(value),\n ]))\n case 'ne':\n return builder.where(sql<boolean>`${textExpr} <> ${value}`)\n case 'in': {\n const values = this.toArray(value)\n return builder.where((eb: any) => eb.or(\n values.flatMap((val) => [\n sql<boolean>`${textExpr} = ${val}`,\n arrContains(val),\n ])\n ))\n }\n case 'nin': {\n const values = this.toArray(value)\n return builder.where(sql<boolean>`${textExpr} not in (${sql.join(values.map((v) => sql`${v}`), sql`, `)})`)\n }\n case 'like':\n return builder.where(sql<boolean>`${textExpr} like ${value}`)\n case 'ilike':\n return builder.where(sql<boolean>`${textExpr} ilike ${value}`)\n case 'exists':\n return value\n ? builder.where(sql<boolean>`${textExpr} is not null`)\n : builder.where(sql<boolean>`${textExpr} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = sql.raw(op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<=')\n return builder.where(sql<boolean>`${textExpr} ${operator} ${value}`)\n }\n default:\n return builder\n }\n }\n\n /** Apply a search-token EXISTS subquery across multiple sources (OR-joined). */\n private applyMultiSourceSearchExists(\n builder: AnyBuilder,\n sources: IndexDocSource[],\n key: string,\n hashes: string[],\n search: SearchRuntime,\n ): { builder: AnyBuilder; applied: boolean } {\n if (!sources.length || !hashes.length) return { builder, applied: false }\n const next = builder.where((eb: any) => eb.or(\n sources.map((source) =>\n eb.exists(this.buildSearchTokensSub(eb, {\n entity: String(source.entityId),\n field: key, hashes,\n recordIdColumn: `${source.alias}.entity_id`,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n }))\n )\n ))\n return { builder: next, applied: true }\n }\n\n /** Construct a search-token EXISTS subquery using the given ExpressionBuilder. */\n private buildSearchTokensSub(\n eb: any,\n opts: {\n entity: string\n field: string\n hashes: string[]\n recordIdColumn: string\n tenantId?: string | null\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n }\n ): any {\n const alias = `st_${this.searchAliasSeq++}`\n let sub = eb\n .selectFrom(`search_tokens as ${alias}`)\n .select(sql<number>`1`.as('one'))\n .where(`${alias}.entity_type`, '=', opts.entity)\n .where(`${alias}.field`, '=', opts.field)\n .where(sql<boolean>`${sql.ref(`${alias}.entity_id`)} = ${sql.ref(opts.recordIdColumn)}::text`)\n .where(`${alias}.token_hash`, 'in', opts.hashes)\n .groupBy([`${alias}.entity_id`, `${alias}.field`])\n .having(sql<boolean>`count(distinct ${sql.ref(`${alias}.token_hash`)}) >= ${opts.hashes.length}`)\n if (opts.tenantId !== undefined) {\n sub = sub.where(sql<boolean>`${sql.ref(`${alias}.tenant_id`)} is not distinct from ${opts.tenantId ?? null}`)\n }\n if (opts.organizationScope) {\n sub = this.applyOrganizationScope(sub, `${alias}.organization_id`, opts.organizationScope)\n }\n return sub\n }\n\n private applyCfFilterFromAlias(\n q: AnyBuilder,\n alias: string,\n entityType: string,\n key: string,\n op: FilterOp,\n value: unknown,\n search?: SearchRuntime\n ): AnyBuilder {\n const textExpr = this.cfTextExprAlias(alias, key)\n const arrExpr = sql<unknown>`(${sql.ref(alias + '.doc')} -> ${key})`\n const arrContains = (val: unknown) => sql<boolean>`${arrExpr} @> ${JSON.stringify([val])}::jsonb`\n\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = q.where((eb: any) => eb.exists(this.buildSearchTokensSub(eb, {\n entity: entityType, field: key, hashes,\n recordIdColumn: `${alias}.entity_id`,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })))\n this.logSearchDebug('search:cf-filter', {\n entity: entityType, field: key, tokens: tokens.tokens, hashes, applied: true,\n tenantId: search.tenantId ?? null, organizationScope: search.organizationScope,\n })\n return applied\n } else {\n this.logSearchDebug('search:cf-skip-empty-hashes', { entity: entityType, field: key, value })\n }\n return q\n }\n switch (op) {\n case 'eq':\n return q.where((eb: any) => eb.or([\n sql<boolean>`${textExpr} = ${value}`,\n arrContains(value),\n ]))\n case 'ne':\n return q.where(sql<boolean>`${textExpr} <> ${value}`)\n case 'in': {\n const vals = this.toArray(value)\n return q.where((eb: any) => eb.or(\n vals.flatMap((val) => [\n sql<boolean>`${textExpr} = ${val}`,\n arrContains(val),\n ])\n ))\n }\n case 'nin': {\n const vals = this.toArray(value)\n return q.where(sql<boolean>`${textExpr} not in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`)\n }\n case 'like':\n return q.where(sql<boolean>`${textExpr} like ${value}`)\n case 'ilike':\n return q.where(sql<boolean>`${textExpr} ilike ${value}`)\n case 'exists':\n return value\n ? q.where(sql<boolean>`${textExpr} is not null`)\n : q.where(sql<boolean>`${textExpr} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = sql.raw(op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<=')\n return q.where(sql<boolean>`${textExpr} ${operator} ${value}`)\n }\n default:\n return q\n }\n }\n\n private applyIndexDocFilterFromAlias(\n q: AnyBuilder,\n alias: string,\n entityType: string,\n key: string,\n op: FilterOp,\n value: unknown,\n recordIdColumn: string,\n search?: SearchRuntime,\n ): AnyBuilder {\n const textExpr = sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${key})`\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = q.where((eb: any) => eb.exists(this.buildSearchTokensSub(eb, {\n entity: entityType, field: key, hashes, recordIdColumn,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })))\n this.logSearchDebug('search:index-doc-filter', {\n entity: entityType, field: key, tokens: tokens.tokens, hashes, applied: true,\n tenantId: search.tenantId ?? null, organizationScope: search.organizationScope,\n })\n return applied\n } else {\n this.logSearchDebug('search:index-doc-skip-empty-hashes', { entity: entityType, field: key, value })\n }\n return q\n }\n switch (op) {\n case 'eq':\n return q.where(sql<boolean>`${textExpr} = ${value}`)\n case 'ne':\n return q.where(sql<boolean>`${textExpr} <> ${value}`)\n case 'in': {\n const vals = this.toArray(value)\n return q.where(sql<boolean>`${textExpr} in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`)\n }\n case 'nin': {\n const vals = this.toArray(value)\n return q.where(sql<boolean>`${textExpr} not in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`)\n }\n case 'like':\n return q.where(sql<boolean>`${textExpr} like ${value}`)\n case 'ilike':\n return q.where(sql<boolean>`${textExpr} ilike ${value}`)\n case 'exists':\n return value\n ? q.where(sql<boolean>`${textExpr} is not null`)\n : q.where(sql<boolean>`${textExpr} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = sql.raw(op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<=')\n return q.where(sql<boolean>`${textExpr} ${operator} ${value}`)\n }\n default:\n return q\n }\n }\n\n /**\n * Build a single OR-group base filter expression as a Kysely predicate\n * (no side effects on the outer builder).\n */\n private buildBaseFilterExpression(\n eb: any,\n filter: BaseFilter,\n resolveBaseColumn: (field: string) => string | null,\n qualify: (col: string) => string,\n entity: EntityId,\n searchRuntime: SearchRuntime,\n ): any {\n const fieldName = String(filter.field)\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) {\n // Doc-based filter via `ei` alias \u2014 returned as EXISTS where possible\n return this.buildIndexDocFilterExpression(eb, 'ei', entity, fieldName, filter.op, filter.value, 'b.id', searchRuntime)\n }\n // For like/ilike with active search-tokens, route through hashed-token EXISTS subquery\n // so encrypted-at-rest columns can still be searched.\n if (\n (filter.op === 'like' || filter.op === 'ilike') &&\n searchRuntime?.enabled &&\n typeof filter.value === 'string'\n ) {\n const tokens = tokenizeText(String(filter.value), searchRuntime.config)\n if (tokens.hashes.length) {\n const sources: SearchTokenSource[] = (searchRuntime.searchSources && searchRuntime.searchSources.length\n ? searchRuntime.searchSources\n : [{ entity: String(entity), recordIdColumn: 'b.id' }]\n ).filter((src) => src.recordIdColumn && src.entity)\n if (sources.length) {\n return eb.or(\n sources.map((src) =>\n eb.exists(this.buildSearchTokensSub(eb, {\n entity: src.entity,\n field: fieldName,\n hashes: tokens.hashes,\n recordIdColumn: src.recordIdColumn,\n tenantId: searchRuntime.tenantId ?? null,\n organizationScope: searchRuntime.organizationScope ?? null,\n })),\n ),\n )\n }\n }\n // Tokenizer produced no hashes (e.g. value too short). Match the regular-base-filter\n // path's behavior of skipping the predicate (no filter), which is preferable to\n // silently turning into a plain `ilike` against an encrypted column.\n return sql<boolean>`true`\n }\n return this.buildColumnFilterExpression(eb, qualify(baseField), filter.op, filter.value)\n }\n\n private buildColumnFilterExpression(\n eb: any,\n column: string,\n op: FilterOp,\n value: unknown,\n ): any {\n switch (op) {\n case 'eq': return eb(column, '=', value)\n case 'ne': return eb(column, '!=', value)\n case 'gt': return eb(column, '>', value)\n case 'gte': return eb(column, '>=', value)\n case 'lt': return eb(column, '<', value)\n case 'lte': return eb(column, '<=', value)\n case 'in': return eb(column, 'in', this.toArray(value))\n case 'nin': return eb(column, 'not in', this.toArray(value))\n case 'like': return eb(column, 'like', value)\n case 'ilike': return eb(column, 'ilike', value)\n case 'exists': return eb(column, value ? 'is not' : 'is', null)\n default: return sql<boolean>`true`\n }\n }\n\n private buildIndexDocFilterExpression(\n eb: any,\n alias: string,\n _entity: EntityId,\n key: string,\n op: FilterOp,\n value: unknown,\n _recordIdColumn: string,\n _search?: SearchRuntime,\n ): any {\n const textExpr = sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${key})`\n switch (op) {\n case 'eq': return sql<boolean>`${textExpr} = ${value}`\n case 'ne': return sql<boolean>`${textExpr} <> ${value}`\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = sql.raw(op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<=')\n return sql<boolean>`${textExpr} ${operator} ${value}`\n }\n case 'like': return sql<boolean>`${textExpr} like ${value}`\n case 'ilike': return sql<boolean>`${textExpr} ilike ${value}`\n case 'in': {\n const vals = this.toArray(value)\n return sql<boolean>`${textExpr} in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`\n }\n case 'nin': {\n const vals = this.toArray(value)\n return sql<boolean>`${textExpr} not in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`\n }\n case 'exists':\n return value ? sql<boolean>`${textExpr} is not null` : sql<boolean>`${textExpr} is null`\n default:\n return sql<boolean>`true`\n }\n }\n\n private async queryCustomEntity<T = unknown>(entity: string, opts: QueryOptions = {}): Promise<QueryResult<T>> {\n const db = this.getDb() as any\n const alias = 'ce'\n\n const orgScope = this.resolveOrganizationScope(opts)\n if (!opts.tenantId) throw new Error('QueryEngine: tenantId is required')\n\n const searchConfig = resolveSearchConfig()\n const searchEnabled = searchConfig.enabled && await this.tableExists('search_tokens')\n const hasSearchTokens = searchEnabled\n ? await this.hasSearchTokens(entity, opts.tenantId ?? null, orgScope)\n : false\n const searchRuntime: SearchRuntime = {\n enabled: searchEnabled && hasSearchTokens,\n config: searchConfig,\n organizationScope: orgScope,\n tenantId: opts.tenantId ?? null,\n }\n\n const normalizedFilters = normalizeFilters(opts.filters)\n\n const applyScope = (q: AnyBuilder): AnyBuilder => {\n let next = q\n .where(`${alias}.entity_type`, '=', entity)\n .where(`${alias}.tenant_id`, '=', opts.tenantId)\n if (orgScope) {\n next = this.applyOrganizationScope(next, `${alias}.organization_id`, orgScope)\n }\n if (!opts.withDeleted) next = next.where(`${alias}.deleted_at`, 'is', null)\n for (const filter of normalizedFilters) {\n if (filter.field.startsWith('cf:')) {\n next = this.applyCfFilterFromAlias(next, alias, entity, filter.field, filter.op, filter.value, searchRuntime)\n continue\n }\n const column = this.resolveCustomEntityColumn(alias, String(filter.field))\n if (column) {\n next = this.applyColumnFilter(next, column, filter, {\n ...searchRuntime, entity, field: String(filter.field), recordIdColumn: `${alias}.entity_id`,\n })\n continue\n }\n // Unknown field \u2192 filter on doc JSON text\n const docExpr = sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${String(filter.field)})`\n next = this.applyColumnFilter(next, docExpr, filter, {\n ...searchRuntime, entity, field: String(filter.field), recordIdColumn: `${alias}.entity_id`,\n })\n }\n return next\n }\n\n // Determine CFs and l10n keys to include\n const cfKeys = new Set<string>()\n for (const f of (opts.fields || [])) {\n if (typeof f === 'string' && f.startsWith('cf:')) cfKeys.add(f.slice(3))\n else if (typeof f === 'string' && f.startsWith('l10n:')) cfKeys.add(f)\n }\n for (const filter of normalizedFilters) {\n if (typeof filter.field === 'string' && filter.field.startsWith('cf:')) cfKeys.add(filter.field.slice(3))\n else if (typeof filter.field === 'string' && filter.field.startsWith('l10n:')) cfKeys.add(filter.field)\n }\n if (opts.includeCustomFields === true) {\n try {\n const rows = await db\n .selectFrom('custom_field_defs')\n .select('key')\n .where('entity_id', '=', entity)\n .where('is_active', '=', true)\n .where('tenant_id', '=', opts.tenantId)\n .execute() as Array<{ key: unknown }>\n for (const row of rows) {\n const key = row.key\n if (typeof key === 'string') cfKeys.add(key)\n else if (key != null) cfKeys.add(String(key))\n }\n } catch {\n // ignore\n }\n } else if (Array.isArray(opts.includeCustomFields)) {\n for (const k of opts.includeCustomFields) cfKeys.add(k)\n }\n\n const applySelection = (q: AnyBuilder): AnyBuilder => {\n let next = q\n const requested = (opts.fields && opts.fields.length) ? opts.fields : ['id']\n for (const field of requested) {\n const f = String(field)\n if (f.startsWith('cf:')) {\n const aliasName = this.sanitize(f)\n next = next.select(this.jsonbSqlAlias(alias, f).as(aliasName))\n } else if (f === 'id') {\n next = next.select(`${alias}.entity_id as id`)\n } else if (f === 'created_at' || f === 'updated_at' || f === 'deleted_at') {\n next = next.select(`${alias}.${f} as ${f}`)\n } else {\n const expr = sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${f})`\n next = next.select(expr.as(f))\n }\n }\n // Ensure CF fields for sort / includeCustomFields are selected\n for (const key of cfKeys) {\n const aliasName = this.sanitize(`cf:${key}`)\n next = next.select(this.jsonbSqlAlias(alias, `cf:${key}`).as(aliasName))\n }\n return next\n }\n\n const applySort = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const s of opts.sort || []) {\n if (s.field.startsWith('cf:')) {\n const key = s.field.slice(3)\n const aliasName = this.sanitize(`cf:${key}`)\n next = next.orderBy(aliasName, s.dir ?? SortDir.Asc)\n } else if (s.field === 'id') {\n next = next.orderBy(`${alias}.entity_id`, s.dir ?? SortDir.Asc)\n } else if (s.field === 'created_at' || s.field === 'updated_at' || s.field === 'deleted_at') {\n next = next.orderBy(`${alias}.${s.field}`, s.dir ?? SortDir.Asc)\n } else {\n const direction = sql.raw(String(s.dir ?? SortDir.Asc))\n next = next.orderBy(sql`(${sql.ref(alias + '.doc')} ->> ${s.field}) ${direction}`)\n }\n }\n return next\n }\n\n const page = opts.page?.page ?? 1\n const pageSize = opts.page?.pageSize ?? 20\n\n const root = db.selectFrom(`custom_entities_storage as ${alias}`)\n const countQuery = applyScope(root).select(sql<string>`count(distinct ${sql.ref(`${alias}.entity_id`)})`.as('count'))\n const countRow = await countQuery.executeTakeFirst()\n const total = this.parseCount(countRow)\n\n let dataQuery = applyScope(db.selectFrom(`custom_entities_storage as ${alias}`))\n dataQuery = applySelection(dataQuery)\n dataQuery = applySort(dataQuery)\n dataQuery = dataQuery.limit(pageSize).offset((page - 1) * pageSize)\n const items = await dataQuery.execute()\n return { items, page, pageSize, total }\n }\n\n private async tableExists(table: string): Promise<boolean> {\n const db = this.getDb() as any\n const exists = await db\n .selectFrom('information_schema.tables')\n .select(sql<number>`1`.as('one'))\n .where('table_name', '=', table)\n .executeTakeFirst()\n return !!exists\n }\n\n private async hasSearchTokens(\n entity: string,\n tenantId: string | null,\n orgScope?: { ids: string[]; includeNull: boolean } | null\n ): Promise<boolean> {\n try {\n const db = this.getDb() as any\n let query = db\n .selectFrom('search_tokens')\n .select(sql<number>`1`.as('one'))\n .where('entity_type', '=', entity)\n if (tenantId !== undefined) {\n query = query.where(sql<boolean>`tenant_id is not distinct from ${tenantId}`)\n }\n if (orgScope) {\n query = this.applyOrganizationScope(query, 'search_tokens.organization_id', orgScope)\n }\n const row = await query.limit(1).executeTakeFirst()\n return !!row\n } catch (err) {\n this.logSearchDebug('search:has-tokens-error', {\n entity, tenantId, organizationScope: orgScope,\n error: err instanceof Error ? err.message : String(err),\n })\n return false\n }\n }\n\n private async searchSourcesHaveTokens(\n sources: SearchTokenSource[],\n tenantId: string | null,\n orgScope?: { ids: string[]; includeNull: boolean } | null\n ): Promise<boolean> {\n for (const source of sources) {\n const ok = await this.hasSearchTokens(source.entity, tenantId, orgScope)\n this.logSearchDebug('search:source-has-tokens', {\n entity: source.entity, recordIdColumn: source.recordIdColumn,\n tenantId, organizationScope: orgScope, hasTokens: ok,\n })\n if (ok) return true\n }\n return false\n }\n\n private async resolveAvailableCustomFieldKeys(entityIds: string[], tenantId: string | null): Promise<string[]> {\n if (!entityIds.length) return []\n const cacheKey = this.customFieldKeysCacheKey(entityIds, tenantId)\n const now = Date.now()\n const cached = this.customFieldKeysCache.get(cacheKey)\n if (cached && cached.expiresAt > now) return cached.value.slice()\n\n const db = this.getDb() as any\n const rows = await db\n .selectFrom('custom_field_defs')\n .select('key')\n .where('entity_id', 'in', entityIds)\n .where('is_active', '=', true)\n .where((eb: any) => eb.or([\n eb('tenant_id', '=', tenantId),\n eb('tenant_id', 'is', null),\n ]))\n .execute() as Array<{ key: unknown }>\n const keys = new Set<string>()\n for (const row of rows) {\n const key = row.key\n if (typeof key === 'string' && key.trim().length) keys.add(key.trim())\n else if (key != null) keys.add(String(key))\n }\n const result = Array.from(keys)\n if (this.customFieldKeysTtlMs > 0) {\n this.customFieldKeysCache.set(cacheKey, { expiresAt: now + this.customFieldKeysTtlMs, value: result })\n }\n return result.slice()\n }\n\n private async entityHasActiveCustomFields(entityId: string, tenantId: string | null): Promise<boolean> {\n try {\n const keys = await this.resolveAvailableCustomFieldKeys([entityId], tenantId)\n return keys.length > 0\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('query:cf:check-error', {\n entity: entityId, tenantId: tenantId ?? null,\n error: err instanceof Error ? err.message : err,\n })\n }\n return true\n }\n }\n\n private customFieldKeysCacheKey(entityIds: string[], tenantId: string | null): string {\n const sorted = entityIds.slice().sort((a, b) => a.localeCompare(b)).join(',')\n return `${tenantId ?? '__none__'}|${sorted}`\n }\n\n private resolveVectorService(): VectorIndexService | null {\n if (!this.vectorServiceResolver) return null\n try {\n return this.vectorServiceResolver() ?? null\n } catch {\n return null\n }\n }\n\n private resolveEntityLabel(entity: string): string {\n return entity\n }\n\n private async indexAnyRows(entity: string): Promise<boolean> {\n const db = this.getDb() as any\n const coverage = await db\n .selectFrom('entity_index_coverage')\n .select(sql<number>`1`.as('one'))\n .where('entity_type', '=', entity)\n .where('indexed_count', '>', 0)\n .executeTakeFirst()\n if (coverage) return true\n const exists = await db\n .selectFrom('entity_indexes')\n .select('entity_id')\n .where('entity_type', '=', entity)\n .executeTakeFirst()\n return !!exists\n }\n\n private async getStoredCoverageSnapshot(\n entity: string,\n tenantId: string | null,\n organizationId: string | null,\n withDeleted: boolean\n ): Promise<{ baseCount: number; indexedCount: number } | null> {\n try {\n if (!this.isCoverageOptimizationEnabled()) {\n await refreshCoverageSnapshot(this.em, {\n entityType: entity, tenantId, organizationId, withDeleted,\n })\n }\n const db = this.getDb()\n const row = await readCoverageSnapshot(db as any, {\n entityType: entity, tenantId, organizationId, withDeleted,\n })\n if (!row) return null\n return { baseCount: row.baseCount, indexedCount: row.indexedCount }\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('coverage:snapshot:read-error', {\n entity, tenantId, organizationId, withDeleted,\n error: err instanceof Error ? err.message : err,\n })\n }\n return null\n }\n }\n\n private scheduleAutoReindex(\n entity: string,\n opts: QueryOptions,\n stats?: { baseCount: number; indexedCount: number },\n organizationIdOverride?: string | null\n ) {\n if (!this.isAutoReindexEnabled()) return\n const bus = this.resolveEventBus()\n if (!bus) return\n const payload = {\n entityType: entity,\n tenantId: opts.tenantId ?? null,\n organizationId: organizationIdOverride ?? opts.organizationId ?? null,\n force: false,\n }\n const context = stats\n ? { entity, tenantId: payload.tenantId, organizationId: payload.organizationId, baseCount: stats.baseCount, indexedCount: stats.indexedCount }\n : { entity, tenantId: payload.tenantId, organizationId: payload.organizationId }\n\n void Promise.resolve().then(async () => {\n try {\n await bus.emitEvent('query_index.reindex', payload, { persistent: true })\n if (this.isDebugVerbosity()) this.debug('query:auto-reindex:scheduled', context)\n } catch (err) {\n console.warn('[HybridQueryEngine] Failed to schedule auto reindex:', {\n ...context, error: err instanceof Error ? err.message : err,\n })\n }\n })\n }\n\n private scheduleCoverageRefresh(\n entity: string,\n tenantId: string | null | undefined,\n organizationId: string | null | undefined,\n withDeleted: boolean\n ): void {\n const bus = this.resolveEventBus()\n if (!bus) return\n const key = [entity, tenantId ?? '__tenant__', organizationId ?? '__org__', withDeleted ? '1' : '0'].join('|')\n if (this.pendingCoverageRefreshKeys.has(key)) return\n this.pendingCoverageRefreshKeys.add(key)\n void Promise.resolve()\n .then(async () => {\n try {\n await bus.emitEvent('query_index.coverage.refresh', {\n entityType: entity,\n tenantId: tenantId ?? null, organizationId: organizationId ?? null,\n withDeleted, delayMs: 0,\n })\n if (this.isDebugVerbosity()) {\n this.debug('coverage:refresh:scheduled', {\n entity, tenantId: tenantId ?? null, organizationId: organizationId ?? null, withDeleted,\n })\n }\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('coverage:refresh:failed', {\n entity, tenantId: tenantId ?? null, organizationId: organizationId ?? null, withDeleted,\n error: err instanceof Error ? err.message : err,\n })\n }\n }\n })\n .finally(() => { this.pendingCoverageRefreshKeys.delete(key) })\n }\n\n private resolveEventBus(): Pick<EventBus, 'emitEvent'> | null {\n if (!this.eventBusResolver) return null\n try {\n const bus = this.eventBusResolver()\n return bus ?? null\n } catch {\n return null\n }\n }\n\n private isAutoReindexEnabled(): boolean {\n if (this.autoReindexEnabled != null) return this.autoReindexEnabled\n const raw = (process.env.SCHEDULE_AUTO_REINDEX ?? process.env.QUERY_INDEX_AUTO_REINDEX ?? '').trim().toLowerCase()\n if (!raw) { this.autoReindexEnabled = true; return true }\n const parsed = parseBooleanToken(raw)\n this.autoReindexEnabled = parsed === null ? true : parsed\n return this.autoReindexEnabled\n }\n\n private isCoverageOptimizationEnabled(): boolean {\n if (this.coverageOptimizationEnabled != null) return this.coverageOptimizationEnabled\n const raw = (process.env.OPTIMIZE_INDEX_COVERAGE_STATS ?? '').trim().toLowerCase()\n if (!raw) { this.coverageOptimizationEnabled = false; return false }\n this.coverageOptimizationEnabled = parseBooleanToken(raw) === true\n return this.coverageOptimizationEnabled\n }\n\n private async columnExists(table: string, column: string): Promise<boolean> {\n const key = `${table}.${column}`\n if (this.columnCache.has(key)) {\n const cached = this.columnCache.get(key)\n if (cached === true) return true\n this.columnCache.delete(key)\n }\n const db = this.getDb() as any\n const exists = await db\n .selectFrom('information_schema.columns')\n .select(sql<number>`1`.as('one'))\n .where('table_name', '=', table)\n .where('column_name', '=', column)\n .executeTakeFirst()\n const present = !!exists\n if (present) this.columnCache.set(key, true)\n else this.columnCache.delete(key)\n return present\n }\n\n private async getBaseColumnsForEntity(entity: string): Promise<Map<string, string>> {\n const db = this.getDb() as any\n const table = resolveEntityTableName(this.em, entity)\n const rows = await db\n .selectFrom('information_schema.columns')\n .select(['column_name', 'data_type'])\n .where('table_name', '=', table)\n .execute() as Array<{ column_name: string; data_type: string }>\n const map = new Map<string, string>()\n for (const r of rows) map.set(r.column_name, r.data_type)\n return map\n }\n\n private resolveOrganizationScope(opts: QueryOptions): { ids: string[]; includeNull: boolean } | null {\n if (opts.organizationIds !== undefined) {\n const raw = (opts.organizationIds ?? []).map((id) => (typeof id === 'string' ? id.trim() : id))\n const includeNull = raw.some((id) => id == null || id === '')\n const ids = raw.filter((id): id is string => typeof id === 'string' && id.length > 0)\n const unique = Array.from(new Set(ids))\n return { ids: unique, includeNull }\n }\n if (typeof opts.organizationId === 'string' && opts.organizationId.trim().length > 0) {\n return { ids: [opts.organizationId], includeNull: false }\n }\n return null\n }\n\n private resolveCoverageSnapshotScope(\n opts: QueryOptions\n ): { tenantId: string | null; organizationId: string | null } | null {\n const tenantId = opts.tenantId ?? null\n const orgScope = this.resolveOrganizationScope(opts)\n if (!orgScope) return { tenantId, organizationId: null }\n if (orgScope.includeNull) {\n if (orgScope.ids.length === 0) return { tenantId, organizationId: null }\n return null\n }\n if (orgScope.ids.length === 1) return { tenantId, organizationId: orgScope.ids[0] }\n if (orgScope.ids.length === 0) return { tenantId, organizationId: null }\n return null\n }\n\n private applyOrganizationScope(\n q: AnyBuilder,\n column: string,\n scope: { ids: string[]; includeNull: boolean }\n ): AnyBuilder {\n if (scope.ids.length === 0 && !scope.includeNull) {\n return q.where(sql<boolean>`1 = 0`)\n }\n return q.where((eb: any) => {\n const parts: any[] = []\n if (scope.ids.length > 0) parts.push(eb(column, 'in', scope.ids))\n if (scope.includeNull) parts.push(eb(column, 'is', null))\n if (parts.length === 1) return parts[0]\n return eb.or(parts)\n })\n }\n\n private normalizeFilters(filters?: QueryOptions['filters']): NormalizedFilter[] {\n if (!filters) return []\n const normalizeField = (k: string) => k.startsWith('cf_') ? `cf:${k.slice(3)}` : k\n if (Array.isArray(filters)) {\n return (filters as Filter[]).map((filter) => ({\n field: normalizeField(String(filter.field)),\n op: filter.op, value: filter.value,\n }))\n }\n const out: NormalizedFilter[] = []\n const obj = filters as Record<string, unknown>\n const add = (field: string, op: FilterOp, value?: unknown) => out.push({ field, op, value })\n for (const [rawKey, rawVal] of Object.entries(obj)) {\n const field = normalizeField(rawKey)\n if (rawVal !== null && typeof rawVal === 'object' && !Array.isArray(rawVal)) {\n for (const [opKey, opVal] of Object.entries(rawVal as Record<string, unknown>)) {\n switch (opKey) {\n case '$eq': add(field, 'eq', opVal); break\n case '$ne': add(field, 'ne', opVal); break\n case '$gt': add(field, 'gt', opVal); break\n case '$gte': add(field, 'gte', opVal); break\n case '$lt': add(field, 'lt', opVal); break\n case '$lte': add(field, 'lte', opVal); break\n case '$in': add(field, 'in', opVal); break\n case '$nin': add(field, 'nin', opVal); break\n case '$like': add(field, 'like', opVal); break\n case '$ilike': add(field, 'ilike', opVal); break\n case '$exists': add(field, 'exists', opVal); break\n }\n }\n } else {\n add(field, 'eq', rawVal)\n }\n }\n return out\n }\n\n private sanitize(s: string): string {\n return s.replace(/[^a-zA-Z0-9_]/g, '_')\n }\n\n private toArray(value: unknown): readonly unknown[] {\n if (Array.isArray(value)) return value\n if (value === undefined) return []\n return [value]\n }\n\n private parseCount(row: unknown): number {\n if (row && typeof row === 'object' && 'count' in row) {\n const value = (row as { count: unknown }).count\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? 0 : parsed\n }\n if (typeof value === 'bigint') return Number(value)\n }\n return 0\n }\n\n private logSearchDebug(event: string, payload: Record<string, unknown>) {\n if (!this.isDebugVerbosity()) return\n try {\n console.info('[query-index:search]', event, JSON.stringify(payload))\n } catch {\n console.info('[query-index:search]', event, payload)\n }\n }\n\n private applyColumnFilter(\n q: AnyBuilder,\n column: string | RawBuilder<unknown>,\n filter: NormalizedFilter,\n search?: SearchRuntime & { entity: string; field: string; recordIdColumn?: string },\n ): AnyBuilder {\n if (\n (filter.op === 'like' || filter.op === 'ilike') &&\n search?.enabled &&\n typeof filter.value === 'string'\n ) {\n const tokens = tokenizeText(String(filter.value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const sources: SearchTokenSource[] = (search.searchSources && search.searchSources.length\n ? search.searchSources\n : [{ entity: search.entity, recordIdColumn: search.recordIdColumn ?? '' }]\n ).filter((src) => src.recordIdColumn && src.entity)\n if (sources.length) {\n const engine = this\n q = q.where((eb: any) => eb.or(\n sources.map((src) =>\n eb.exists(engine.buildSearchTokensSub(eb, {\n entity: src.entity, field: search.field, hashes,\n recordIdColumn: src.recordIdColumn,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })))\n ))\n this.logSearchDebug('search:filter', {\n entity: search.entity, field: search.field, tokens: tokens.tokens, hashes,\n applied: true, tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n sources: sources.map((src) => ({ entity: src.entity, recordIdColumn: src.recordIdColumn })),\n })\n return q\n }\n } else {\n this.logSearchDebug('search:skip-empty-hashes', {\n entity: search.entity, field: search.field, value: filter.value,\n })\n }\n return q\n }\n const col: any = column\n switch (filter.op) {\n case 'eq': return q.where(col, '=', filter.value as any)\n case 'ne': return q.where(col, '!=', filter.value as any)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = filter.op === 'gt' ? '>' : filter.op === 'gte' ? '>=' : filter.op === 'lt' ? '<' : '<='\n return q.where(col, operator, filter.value as any)\n }\n case 'in':\n return q.where(col, 'in', this.toArray(filter.value))\n case 'nin':\n return q.where(col, 'not in', this.toArray(filter.value))\n case 'like':\n return q.where(col, 'like', filter.value as any)\n case 'ilike':\n return q.where(col, 'ilike', filter.value as any)\n case 'exists':\n return filter.value ? q.where(col, 'is not', null) : q.where(col, 'is', null)\n default:\n return q\n }\n }\n\n private resolveCustomEntityColumn(alias: string, field: string): string | null {\n if (field === 'id') return `${alias}.entity_id`\n if (field === 'organization_id' || field === 'organizationId') return `${alias}.organization_id`\n if (field === 'tenant_id' || field === 'tenantId') return `${alias}.tenant_id`\n if (field === 'created_at' || field === 'updated_at' || field === 'deleted_at') return `${alias}.${field}`\n return null\n }\n\n private isDebugVerbosity(): boolean {\n if (this.debugVerbosity != null) return this.debugVerbosity\n this.debugVerbosity = resolveDebugVerbosity()\n return this.debugVerbosity\n }\n\n private isSqlDebugEnabled(): boolean {\n if (this.sqlDebugEnabled != null) return this.sqlDebugEnabled\n this.sqlDebugEnabled = resolveBooleanEnv(['QUERY_ENGINE_DEBUG_SQL'], false)\n return this.sqlDebugEnabled\n }\n\n private isForcePartialIndexEnabled(): boolean {\n if (this.forcePartialIndexEnabled != null) return this.forcePartialIndexEnabled\n this.forcePartialIndexEnabled = resolveBooleanEnv(['FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES'], false)\n return this.forcePartialIndexEnabled\n }\n\n private async resolveCoverageGap(\n entity: string,\n opts: QueryOptions,\n coverageScope?: { tenantId: string | null; organizationId: string | null } | null,\n _sourceTable?: string\n ): Promise<{ stats?: { baseCount: number; indexedCount: number }; scope: 'scoped' | 'global' } | null> {\n const scope = coverageScope ?? this.resolveCoverageSnapshotScope(opts)\n if (!scope) return null\n const tenantId = scope.tenantId\n const organizationId = scope.organizationId\n const withDeleted = !!opts.withDeleted\n\n const snapshot = await this.getStoredCoverageSnapshot(entity, tenantId, organizationId, withDeleted)\n if (!snapshot) {\n this.scheduleCoverageRefresh(entity, tenantId, organizationId, withDeleted)\n return { stats: undefined, scope: 'scoped' }\n }\n\n const baseCount = snapshot.baseCount\n const indexCount = snapshot.indexedCount\n const hasGap = baseCount > 0 && indexCount < baseCount\n if (hasGap || indexCount > baseCount) return { stats: snapshot, scope: 'scoped' }\n return null\n }\n\n // Backward-compatible hook for tests that mock coverage stats\n private async indexCoverageStats(\n entity: string,\n opts: QueryOptions,\n coverageScope?: { tenantId: string | null; organizationId: string | null } | null,\n ): Promise<{ baseCount: number; indexedCount: number } | null> {\n const gap = await this.resolveCoverageGap(entity, opts, coverageScope)\n return gap?.stats ?? null\n }\n\n private async captureSqlTiming<TResult>(\n label: string,\n entity: EntityId,\n execute: () => Promise<TResult> | TResult,\n extra?: Record<string, unknown>,\n profiler?: Profiler\n ): Promise<TResult> {\n const shouldDebug = this.isSqlDebugEnabled() && this.isDebugVerbosity()\n const shouldProfile = profiler?.enabled === true\n if (!shouldDebug && !shouldProfile) return Promise.resolve(execute())\n const startedAt = process.hrtime.bigint()\n try {\n return await Promise.resolve(execute())\n } finally {\n const elapsedMs = Number(process.hrtime.bigint() - startedAt) / 1_000_000\n const context: Record<string, unknown> = { entity, durationMs: Math.round(elapsedMs * 1000) / 1000 }\n if (extra) Object.assign(context, extra)\n if (shouldProfile) profiler!.record(label, context.durationMs as number, extra)\n if (shouldDebug) this.debug(`${label}:timing`, context)\n }\n }\n\n private debug(message: string, context?: Record<string, unknown>): void {\n if (!this.isDebugVerbosity()) return\n if (!this.isSqlDebugEnabled()) return\n if (context) console.debug('[HybridQueryEngine]', message, context)\n else console.debug('[HybridQueryEngine]', message)\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { QueryEngine, QueryOptions, QueryResult, FilterOp, Filter, QueryCustomFieldSource, PartialIndexWarning, QueryExtensionsConfig } from '@open-mercato/shared/lib/query/types'\nimport { SortDir } from '@open-mercato/shared/lib/query/types'\nimport type { EntityId } from '@open-mercato/shared/modules/entities'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { BasicQueryEngine, resolveEntityTableName } from '@open-mercato/shared/lib/query/engine'\nimport { type Kysely, sql, type RawBuilder } from 'kysely'\nimport type { EventBus } from '@open-mercato/events'\nimport { readCoverageSnapshot, refreshCoverageSnapshot } from './coverage'\nimport { createProfiler, shouldEnableProfiler, type Profiler } from '@open-mercato/shared/lib/profiler'\nimport type { VectorIndexService } from '@open-mercato/search/vector'\nimport { decryptIndexDocCustomFields } from '@open-mercato/shared/lib/encryption/indexDoc'\nimport { parseBooleanToken, parseBooleanWithDefault } from '@open-mercato/shared/lib/boolean'\nimport {\n applyJoinFilters,\n normalizeFilters,\n partitionFilters,\n resolveJoins,\n type BaseFilter,\n type ResolvedJoin,\n} from '@open-mercato/shared/lib/query/join-utils'\nimport { resolveSearchConfig, type SearchConfig } from '@open-mercato/shared/lib/search/config'\nimport { tokenizeText } from '@open-mercato/shared/lib/search/tokenize'\nimport { runBeforeQueryPipeline, runAfterQueryPipeline, type QueryExtensionContext } from '@open-mercato/shared/lib/query/query-extension-runner'\n\nfunction buildFilterableCustomFieldJoins(\n sources: QueryCustomFieldSource[] | undefined,\n): Array<{\n alias: string\n table?: string\n entityId: EntityId\n from: { field: string }\n to: { field: string }\n type: 'left' | 'inner'\n}> {\n if (!sources || sources.length === 0) return []\n return sources.flatMap((source, index) => {\n if (!source.join) return []\n const alias = typeof source.alias === 'string' && source.alias.trim().length > 0\n ? source.alias.trim()\n : `cfs_${index}`\n return [{\n alias,\n table: source.table,\n entityId: source.entityId,\n from: { field: source.join.fromField },\n to: { field: source.join.toField },\n type: source.join.type === 'inner' ? 'inner' : 'left',\n }]\n })\n}\n\nfunction resolveBooleanEnv(names: readonly string[], defaultValue: boolean): boolean {\n for (const name of names) {\n const raw = process.env[name]\n if (raw !== undefined) return parseBooleanWithDefault(raw, defaultValue)\n }\n return defaultValue\n}\n\nfunction resolveDebugVerbosity(): boolean {\n const queryIndexDebug = process.env.OM_QUERY_INDEX_DEBUG\n if (queryIndexDebug !== undefined) {\n return parseBooleanToken(queryIndexDebug) ?? false\n }\n const level = (process.env.LOG_VERBOSITY ?? process.env.LOG_LEVEL ?? '').toLowerCase()\n if (['debug', 'trace', 'silly'].includes(level)) return true\n return false\n}\n\ntype AnyDb = Kysely<any>\ntype AnyBuilder = any\ntype NormalizedFilter = { field: string; op: FilterOp; value?: unknown }\ntype IndexDocSource = { alias: string; entityId: EntityId; recordIdColumn: string }\ntype PreparedCustomFieldSource = {\n alias: string\n indexAlias: string\n entityId: EntityId\n recordIdColumn: string\n organizationField?: string\n tenantField?: string\n table: string\n}\ntype SearchRuntime = {\n enabled: boolean\n config: SearchConfig\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n tenantId?: string | null\n searchSources?: SearchTokenSource[]\n}\n\ntype EncryptionResolver = () => {\n decryptEntityPayload?: (entityId: EntityId, payload: Record<string, unknown>, tenantId?: string | null, organizationId?: string | null) => Promise<Record<string, unknown>>\n isEnabled?: () => boolean\n} | null\n\ntype SearchTokenSource = { entity: string; recordIdColumn: string }\n\nfunction createQueryProfiler(entity: string): Profiler {\n const enabled = shouldEnableProfiler(entity)\n return createProfiler({\n scope: 'query_engine',\n target: entity,\n label: `query_engine:${entity}`,\n loggerLabel: '[qe:profile]',\n enabled,\n })\n}\n\nexport class HybridQueryEngine implements QueryEngine {\n private coverageStatsTtlMs: number\n private customFieldKeysCache = new Map<string, { expiresAt: number; value: string[] }>()\n private customFieldKeysTtlMs: number\n private columnCache = new Map<string, boolean>()\n private debugVerbosity: boolean | null = null\n private sqlDebugEnabled: boolean | null = null\n private forcePartialIndexEnabled: boolean | null = null\n private autoReindexEnabled: boolean | null = null\n private coverageOptimizationEnabled: boolean | null = null\n private pendingCoverageRefreshKeys = new Set<string>()\n private searchAliasSeq = 0\n\n constructor(\n private em: EntityManager,\n private fallback: BasicQueryEngine,\n private eventBusResolver?: () => Pick<EventBus, 'emitEvent'> | null | undefined,\n private vectorServiceResolver?: () => VectorIndexService | null | undefined,\n private encryptionResolver?: EncryptionResolver,\n ) {\n const coverageTtl = Number.parseInt(process.env.QUERY_INDEX_COVERAGE_CACHE_MS ?? '', 10)\n this.coverageStatsTtlMs = Number.isFinite(coverageTtl) && coverageTtl >= 0 ? coverageTtl : 5 * 60 * 1000\n const cfTtl = Number.parseInt(process.env.QUERY_INDEX_CF_KEYS_CACHE_MS ?? '', 10)\n this.customFieldKeysTtlMs = Number.isFinite(cfTtl) && cfTtl >= 0 ? cfTtl : 5 * 60 * 1000\n }\n\n private getEncryptionService() {\n try {\n return this.encryptionResolver?.() ?? null\n } catch {\n return null\n }\n }\n\n private getDb(): AnyDb {\n const emAny = this.em as any\n if (typeof emAny.getKysely === 'function') return emAny.getKysely() as AnyDb\n throw new Error('HybridQueryEngine requires an EntityManager exposing getKysely() (MikroORM v7)')\n }\n\n async query<T = unknown>(entity: EntityId, opts: QueryOptions = {}): Promise<QueryResult<T>> {\n const ext: QueryExtensionsConfig | undefined = opts.extensions\n let hybridExtCtx: QueryExtensionContext | null = null\n const noopDi = { resolve: <R = unknown>(_name: string): R => { throw new Error('No DI context') } }\n\n if (ext) {\n hybridExtCtx = {\n entity: String(entity),\n engine: 'hybrid',\n tenantId: opts.tenantId ?? '',\n organizationId: opts.organizationId,\n userId: ext.userId,\n em: this.em,\n container: ext.container,\n userFeatures: ext.userFeatures,\n }\n const diCtx = ext.resolve ? { resolve: ext.resolve } : noopDi\n const beforeResult = await runBeforeQueryPipeline(opts, hybridExtCtx, diCtx)\n if (beforeResult.blocked) {\n throw new Error(beforeResult.errorMessage ?? 'Query blocked by extension subscriber')\n }\n opts = beforeResult.query\n }\n const { extensions: _stripExt, ...coreOpts } = opts\n opts = coreOpts\n\n const providedProfiler = opts.profiler\n const profiler = providedProfiler && providedProfiler.enabled\n ? providedProfiler\n : createQueryProfiler(String(entity))\n profiler.mark('query:init')\n let profileClosed = false\n const finishProfile = (meta?: Record<string, unknown>) => {\n if (!profiler.enabled || profileClosed) return\n profileClosed = true\n profiler.end(meta)\n }\n\n const applyAfterExtensions = async <R>(queryResult: QueryResult<R>): Promise<QueryResult<R>> => {\n if (!ext || !hybridExtCtx) return queryResult\n const diCtx = ext.resolve ? { resolve: ext.resolve } : noopDi\n return await runAfterQueryPipeline(\n queryResult as QueryResult<Record<string, unknown>>,\n opts,\n hybridExtCtx,\n diCtx,\n ) as QueryResult<R>\n }\n\n try {\n const debugEnabled = this.isDebugVerbosity()\n if (debugEnabled) this.debug('query:start', { entity })\n this.searchAliasSeq = 0\n\n const isCustom = await this.isCustomEntity(entity)\n if (isCustom) {\n if (debugEnabled) this.debug('query:custom-entity', { entity })\n const section = profiler.section('custom_entity')\n try {\n const result = await this.queryCustomEntity<T>(entity, opts)\n section.end({ mode: 'custom_entity' })\n finishProfile({\n result: 'custom_entity',\n total: Array.isArray(result.items) ? result.items.length : undefined,\n })\n return await applyAfterExtensions(result)\n } catch (err) {\n section.end({ error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }\n\n const db = this.getDb()\n profiler.mark('query:db_ready')\n const baseTable = resolveEntityTableName(this.em, entity)\n profiler.mark('query:base_table_resolved')\n const searchConfig = resolveSearchConfig()\n const orgScope = this.resolveOrganizationScope(opts)\n const searchEnabled = searchConfig.enabled && await this.tableExists('search_tokens')\n\n const baseExists = await profiler.measure('base_table_exists', () => this.tableExists(baseTable))\n if (!baseExists) {\n if (debugEnabled) this.debug('query:fallback:missing-base', { entity, baseTable })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'missing_base' })\n return await applyAfterExtensions(fallbackResult)\n }\n\n if (opts.omitAutomaticTenantOrgScope === true) {\n if (debugEnabled) this.debug('query:fallback:omit-automatic-scope', { entity })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'omit_automatic_tenant_org_scope' })\n return await applyAfterExtensions(fallbackResult)\n }\n\n const normalizedFilters = normalizeFilters(opts.filters)\n const cfFilters = normalizedFilters.filter((filter) => filter.field.startsWith('cf:') || filter.field.startsWith('l10n:'))\n const coverageScope = this.resolveCoverageSnapshotScope(opts)\n const wantsCf = (\n (opts.fields || []).some((field) => typeof field === 'string' && (field.startsWith('cf:') || field.startsWith('l10n:'))) ||\n cfFilters.length > 0 ||\n (Array.isArray(opts.includeCustomFields) && opts.includeCustomFields.length > 0)\n )\n\n if (debugEnabled) {\n this.debug('query:config', {\n entity,\n wantsCustomFields: wantsCf,\n customFieldSources: Array.isArray(opts.customFieldSources) ? opts.customFieldSources.map((src) => src?.entityId) : undefined,\n fields: opts.fields,\n })\n }\n\n let partialIndexWarning: PartialIndexWarning | null = null\n let entityHasActiveCustomFields = true\n\n if (wantsCf) {\n entityHasActiveCustomFields = await this.entityHasActiveCustomFields(entity, opts.tenantId ?? null)\n const hasIndexRows = await profiler.measure(\n 'index_any_rows',\n () => this.indexAnyRows(entity),\n (value) => ({ hasIndexRows: value })\n )\n if (!hasIndexRows) {\n if (debugEnabled) this.debug('query:fallback:no-index', { entity })\n const fallbackResult = await this.fallback.query(entity, opts)\n finishProfile({ result: 'fallback', reason: 'no_index_rows' })\n return await applyAfterExtensions(fallbackResult)\n }\n if (entityHasActiveCustomFields) {\n const gap = await profiler.measure(\n 'resolve_coverage_gap',\n () => this.resolveCoverageGap(entity, opts, coverageScope),\n (value) => (value\n ? {\n scope: value.scope,\n baseCount: value.stats?.baseCount ?? null,\n indexedCount: value.stats?.indexedCount ?? null,\n }\n : { scope: null })\n )\n if (gap) {\n if (!opts.skipAutoReindex) {\n this.scheduleAutoReindex(entity, opts, gap.stats, coverageScope?.organizationId ?? null)\n }\n const force = this.isForcePartialIndexEnabled()\n if (!force) {\n if (gap.stats) {\n console.warn('[HybridQueryEngine] Partial index coverage detected; falling back to basic engine:', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n if (debugEnabled) this.debug('query:fallback:partial-coverage', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n } else {\n console.warn('[HybridQueryEngine] Partial index coverage detected; falling back to basic engine:', { entity })\n if (debugEnabled) this.debug('query:fallback:partial-coverage', { entity })\n }\n const fallbackResult = await this.fallback.query(entity, opts)\n const resultWithWarning: QueryResult<T> = {\n ...fallbackResult,\n meta: {\n ...(fallbackResult.meta ?? {}),\n partialIndexWarning: {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n },\n },\n }\n finishProfile({\n result: 'fallback',\n reason: 'partial_index',\n scope: gap.scope,\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n })\n return await applyAfterExtensions(resultWithWarning)\n }\n if (gap.stats) {\n console.warn('[HybridQueryEngine] Partial index coverage detected; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n } else {\n console.warn('[HybridQueryEngine] Partial index coverage detected; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity })\n }\n partialIndexWarning = {\n entity,\n entityLabel: this.resolveEntityLabel(entity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n }\n }\n } else if (debugEnabled) {\n this.debug('query:coverage:skip-no-custom-fields', { entity })\n }\n }\n\n const qualify = (col: string) => `b.${col}`\n const columns = await this.getBaseColumnsForEntity(entity)\n const hasOrganizationColumn = await this.columnExists(baseTable, 'organization_id')\n const hasTenantColumn = await this.columnExists(baseTable, 'tenant_id')\n const hasDeletedColumn = await this.columnExists(baseTable, 'deleted_at')\n\n if (!opts.tenantId) throw new Error('QueryEngine: tenantId is required')\n\n const resolvedJoinsConfig = resolveJoins(\n baseTable,\n [...(opts.joins ?? []), ...buildFilterableCustomFieldJoins(opts.customFieldSources)],\n (entityId) => resolveEntityTableName(this.em, entityId as any),\n )\n const joinMap = new Map<string, ResolvedJoin>()\n const aliasTables = new Map<string, string>()\n aliasTables.set('b', baseTable)\n aliasTables.set('base', baseTable)\n aliasTables.set(baseTable, baseTable)\n for (const join of resolvedJoinsConfig) {\n joinMap.set(join.alias, join)\n aliasTables.set(join.alias, join.table)\n }\n const { baseFilters, joinFilters } = partitionFilters(baseTable, normalizedFilters, joinMap)\n\n const searchRuntimeBase = {\n enabled: false,\n config: searchConfig,\n organizationScope: orgScope,\n tenantId: opts.tenantId ?? null,\n }\n\n // Prepare index sources for JSONB custom-field access.\n const indexSources: IndexDocSource[] = [{ alias: 'ei', entityId: entity, recordIdColumn: 'b.id' }]\n let preparedCfSources: PreparedCustomFieldSource[] = []\n const shouldAttachCustomSources = Array.isArray(opts.customFieldSources) && opts.customFieldSources.length > 0 && (wantsCf || searchEnabled)\n if (shouldAttachCustomSources) {\n preparedCfSources = this.prepareCustomFieldSources(opts.customFieldSources ?? [])\n for (const source of preparedCfSources) {\n indexSources.push({ alias: source.indexAlias, entityId: source.entityId, recordIdColumn: `${source.alias}.${source.recordIdColumn}` })\n }\n }\n\n const searchSources: SearchTokenSource[] = indexSources\n .map((src) => ({ entity: String(src.entityId), recordIdColumn: src.recordIdColumn }))\n .filter((src) => src.recordIdColumn && src.entity)\n const hasSearchTokens = searchEnabled && searchSources.length\n ? await this.searchSourcesHaveTokens(searchSources, opts.tenantId ?? null, orgScope)\n : false\n const searchRuntime: SearchRuntime = { ...searchRuntimeBase, searchSources, enabled: searchEnabled && hasSearchTokens }\n const joinSearchAvailability = new Map<string, boolean>()\n const searchFilters = normalizeFilters(opts.filters).filter((filter) => filter.op === 'like' || filter.op === 'ilike')\n if (searchFilters.length) {\n this.logSearchDebug('search:init', {\n entity,\n baseTable,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n fields: searchFilters.map((filter) => String(filter.field)),\n searchEnabled,\n hasSearchTokens,\n searchSources,\n searchConfig: {\n enabled: searchConfig.enabled,\n minTokenLength: searchConfig.minTokenLength,\n enablePartials: searchConfig.enablePartials,\n hashAlgorithm: searchConfig.hashAlgorithm,\n blocklistedFields: searchConfig.blocklistedFields,\n },\n })\n if (!searchEnabled) this.logSearchDebug('search:disabled', { entity, baseTable })\n else if (!hasSearchTokens) this.logSearchDebug('search:no-search-tokens', {\n entity, baseTable,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n searchSources,\n })\n }\n const hasNonBaseSearchSource = searchSources.some(\n (src) => src.entity !== String(entity) || src.recordIdColumn !== 'b.id'\n )\n\n // Additional partial-coverage checks for customFieldSources\n if (!partialIndexWarning && Array.isArray(opts.customFieldSources) && opts.customFieldSources.length > 0 && this.isForcePartialIndexEnabled()) {\n const seen = new Set<string>([entity])\n for (const source of opts.customFieldSources) {\n const targetEntity = source?.entityId ? String(source.entityId) : null\n if (!targetEntity || seen.has(targetEntity)) continue\n seen.add(targetEntity)\n const sourceHasCustomFields = await this.entityHasActiveCustomFields(targetEntity, opts.tenantId ?? null)\n if (!sourceHasCustomFields) {\n if (debugEnabled) this.debug('query:coverage:skip-no-custom-fields', { entity: targetEntity })\n continue\n }\n const sourceTable = source.table ?? resolveEntityTableName(this.em, targetEntity)\n try {\n const gap = await profiler.measure(\n 'resolve_coverage_gap',\n () => this.resolveCoverageGap(targetEntity, opts, coverageScope, sourceTable),\n (value) => (value\n ? {\n entity: targetEntity, scope: value.scope,\n baseCount: value.stats?.baseCount ?? null,\n indexedCount: value.stats?.indexedCount ?? null,\n }\n : { entity: targetEntity, scope: null })\n )\n if (!gap) continue\n if (!opts.skipAutoReindex) {\n this.scheduleAutoReindex(targetEntity, opts, gap.stats, coverageScope?.organizationId ?? null)\n }\n partialIndexWarning = {\n entity: targetEntity,\n entityLabel: this.resolveEntityLabel(targetEntity),\n baseCount: gap.stats?.baseCount ?? null,\n indexedCount: gap.stats?.indexedCount ?? null,\n scope: gap.stats ? gap.scope : undefined,\n }\n if (debugEnabled) {\n if (gap.stats) this.debug('query:partial-coverage:forced', { entity: targetEntity, baseCount: gap.stats.baseCount, indexedCount: gap.stats.indexedCount, scope: gap.scope })\n else this.debug('query:partial-coverage:forced', { entity: targetEntity })\n }\n break\n } catch (err) {\n if (debugEnabled) this.debug('query:partial-coverage:check-failed', { entity: targetEntity, error: err instanceof Error ? err.message : err })\n }\n }\n }\n\n if (\n !partialIndexWarning &&\n wantsCf &&\n entityHasActiveCustomFields &&\n this.isForcePartialIndexEnabled() &&\n opts.tenantId\n ) {\n try {\n await this.indexCoverageStats(entity, opts, coverageScope)\n const globalStats = await this.indexCoverageStats(entity, opts, coverageScope)\n if (globalStats) {\n const globalBase = globalStats.baseCount\n const globalIndexed = globalStats.indexedCount\n const globalGap = (globalBase > 0 && globalIndexed < globalBase) || globalIndexed > globalBase\n if (globalGap) {\n console.warn('[HybridQueryEngine] Partial index coverage detected at global scope; forcing query index usage due to FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES:', { entity, baseCount: globalBase, indexedCount: globalIndexed, scope: 'global' })\n if (debugEnabled) this.debug('query:partial-coverage:forced', { entity, baseCount: globalBase, indexedCount: globalIndexed, scope: 'global' })\n partialIndexWarning = {\n entity, entityLabel: this.resolveEntityLabel(entity),\n baseCount: globalBase, indexedCount: globalIndexed, scope: 'global',\n }\n }\n }\n } catch (err) {\n if (debugEnabled) this.debug('query:partial-coverage:global-check-failed', { entity, error: err instanceof Error ? err.message : err })\n }\n }\n\n const resolveBaseColumn = (field: string): string | null => {\n if (columns.has(field)) return field\n if (field === 'organization_id' && columns.has('id')) return 'id'\n return null\n }\n\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // Build a reusable \"applyQueryShape\" function that applies every\n // WHERE/JOIN/scope to a fresh SelectQueryBuilder. We use this in\n // place of knex's `.clone()` for producing count + data queries.\n // \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n const applyBaseScope = (q: AnyBuilder): AnyBuilder => {\n let next = q\n if (orgScope && hasOrganizationColumn) {\n next = this.applyOrganizationScope(next, qualify('organization_id'), orgScope)\n }\n if (hasTenantColumn) {\n next = next.where(qualify('tenant_id'), '=', opts.tenantId)\n }\n if (!opts.withDeleted && hasDeletedColumn) {\n next = next.where(qualify('deleted_at'), 'is', null)\n }\n return next\n }\n\n const applyEntityIndexesJoin = (q: AnyBuilder): AnyBuilder => {\n return q.leftJoin('entity_indexes as ei', (jb: any) => {\n let jc = jb\n .on('ei.entity_type', '=', String(entity))\n .onRef('ei.entity_id', '=', sql<string>`(${sql.ref(qualify('id'))}::text)`)\n if (hasOrganizationColumn) {\n jc = jc\n .onRef('ei.organization_id', '=', qualify('organization_id'))\n .on('ei.organization_id', 'is not', null)\n }\n if (hasTenantColumn) {\n jc = jc\n .onRef('ei.tenant_id', '=', qualify('tenant_id'))\n .on('ei.tenant_id', 'is not', null)\n }\n if (!opts.withDeleted) {\n jc = jc.on('ei.deleted_at', 'is', null)\n }\n return jc\n })\n }\n\n const applyCustomFieldSourceJoins = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const source of preparedCfSources) {\n const join = (opts.customFieldSources ?? []).find((s) => s && (s.alias ?? undefined) === source.alias)?.join\n if (!join) continue\n const joinType = (join.type ?? 'left') === 'inner' ? 'innerJoin' : 'leftJoin'\n next = (next as any)[joinType](`${source.table} as ${source.alias}`, (jb: any) =>\n jb.onRef(`${source.alias}.${join.toField}`, '=', qualify(join.fromField)))\n // Index join for source\n next = next.leftJoin(`entity_indexes as ${source.indexAlias}`, (jb: any) => {\n let jc = jb\n .on(`${source.indexAlias}.entity_type`, '=', String(source.entityId))\n .onRef(`${source.indexAlias}.entity_id`, '=', sql<string>`(${sql.ref(`${source.alias}.${source.recordIdColumn}`)}::text)`)\n const orgRef = source.organizationField\n ? `${source.alias}.${source.organizationField}`\n : (columns.has('organization_id') ? qualify('organization_id') : null)\n if (orgRef) {\n jc = jc\n .onRef(`${source.indexAlias}.organization_id`, '=', orgRef)\n .on(`${source.indexAlias}.organization_id`, 'is not', null)\n }\n const tenantRef = source.tenantField\n ? `${source.alias}.${source.tenantField}`\n : (columns.has('tenant_id') ? qualify('tenant_id') : null)\n if (tenantRef) {\n jc = jc\n .onRef(`${source.indexAlias}.tenant_id`, '=', tenantRef)\n .on(`${source.indexAlias}.tenant_id`, 'is not', null)\n }\n if (!opts.withDeleted) jc = jc.on(`${source.indexAlias}.deleted_at`, 'is', null)\n return jc\n })\n }\n return next\n }\n\n const applyCfFilters = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const filter of cfFilters) {\n next = this.applyCfFilterAcrossSources(\n next, filter.field, filter.op, filter.value, indexSources, searchRuntime,\n )\n }\n return next\n }\n\n const regularBaseFilters = baseFilters.filter((filter) => !filter.orGroup)\n const orGroupFilters = baseFilters.filter((filter) => filter.orGroup)\n\n const applyRegularBaseFilters = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const filter of regularBaseFilters) {\n const fieldName = String(filter.field)\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) {\n next = this.applyIndexDocFilterFromAlias(\n next, 'ei', entity, fieldName, filter.op, filter.value, 'b.id', searchRuntime,\n )\n continue\n }\n const column = qualify(baseField)\n next = this.applyColumnFilter(next, column, filter, {\n ...searchRuntime,\n entity, field: fieldName, recordIdColumn: 'b.id',\n })\n }\n return next\n }\n\n const applyOrGroupedBaseFilters = (q: AnyBuilder): AnyBuilder => {\n if (orGroupFilters.length === 0) return q\n const groups = new Map<string, BaseFilter[]>()\n for (const filter of orGroupFilters) {\n if (!filter.orGroup) continue\n const existing = groups.get(filter.orGroup) ?? []\n existing.push(filter)\n groups.set(filter.orGroup, existing)\n }\n const groupList = Array.from(groups.values()).filter((g) => g.length > 0)\n if (groupList.length === 0) return q\n // Combine all groups in a single WHERE: disjuncts are OR'd together; within\n // each disjunct, fields are AND'd. Building this as separate `.where()` calls\n // would AND the disjuncts (wrong semantics).\n return q.where((eb: any) => eb.or(\n groupList.map((groupFilters) => {\n const parts = groupFilters.map((filter) =>\n this.buildBaseFilterExpression(eb, filter, resolveBaseColumn, qualify, entity, searchRuntime),\n )\n return parts.length === 1 ? parts[0] : eb.and(parts)\n }),\n ))\n }\n\n const applyAliasScopes = async (target: AnyBuilder, aliasName: string): Promise<AnyBuilder> => {\n let next = target\n const tableName = aliasTables.get(aliasName)\n if (!tableName) return next\n if (orgScope && await this.columnExists(tableName, 'organization_id')) {\n next = this.applyOrganizationScope(next, `${aliasName}.organization_id`, orgScope)\n }\n if (opts.tenantId && await this.columnExists(tableName, 'tenant_id')) {\n next = next.where(`${aliasName}.tenant_id`, '=', opts.tenantId)\n }\n if (!opts.withDeleted && await this.columnExists(tableName, 'deleted_at')) {\n next = next.where(`${aliasName}.deleted_at`, 'is', null)\n }\n return next\n }\n\n const applyJoinFilterOpFn = (target: AnyBuilder, column: string, op: FilterOp, value?: unknown): AnyBuilder => {\n switch (op) {\n case 'eq': return target.where(column, '=', value as any)\n case 'ne': return target.where(column, '!=', value as any)\n case 'gt': return target.where(column, '>', value as any)\n case 'gte': return target.where(column, '>=', value as any)\n case 'lt': return target.where(column, '<', value as any)\n case 'lte': return target.where(column, '<=', value as any)\n case 'in': return target.where(column, 'in', this.toArray(value))\n case 'nin': return target.where(column, 'not in', this.toArray(value))\n case 'like': return target.where(column, 'like', value as any)\n case 'ilike': return target.where(column, 'ilike', value as any)\n case 'exists': return value ? target.where(column, 'is not', null) : target.where(column, 'is', null)\n default: return target\n }\n }\n\n const applyJoinSearchFilterOp = async (\n target: AnyBuilder,\n filter: { column: string; op: FilterOp; value?: unknown },\n _qualified: string,\n join: ResolvedJoin,\n ): Promise<boolean> => {\n if (!searchEnabled || !join.entityId) return false\n if (!['like', 'ilike'].includes(filter.op)) return false\n if (typeof filter.value !== 'string' || filter.value.trim().length === 0) return false\n\n let searchAvailable = joinSearchAvailability.get(join.entityId)\n if (searchAvailable === undefined) {\n searchAvailable = await this.hasSearchTokens(String(join.entityId), opts.tenantId ?? null, orgScope)\n joinSearchAvailability.set(join.entityId, searchAvailable)\n }\n if (!searchAvailable) return false\n\n const tokens = tokenizeText(String(filter.value), searchConfig)\n if (!tokens.hashes.length) return false\n\n return this.applySearchTokens(target, {\n entity: String(join.entityId),\n field: filter.column,\n hashes: tokens.hashes,\n recordIdColumn: `${join.alias}.id`,\n tenantId: opts.tenantId ?? null,\n organizationScope: orgScope,\n })\n }\n\n const applyQueryShape = async (q: AnyBuilder): Promise<AnyBuilder> => {\n let next = applyBaseScope(q)\n next = applyEntityIndexesJoin(next)\n next = applyCustomFieldSourceJoins(next)\n next = applyCfFilters(next)\n next = applyRegularBaseFilters(next)\n next = applyOrGroupedBaseFilters(next)\n // applyJoinFilters is the shared helper that handles `joinFilters` (ALIAS:col -> value).\n next = await applyJoinFilters({\n db,\n baseTable,\n builder: next,\n joinMap,\n joinFilters,\n aliasTables,\n qualifyBase: (column) => qualify(column),\n applyAliasScope: async (target: any, alias: string) => applyAliasScopes(target as AnyBuilder, alias),\n applyFilterOp: (target, column, op, value) => applyJoinFilterOpFn(target as AnyBuilder, column, op, value),\n applyJoinFilterOp: async (target, filter, qualified, join) => {\n const applied = await applyJoinSearchFilterOp(target as AnyBuilder, filter, qualified, join)\n return { applied, builder: target }\n },\n columnExists: (tbl, column) => this.columnExists(tbl, column),\n })\n return next\n }\n\n const hasCustomFieldFilters = cfFilters.length > 0\n const canOptimizeCount = !hasCustomFieldFilters && !hasNonBaseSearchSource\n\n // Selection (for data query)\n const selectFieldSet = new Set<string>((opts.fields && opts.fields.length) ? opts.fields.map(String) : Array.from(columns.keys()))\n if (opts.includeCustomFields === true) {\n const entityIds = Array.from(new Set(indexSources.map((src) => String(src.entityId))))\n try {\n const resolvedKeys = await this.resolveAvailableCustomFieldKeys(entityIds, opts.tenantId ?? null)\n resolvedKeys.forEach((key) => selectFieldSet.add(`cf:${key}`))\n if (this.isDebugVerbosity()) this.debug('query:cf:resolved-keys', { entity, keys: resolvedKeys })\n } catch (err) {\n console.warn('[HybridQueryEngine] Failed to resolve custom field keys for', entity, err)\n }\n } else if (Array.isArray(opts.includeCustomFields)) {\n opts.includeCustomFields.map((key) => String(key)).forEach((key) => selectFieldSet.add(`cf:${key}`))\n }\n const selectFields = Array.from(selectFieldSet)\n\n const applySelection = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const field of selectFields) {\n const fieldName = String(field)\n if (fieldName.startsWith('cf:')) {\n const alias = this.sanitize(fieldName)\n const jsonExpr = this.buildCfJsonExprSql(fieldName, indexSources)\n const exprRaw = jsonExpr ?? sql`NULL::jsonb`\n next = next.select(exprRaw.as(alias))\n } else if (columns.has(fieldName)) {\n next = next.select(`${qualify(fieldName)} as ${fieldName}`)\n }\n }\n return next\n }\n\n const applySort = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const s of opts.sort || []) {\n const fieldName = String(s.field)\n if (fieldName.startsWith('cf:')) {\n const textExpr = this.buildCfTextExprSql(fieldName, indexSources)\n if (textExpr) {\n const direction = sql.raw(String(s.dir ?? SortDir.Asc))\n next = next.orderBy(sql`${textExpr} ${direction}`)\n }\n } else {\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) continue\n next = next.orderBy(qualify(baseField), s.dir ?? SortDir.Asc)\n }\n }\n return next\n }\n\n const page = opts.page?.page ?? 1\n const pageSize = opts.page?.pageSize ?? 20\n const sqlDebugEnabled = this.isSqlDebugEnabled()\n\n let total: number\n\n if (canOptimizeCount) {\n // Optimized count: apply only base-scope + regular filters + or-group filters (no index joins).\n const optimizedRoot = db.selectFrom(`${baseTable} as b` as any)\n let countCore = applyBaseScope(optimizedRoot)\n countCore = applyRegularBaseFilters(countCore)\n countCore = applyOrGroupedBaseFilters(countCore)\n // joinFilters still need to be re-applied in the optimized path\n countCore = await applyJoinFilters({\n db,\n baseTable,\n builder: countCore,\n joinMap,\n joinFilters,\n aliasTables,\n qualifyBase: (column) => qualify(column),\n applyAliasScope: async (target: any, alias: string) => applyAliasScopes(target as AnyBuilder, alias),\n applyFilterOp: (target, column, op, value) => applyJoinFilterOpFn(target as AnyBuilder, column, op, value),\n applyJoinFilterOp: async (target, filter, qualified, join) => {\n const applied = await applyJoinSearchFilterOp(target as AnyBuilder, filter, qualified, join)\n return { applied, builder: target }\n },\n columnExists: (tbl, column) => this.columnExists(tbl, column),\n })\n const sub = countCore.select(sql.ref(qualify('id')).as('id')).groupBy(qualify('id')).as('sq')\n const countQuery = db.selectFrom(sub as any).select(sql<string>`count(*)`.as('count'))\n if (debugEnabled && sqlDebugEnabled) {\n const compiled = countQuery.compile()\n this.debug('query:sql:count', { entity, sql: compiled.sql, bindings: compiled.parameters })\n }\n const countRow = await this.captureSqlTiming(\n 'query:sql:count', entity,\n () => countQuery.executeTakeFirst(),\n { optimized: true }, profiler,\n )\n total = this.parseCount(countRow)\n } else {\n const countRoot = db.selectFrom(`${baseTable} as b` as any)\n const countBuilder = (await applyQueryShape(countRoot))\n .select(sql<string>`count(distinct ${sql.ref(qualify('id'))})`.as('count'))\n if (debugEnabled && sqlDebugEnabled) {\n const compiled = countBuilder.compile()\n this.debug('query:sql:count', { entity, sql: compiled.sql, bindings: compiled.parameters })\n }\n const countRow = await this.captureSqlTiming(\n 'query:sql:count', entity,\n () => countBuilder.executeTakeFirst(),\n { optimized: false }, profiler,\n )\n total = this.parseCount(countRow)\n }\n\n const dataRoot = db.selectFrom(`${baseTable} as b` as any)\n let dataBuilder = await applyQueryShape(dataRoot)\n dataBuilder = applySelection(dataBuilder)\n dataBuilder = applySort(dataBuilder)\n dataBuilder = dataBuilder.limit(pageSize).offset((page - 1) * pageSize)\n\n if (debugEnabled && sqlDebugEnabled) {\n const compiled = dataBuilder.compile()\n this.debug('query:sql:data', { entity, sql: compiled.sql, bindings: compiled.parameters, page, pageSize })\n }\n const itemsRaw = await this.captureSqlTiming(\n 'query:sql:data', entity,\n () => dataBuilder.execute(),\n { page, pageSize }, profiler,\n )\n if (debugEnabled) this.debug('query:complete', { entity, total, items: Array.isArray(itemsRaw) ? itemsRaw.length : 0 })\n\n let items = itemsRaw as any[]\n const encSvc = this.getEncryptionService()\n const dekKeyCache = new Map<string | null, string | null>()\n if (encSvc?.decryptEntityPayload) {\n const decrypt = encSvc.decryptEntityPayload.bind(encSvc) as (\n entityId: EntityId, payload: Record<string, unknown>, tenantId: string | null, organizationId: string | null,\n ) => Promise<Record<string, unknown>>\n const fallbackOrgId =\n opts.organizationId\n ?? (Array.isArray(opts.organizationIds) && opts.organizationIds.length === 1 ? opts.organizationIds[0] : null)\n items = await Promise.all(\n items.map(async (item) => {\n try {\n const decrypted = await decrypt(\n entity, item,\n item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,\n item?.organization_id ?? item?.organizationId ?? fallbackOrgId ?? null,\n )\n return { ...item, ...decrypted }\n } catch (err) {\n console.error('Error decrypting entity payload', err)\n return item\n }\n })\n )\n }\n if (encSvc) {\n items = await Promise.all(\n items.map(async (item) => {\n try {\n return await decryptIndexDocCustomFields(\n item,\n {\n tenantId: item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,\n organizationId: item?.organization_id ?? item?.organizationId ?? null,\n },\n encSvc as any, dekKeyCache,\n )\n } catch { return item }\n }),\n )\n }\n\n const typedItems = items as unknown as T[]\n let result: QueryResult<T> = { items: typedItems, page, pageSize, total }\n if (partialIndexWarning) result.meta = { partialIndexWarning }\n\n result = await applyAfterExtensions(result)\n finishProfile({\n result: 'ok', total, page, pageSize,\n itemCount: Array.isArray(items) ? items.length : undefined,\n partialIndexWarning: partialIndexWarning ? true : false,\n })\n return result\n } catch (err) {\n finishProfile({ result: 'error', error: err instanceof Error ? err.message : String(err) })\n throw err\n }\n }\n\n private prepareCustomFieldSources(\n sources: QueryCustomFieldSource[],\n ): PreparedCustomFieldSource[] {\n const prepared: PreparedCustomFieldSource[] = []\n sources.forEach((source, index) => {\n if (!source) return\n const joinTable = source.table ?? resolveEntityTableName(this.em, source.entityId)\n const alias = source.alias ?? `cfs_${index}`\n if (!source.join) {\n throw new Error(`QueryEngine: customFieldSources entry for ${String(source.entityId)} requires a join configuration`)\n }\n prepared.push({\n alias,\n indexAlias: `ei_${alias}`,\n entityId: source.entityId,\n recordIdColumn: source.recordIdColumn ?? 'id',\n organizationField: source.organizationField,\n tenantField: source.tenantField,\n table: joinTable,\n })\n })\n return prepared\n }\n\n private async isCustomEntity(entity: string): Promise<boolean> {\n try {\n const db = this.getDb() as any\n const row = await db\n .selectFrom('custom_entities')\n .select('id')\n .where('entity_id', '=', entity)\n .where('is_active', '=', true)\n .executeTakeFirst()\n return !!row\n } catch {\n return false\n }\n }\n\n /**\n * Adds a WHERE EXISTS / OR WHERE EXISTS subquery that matches\n * `search_tokens` for the supplied (entity, field) against the\n * provided record id column.\n *\n * Returns true when the sub-query was applied (i.e. tokens were\n * non-empty). Caller is responsible for the calling context\n * (direct where vs. inside `eb.or([...])`).\n */\n private applySearchTokens(\n q: AnyBuilder,\n opts: {\n entity: string\n field: string\n hashes: string[]\n recordIdColumn: string\n tenantId?: string | null\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n combineWith?: 'and' | 'or'\n }\n ): boolean {\n if (!opts.hashes.length) {\n this.logSearchDebug('search:skip-no-hashes', {\n entity: opts.entity, field: opts.field,\n tenantId: opts.tenantId ?? null, organizationScope: opts.organizationScope,\n })\n return false\n }\n const alias = `st_${this.searchAliasSeq++}`\n this.logSearchDebug('search:apply-search-tokens', {\n entity: opts.entity, field: opts.field, alias,\n tokenCount: opts.hashes.length,\n tenantId: opts.tenantId ?? null,\n organizationScope: opts.organizationScope,\n combineWith: opts.combineWith ?? 'and',\n })\n\n const engine = this\n const buildSub = (eb: any) => {\n let sub = eb\n .selectFrom(`search_tokens as ${alias}`)\n .select(sql<number>`1`.as('one'))\n .where(`${alias}.entity_type`, '=', opts.entity)\n .where(`${alias}.field`, '=', opts.field)\n .where(sql<boolean>`${sql.ref(`${alias}.entity_id`)} = ${sql.ref(opts.recordIdColumn)}::text`)\n .where(`${alias}.token_hash`, 'in', opts.hashes)\n .groupBy([`${alias}.entity_id`, `${alias}.field`])\n .having(sql<boolean>`count(distinct ${sql.ref(`${alias}.token_hash`)}) >= ${opts.hashes.length}`)\n if (opts.tenantId !== undefined) {\n sub = sub.where(sql<boolean>`${sql.ref(`${alias}.tenant_id`)} is not distinct from ${opts.tenantId ?? null}`)\n }\n if (opts.organizationScope) {\n sub = engine.applyOrganizationScope(sub, `${alias}.organization_id`, opts.organizationScope)\n }\n return sub\n }\n\n if (opts.combineWith === 'or') {\n // When called inside an .or([...]) array the caller supplied `eb`.\n // `q` is the ExpressionBuilder callable (eb) itself in that case.\n // We return the expression node rather than mutating q.\n ;(q as any).__pendingOrExists = buildSub(q)\n return true\n }\n\n // Default: append WHERE EXISTS (...) to the outer builder.\n ;(q as any).__applied = true\n const built = buildSub(q)\n // If q is a Kysely builder (has .where), use eb => eb.exists(sub)\n if (typeof q.where === 'function') {\n ;(q as any) = q.where((eb: any) => eb.exists(built))\n }\n return true\n }\n\n /** SQL fragment for `cf:<key>` (or legacy bare key) as JSON across a single alias. */\n private jsonbSqlAlias(alias: string, key: string): RawBuilder<unknown> {\n if (key.startsWith('cf:')) {\n const bare = key.slice(3)\n return sql`coalesce(${sql.ref(alias + '.doc')} -> ${key}, ${sql.ref(alias + '.doc')} -> ${bare})`\n }\n return sql`${sql.ref(alias + '.doc')} -> ${key}`\n }\n\n /** SQL fragment for `cf:<key>` (or legacy bare key) as text across a single alias. */\n private cfTextExprAlias(alias: string, key: string): RawBuilder<string | null> {\n if (key.startsWith('cf:')) {\n const bare = key.slice(3)\n return sql<string | null>`coalesce((${sql.ref(alias + '.doc')} ->> ${key}), (${sql.ref(alias + '.doc')} ->> ${bare}))`\n }\n return sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${key})`\n }\n\n /** Build JSON/text SQL expressions across multiple index alias sources (coalesce over them). */\n private buildCfJsonExprSql(key: string, sources: IndexDocSource[]): RawBuilder<unknown> | null {\n if (!sources.length) return null\n const parts = sources.map((src) => this.jsonbSqlAlias(src.alias, key))\n if (parts.length === 1) return parts[0]\n return sql`coalesce(${sql.join(parts, sql`, `)})`\n }\n\n private buildCfTextExprSql(key: string, sources: IndexDocSource[]): RawBuilder<string | null> | null {\n if (!sources.length) return null\n const parts = sources.map((src) => this.cfTextExprAlias(src.alias, key))\n if (parts.length === 1) return parts[0]\n return sql<string | null>`coalesce(${sql.join(parts, sql`, `)})`\n }\n\n private applyCfFilterAcrossSources(\n builder: AnyBuilder,\n key: string,\n op: FilterOp,\n value: unknown,\n sources: IndexDocSource[],\n search?: SearchRuntime\n ): AnyBuilder {\n if (!sources.length) return builder\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = this.applyMultiSourceSearchExists(builder, sources, key, hashes, search)\n this.logSearchDebug('search:cf-filter-across', {\n entity: sources.map((src) => src.entityId),\n field: key, tokens: tokens.tokens, hashes, applied,\n tenantId: search.tenantId ?? null, organizationScope: search.organizationScope,\n })\n if (applied.builder !== builder) return applied.builder\n } else {\n this.logSearchDebug('search:cf-skip-empty-hashes', {\n entity: sources.map((src) => src.entityId), field: key, value,\n })\n }\n return builder\n }\n\n const textExpr = this.buildCfTextExprSql(key, sources)\n const jsonExpr = this.buildCfJsonExprSql(key, sources)\n if (!textExpr || !jsonExpr) return builder\n\n const arrContains = (val: unknown) => sql<boolean>`${jsonExpr} @> ${JSON.stringify([val])}::jsonb`\n\n switch (op) {\n case 'eq':\n return builder.where((eb: any) => eb.or([\n sql<boolean>`${textExpr} = ${value}`,\n arrContains(value),\n ]))\n case 'ne':\n return builder.where(sql<boolean>`${textExpr} <> ${value}`)\n case 'in': {\n const values = this.toArray(value)\n return builder.where((eb: any) => eb.or(\n values.flatMap((val) => [\n sql<boolean>`${textExpr} = ${val}`,\n arrContains(val),\n ])\n ))\n }\n case 'nin': {\n const values = this.toArray(value)\n return builder.where(sql<boolean>`${textExpr} not in (${sql.join(values.map((v) => sql`${v}`), sql`, `)})`)\n }\n case 'like':\n return builder.where(sql<boolean>`${textExpr} like ${value}`)\n case 'ilike':\n return builder.where(sql<boolean>`${textExpr} ilike ${value}`)\n case 'exists':\n return value\n ? builder.where(sql<boolean>`${textExpr} is not null`)\n : builder.where(sql<boolean>`${textExpr} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = sql.raw(op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<=')\n return builder.where(sql<boolean>`${textExpr} ${operator} ${value}`)\n }\n default:\n return builder\n }\n }\n\n /** Apply a search-token EXISTS subquery across multiple sources (OR-joined). */\n private applyMultiSourceSearchExists(\n builder: AnyBuilder,\n sources: IndexDocSource[],\n key: string,\n hashes: string[],\n search: SearchRuntime,\n ): { builder: AnyBuilder; applied: boolean } {\n if (!sources.length || !hashes.length) return { builder, applied: false }\n const next = builder.where((eb: any) => eb.or(\n sources.map((source) =>\n eb.exists(this.buildSearchTokensSub(eb, {\n entity: String(source.entityId),\n field: key, hashes,\n recordIdColumn: `${source.alias}.entity_id`,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n }))\n )\n ))\n return { builder: next, applied: true }\n }\n\n /** Construct a search-token EXISTS subquery using the given ExpressionBuilder. */\n private buildSearchTokensSub(\n eb: any,\n opts: {\n entity: string\n field: string\n hashes: string[]\n recordIdColumn: string\n tenantId?: string | null\n organizationScope?: { ids: string[]; includeNull: boolean } | null\n }\n ): any {\n const alias = `st_${this.searchAliasSeq++}`\n let sub = eb\n .selectFrom(`search_tokens as ${alias}`)\n .select(sql<number>`1`.as('one'))\n .where(`${alias}.entity_type`, '=', opts.entity)\n .where(`${alias}.field`, '=', opts.field)\n .where(sql<boolean>`${sql.ref(`${alias}.entity_id`)} = ${sql.ref(opts.recordIdColumn)}::text`)\n .where(`${alias}.token_hash`, 'in', opts.hashes)\n .groupBy([`${alias}.entity_id`, `${alias}.field`])\n .having(sql<boolean>`count(distinct ${sql.ref(`${alias}.token_hash`)}) >= ${opts.hashes.length}`)\n if (opts.tenantId !== undefined) {\n sub = sub.where(sql<boolean>`${sql.ref(`${alias}.tenant_id`)} is not distinct from ${opts.tenantId ?? null}`)\n }\n if (opts.organizationScope) {\n sub = this.applyOrganizationScope(sub, `${alias}.organization_id`, opts.organizationScope)\n }\n return sub\n }\n\n private applyCfFilterFromAlias(\n q: AnyBuilder,\n alias: string,\n entityType: string,\n key: string,\n op: FilterOp,\n value: unknown,\n search?: SearchRuntime\n ): AnyBuilder {\n const textExpr = this.cfTextExprAlias(alias, key)\n const arrExpr = sql<unknown>`(${sql.ref(alias + '.doc')} -> ${key})`\n const arrContains = (val: unknown) => sql<boolean>`${arrExpr} @> ${JSON.stringify([val])}::jsonb`\n\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = q.where((eb: any) => eb.exists(this.buildSearchTokensSub(eb, {\n entity: entityType, field: key, hashes,\n recordIdColumn: `${alias}.entity_id`,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })))\n this.logSearchDebug('search:cf-filter', {\n entity: entityType, field: key, tokens: tokens.tokens, hashes, applied: true,\n tenantId: search.tenantId ?? null, organizationScope: search.organizationScope,\n })\n return applied\n } else {\n this.logSearchDebug('search:cf-skip-empty-hashes', { entity: entityType, field: key, value })\n }\n return q\n }\n switch (op) {\n case 'eq':\n return q.where((eb: any) => eb.or([\n sql<boolean>`${textExpr} = ${value}`,\n arrContains(value),\n ]))\n case 'ne':\n return q.where(sql<boolean>`${textExpr} <> ${value}`)\n case 'in': {\n const vals = this.toArray(value)\n return q.where((eb: any) => eb.or(\n vals.flatMap((val) => [\n sql<boolean>`${textExpr} = ${val}`,\n arrContains(val),\n ])\n ))\n }\n case 'nin': {\n const vals = this.toArray(value)\n return q.where(sql<boolean>`${textExpr} not in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`)\n }\n case 'like':\n return q.where(sql<boolean>`${textExpr} like ${value}`)\n case 'ilike':\n return q.where(sql<boolean>`${textExpr} ilike ${value}`)\n case 'exists':\n return value\n ? q.where(sql<boolean>`${textExpr} is not null`)\n : q.where(sql<boolean>`${textExpr} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = sql.raw(op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<=')\n return q.where(sql<boolean>`${textExpr} ${operator} ${value}`)\n }\n default:\n return q\n }\n }\n\n private applyIndexDocFilterFromAlias(\n q: AnyBuilder,\n alias: string,\n entityType: string,\n key: string,\n op: FilterOp,\n value: unknown,\n recordIdColumn: string,\n search?: SearchRuntime,\n ): AnyBuilder {\n const textExpr = sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${key})`\n if ((op === 'like' || op === 'ilike') && search?.enabled && typeof value === 'string') {\n const tokens = tokenizeText(String(value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const applied = q.where((eb: any) => eb.exists(this.buildSearchTokensSub(eb, {\n entity: entityType, field: key, hashes, recordIdColumn,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })))\n this.logSearchDebug('search:index-doc-filter', {\n entity: entityType, field: key, tokens: tokens.tokens, hashes, applied: true,\n tenantId: search.tenantId ?? null, organizationScope: search.organizationScope,\n })\n return applied\n } else {\n this.logSearchDebug('search:index-doc-skip-empty-hashes', { entity: entityType, field: key, value })\n }\n return q\n }\n switch (op) {\n case 'eq':\n return q.where(sql<boolean>`${textExpr} = ${value}`)\n case 'ne':\n return q.where(sql<boolean>`${textExpr} <> ${value}`)\n case 'in': {\n const vals = this.toArray(value)\n return q.where(sql<boolean>`${textExpr} in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`)\n }\n case 'nin': {\n const vals = this.toArray(value)\n return q.where(sql<boolean>`${textExpr} not in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`)\n }\n case 'like':\n return q.where(sql<boolean>`${textExpr} like ${value}`)\n case 'ilike':\n return q.where(sql<boolean>`${textExpr} ilike ${value}`)\n case 'exists':\n return value\n ? q.where(sql<boolean>`${textExpr} is not null`)\n : q.where(sql<boolean>`${textExpr} is null`)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = sql.raw(op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<=')\n return q.where(sql<boolean>`${textExpr} ${operator} ${value}`)\n }\n default:\n return q\n }\n }\n\n /**\n * Build a single OR-group base filter expression as a Kysely predicate\n * (no side effects on the outer builder).\n */\n private buildBaseFilterExpression(\n eb: any,\n filter: BaseFilter,\n resolveBaseColumn: (field: string) => string | null,\n qualify: (col: string) => string,\n entity: EntityId,\n searchRuntime: SearchRuntime,\n ): any {\n const fieldName = String(filter.field)\n const baseField = resolveBaseColumn(fieldName)\n if (!baseField) {\n // Doc-based filter via `ei` alias \u2014 returned as EXISTS where possible\n return this.buildIndexDocFilterExpression(eb, 'ei', entity, fieldName, filter.op, filter.value, 'b.id', searchRuntime)\n }\n // For like/ilike with active search-tokens, route through hashed-token EXISTS subquery\n // so encrypted-at-rest columns can still be searched.\n if (\n (filter.op === 'like' || filter.op === 'ilike') &&\n searchRuntime?.enabled &&\n typeof filter.value === 'string'\n ) {\n const tokens = tokenizeText(String(filter.value), searchRuntime.config)\n if (tokens.hashes.length) {\n const sources: SearchTokenSource[] = (searchRuntime.searchSources && searchRuntime.searchSources.length\n ? searchRuntime.searchSources\n : [{ entity: String(entity), recordIdColumn: 'b.id' }]\n ).filter((src) => src.recordIdColumn && src.entity)\n if (sources.length) {\n return eb.or(\n sources.map((src) =>\n eb.exists(this.buildSearchTokensSub(eb, {\n entity: src.entity,\n field: fieldName,\n hashes: tokens.hashes,\n recordIdColumn: src.recordIdColumn,\n tenantId: searchRuntime.tenantId ?? null,\n organizationScope: searchRuntime.organizationScope ?? null,\n })),\n ),\n )\n }\n }\n // Tokenizer produced no hashes (e.g. value too short). Match the regular-base-filter\n // path's behavior of skipping the predicate (no filter), which is preferable to\n // silently turning into a plain `ilike` against an encrypted column.\n return sql<boolean>`true`\n }\n return this.buildColumnFilterExpression(eb, qualify(baseField), filter.op, filter.value)\n }\n\n private buildColumnFilterExpression(\n eb: any,\n column: string,\n op: FilterOp,\n value: unknown,\n ): any {\n switch (op) {\n case 'eq': return eb(column, '=', value)\n case 'ne': return eb(column, '!=', value)\n case 'gt': return eb(column, '>', value)\n case 'gte': return eb(column, '>=', value)\n case 'lt': return eb(column, '<', value)\n case 'lte': return eb(column, '<=', value)\n case 'in': return eb(column, 'in', this.toArray(value))\n case 'nin': return eb(column, 'not in', this.toArray(value))\n case 'like': return eb(column, 'like', value)\n case 'ilike': return eb(column, 'ilike', value)\n case 'exists': return eb(column, value ? 'is not' : 'is', null)\n default: return sql<boolean>`true`\n }\n }\n\n private buildIndexDocFilterExpression(\n eb: any,\n alias: string,\n _entity: EntityId,\n key: string,\n op: FilterOp,\n value: unknown,\n _recordIdColumn: string,\n _search?: SearchRuntime,\n ): any {\n const textExpr = sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${key})`\n switch (op) {\n case 'eq': return sql<boolean>`${textExpr} = ${value}`\n case 'ne': return sql<boolean>`${textExpr} <> ${value}`\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = sql.raw(op === 'gt' ? '>' : op === 'gte' ? '>=' : op === 'lt' ? '<' : '<=')\n return sql<boolean>`${textExpr} ${operator} ${value}`\n }\n case 'like': return sql<boolean>`${textExpr} like ${value}`\n case 'ilike': return sql<boolean>`${textExpr} ilike ${value}`\n case 'in': {\n const vals = this.toArray(value)\n return sql<boolean>`${textExpr} in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`\n }\n case 'nin': {\n const vals = this.toArray(value)\n return sql<boolean>`${textExpr} not in (${sql.join(vals.map((v) => sql`${v}`), sql`, `)})`\n }\n case 'exists':\n return value ? sql<boolean>`${textExpr} is not null` : sql<boolean>`${textExpr} is null`\n default:\n return sql<boolean>`true`\n }\n }\n\n private async queryCustomEntity<T = unknown>(entity: string, opts: QueryOptions = {}): Promise<QueryResult<T>> {\n const db = this.getDb() as any\n const alias = 'ce'\n\n const orgScope = this.resolveOrganizationScope(opts)\n if (!opts.tenantId) throw new Error('QueryEngine: tenantId is required')\n\n const searchConfig = resolveSearchConfig()\n const searchEnabled = searchConfig.enabled && await this.tableExists('search_tokens')\n const hasSearchTokens = searchEnabled\n ? await this.hasSearchTokens(entity, opts.tenantId ?? null, orgScope)\n : false\n const searchRuntime: SearchRuntime = {\n enabled: searchEnabled && hasSearchTokens,\n config: searchConfig,\n organizationScope: orgScope,\n tenantId: opts.tenantId ?? null,\n }\n\n const normalizedFilters = normalizeFilters(opts.filters)\n\n const applyScope = (q: AnyBuilder): AnyBuilder => {\n let next = q\n .where(`${alias}.entity_type`, '=', entity)\n .where(`${alias}.tenant_id`, '=', opts.tenantId)\n if (orgScope) {\n next = this.applyOrganizationScope(next, `${alias}.organization_id`, orgScope)\n }\n if (!opts.withDeleted) next = next.where(`${alias}.deleted_at`, 'is', null)\n for (const filter of normalizedFilters) {\n if (filter.field.startsWith('cf:')) {\n next = this.applyCfFilterFromAlias(next, alias, entity, filter.field, filter.op, filter.value, searchRuntime)\n continue\n }\n const column = this.resolveCustomEntityColumn(alias, String(filter.field))\n if (column) {\n next = this.applyColumnFilter(next, column, filter, {\n ...searchRuntime, entity, field: String(filter.field), recordIdColumn: `${alias}.entity_id`,\n })\n continue\n }\n // Unknown field \u2192 filter on doc JSON text\n const docExpr = sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${String(filter.field)})`\n next = this.applyColumnFilter(next, docExpr, filter, {\n ...searchRuntime, entity, field: String(filter.field), recordIdColumn: `${alias}.entity_id`,\n })\n }\n return next\n }\n\n // Determine CFs and l10n keys to include\n const cfKeys = new Set<string>()\n for (const f of (opts.fields || [])) {\n if (typeof f === 'string' && f.startsWith('cf:')) cfKeys.add(f.slice(3))\n else if (typeof f === 'string' && f.startsWith('l10n:')) cfKeys.add(f)\n }\n for (const filter of normalizedFilters) {\n if (typeof filter.field === 'string' && filter.field.startsWith('cf:')) cfKeys.add(filter.field.slice(3))\n else if (typeof filter.field === 'string' && filter.field.startsWith('l10n:')) cfKeys.add(filter.field)\n }\n if (opts.includeCustomFields === true) {\n try {\n const rows = await db\n .selectFrom('custom_field_defs')\n .select('key')\n .where('entity_id', '=', entity)\n .where('is_active', '=', true)\n .where('tenant_id', '=', opts.tenantId)\n .execute() as Array<{ key: unknown }>\n for (const row of rows) {\n const key = row.key\n if (typeof key === 'string') cfKeys.add(key)\n else if (key != null) cfKeys.add(String(key))\n }\n } catch {\n // ignore\n }\n } else if (Array.isArray(opts.includeCustomFields)) {\n for (const k of opts.includeCustomFields) cfKeys.add(k)\n }\n\n const applySelection = (q: AnyBuilder): AnyBuilder => {\n let next = q\n const requested = (opts.fields && opts.fields.length) ? opts.fields : ['id']\n for (const field of requested) {\n const f = String(field)\n if (f.startsWith('cf:')) {\n const aliasName = this.sanitize(f)\n next = next.select(this.jsonbSqlAlias(alias, f).as(aliasName))\n } else if (f === 'id') {\n next = next.select(`${alias}.entity_id as id`)\n } else if (f === 'created_at' || f === 'updated_at' || f === 'deleted_at') {\n next = next.select(`${alias}.${f} as ${f}`)\n } else {\n const expr = sql<string | null>`(${sql.ref(alias + '.doc')} ->> ${f})`\n next = next.select(expr.as(f))\n }\n }\n // Ensure CF fields for sort / includeCustomFields are selected\n for (const key of cfKeys) {\n const aliasName = this.sanitize(`cf:${key}`)\n next = next.select(this.jsonbSqlAlias(alias, `cf:${key}`).as(aliasName))\n }\n return next\n }\n\n const applySort = (q: AnyBuilder): AnyBuilder => {\n let next = q\n for (const s of opts.sort || []) {\n if (s.field.startsWith('cf:')) {\n const key = s.field.slice(3)\n const aliasName = this.sanitize(`cf:${key}`)\n next = next.orderBy(aliasName, s.dir ?? SortDir.Asc)\n } else if (s.field === 'id') {\n next = next.orderBy(`${alias}.entity_id`, s.dir ?? SortDir.Asc)\n } else if (s.field === 'created_at' || s.field === 'updated_at' || s.field === 'deleted_at') {\n next = next.orderBy(`${alias}.${s.field}`, s.dir ?? SortDir.Asc)\n } else {\n const direction = sql.raw(String(s.dir ?? SortDir.Asc))\n next = next.orderBy(sql`(${sql.ref(alias + '.doc')} ->> ${s.field}) ${direction}`)\n }\n }\n return next\n }\n\n const page = opts.page?.page ?? 1\n const pageSize = opts.page?.pageSize ?? 20\n\n const root = db.selectFrom(`custom_entities_storage as ${alias}`)\n const countQuery = applyScope(root).select(sql<string>`count(distinct ${sql.ref(`${alias}.entity_id`)})`.as('count'))\n const countRow = await countQuery.executeTakeFirst()\n const total = this.parseCount(countRow)\n\n let dataQuery = applyScope(db.selectFrom(`custom_entities_storage as ${alias}`))\n dataQuery = applySelection(dataQuery)\n dataQuery = applySort(dataQuery)\n dataQuery = dataQuery.limit(pageSize).offset((page - 1) * pageSize)\n const items = await dataQuery.execute()\n return { items, page, pageSize, total }\n }\n\n private async tableExists(table: string): Promise<boolean> {\n const db = this.getDb() as any\n const exists = await db\n .selectFrom('information_schema.tables')\n .select(sql<number>`1`.as('one'))\n .where('table_name', '=', table)\n .executeTakeFirst()\n return !!exists\n }\n\n private async hasSearchTokens(\n entity: string,\n tenantId: string | null,\n orgScope?: { ids: string[]; includeNull: boolean } | null\n ): Promise<boolean> {\n try {\n const db = this.getDb() as any\n let query = db\n .selectFrom('search_tokens')\n .select(sql<number>`1`.as('one'))\n .where('entity_type', '=', entity)\n if (tenantId !== undefined) {\n query = query.where(sql<boolean>`tenant_id is not distinct from ${tenantId}`)\n }\n if (orgScope) {\n query = this.applyOrganizationScope(query, 'search_tokens.organization_id', orgScope)\n }\n const row = await query.limit(1).executeTakeFirst()\n return !!row\n } catch (err) {\n this.logSearchDebug('search:has-tokens-error', {\n entity, tenantId, organizationScope: orgScope,\n error: err instanceof Error ? err.message : String(err),\n })\n return false\n }\n }\n\n private async searchSourcesHaveTokens(\n sources: SearchTokenSource[],\n tenantId: string | null,\n orgScope?: { ids: string[]; includeNull: boolean } | null\n ): Promise<boolean> {\n for (const source of sources) {\n const ok = await this.hasSearchTokens(source.entity, tenantId, orgScope)\n this.logSearchDebug('search:source-has-tokens', {\n entity: source.entity, recordIdColumn: source.recordIdColumn,\n tenantId, organizationScope: orgScope, hasTokens: ok,\n })\n if (ok) return true\n }\n return false\n }\n\n private async resolveAvailableCustomFieldKeys(entityIds: string[], tenantId: string | null): Promise<string[]> {\n if (!entityIds.length) return []\n const cacheKey = this.customFieldKeysCacheKey(entityIds, tenantId)\n const now = Date.now()\n const cached = this.customFieldKeysCache.get(cacheKey)\n if (cached && cached.expiresAt > now) return cached.value.slice()\n\n const db = this.getDb() as any\n const rows = await db\n .selectFrom('custom_field_defs')\n .select('key')\n .where('entity_id', 'in', entityIds)\n .where('is_active', '=', true)\n .where((eb: any) => eb.or([\n eb('tenant_id', '=', tenantId),\n eb('tenant_id', 'is', null),\n ]))\n .execute() as Array<{ key: unknown }>\n const keys = new Set<string>()\n for (const row of rows) {\n const key = row.key\n if (typeof key === 'string' && key.trim().length) keys.add(key.trim())\n else if (key != null) keys.add(String(key))\n }\n const result = Array.from(keys)\n if (this.customFieldKeysTtlMs > 0) {\n this.customFieldKeysCache.set(cacheKey, { expiresAt: now + this.customFieldKeysTtlMs, value: result })\n }\n return result.slice()\n }\n\n private async entityHasActiveCustomFields(entityId: string, tenantId: string | null): Promise<boolean> {\n try {\n const keys = await this.resolveAvailableCustomFieldKeys([entityId], tenantId)\n return keys.length > 0\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('query:cf:check-error', {\n entity: entityId, tenantId: tenantId ?? null,\n error: err instanceof Error ? err.message : err,\n })\n }\n return true\n }\n }\n\n private customFieldKeysCacheKey(entityIds: string[], tenantId: string | null): string {\n const sorted = entityIds.slice().sort((a, b) => a.localeCompare(b)).join(',')\n return `${tenantId ?? '__none__'}|${sorted}`\n }\n\n private resolveVectorService(): VectorIndexService | null {\n if (!this.vectorServiceResolver) return null\n try {\n return this.vectorServiceResolver() ?? null\n } catch {\n return null\n }\n }\n\n private resolveEntityLabel(entity: string): string {\n return entity\n }\n\n private async indexAnyRows(entity: string): Promise<boolean> {\n const db = this.getDb() as any\n const coverage = await db\n .selectFrom('entity_index_coverage')\n .select(sql<number>`1`.as('one'))\n .where('entity_type', '=', entity)\n .where('indexed_count', '>', 0)\n .executeTakeFirst()\n if (coverage) return true\n const exists = await db\n .selectFrom('entity_indexes')\n .select('entity_id')\n .where('entity_type', '=', entity)\n .executeTakeFirst()\n return !!exists\n }\n\n private async getStoredCoverageSnapshot(\n entity: string,\n tenantId: string | null,\n organizationId: string | null,\n withDeleted: boolean\n ): Promise<{ baseCount: number; indexedCount: number } | null> {\n try {\n if (!this.isCoverageOptimizationEnabled()) {\n await refreshCoverageSnapshot(this.em, {\n entityType: entity, tenantId, organizationId, withDeleted,\n })\n }\n const db = this.getDb()\n const row = await readCoverageSnapshot(db as any, {\n entityType: entity, tenantId, organizationId, withDeleted,\n })\n if (!row) return null\n return { baseCount: row.baseCount, indexedCount: row.indexedCount }\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('coverage:snapshot:read-error', {\n entity, tenantId, organizationId, withDeleted,\n error: err instanceof Error ? err.message : err,\n })\n }\n return null\n }\n }\n\n private scheduleAutoReindex(\n entity: string,\n opts: QueryOptions,\n stats?: { baseCount: number; indexedCount: number },\n organizationIdOverride?: string | null\n ) {\n if (!this.isAutoReindexEnabled()) return\n const bus = this.resolveEventBus()\n if (!bus) return\n const payload = {\n entityType: entity,\n tenantId: opts.tenantId ?? null,\n organizationId: organizationIdOverride ?? opts.organizationId ?? null,\n force: false,\n }\n const context = stats\n ? { entity, tenantId: payload.tenantId, organizationId: payload.organizationId, baseCount: stats.baseCount, indexedCount: stats.indexedCount }\n : { entity, tenantId: payload.tenantId, organizationId: payload.organizationId }\n\n void Promise.resolve().then(async () => {\n try {\n await bus.emitEvent('query_index.reindex', payload, { persistent: true })\n if (this.isDebugVerbosity()) this.debug('query:auto-reindex:scheduled', context)\n } catch (err) {\n console.warn('[HybridQueryEngine] Failed to schedule auto reindex:', {\n ...context, error: err instanceof Error ? err.message : err,\n })\n }\n })\n }\n\n private scheduleCoverageRefresh(\n entity: string,\n tenantId: string | null | undefined,\n organizationId: string | null | undefined,\n withDeleted: boolean\n ): void {\n const bus = this.resolveEventBus()\n if (!bus) return\n const key = [entity, tenantId ?? '__tenant__', organizationId ?? '__org__', withDeleted ? '1' : '0'].join('|')\n if (this.pendingCoverageRefreshKeys.has(key)) return\n this.pendingCoverageRefreshKeys.add(key)\n void Promise.resolve()\n .then(async () => {\n try {\n await bus.emitEvent('query_index.coverage.refresh', {\n entityType: entity,\n tenantId: tenantId ?? null, organizationId: organizationId ?? null,\n withDeleted, delayMs: 0,\n })\n if (this.isDebugVerbosity()) {\n this.debug('coverage:refresh:scheduled', {\n entity, tenantId: tenantId ?? null, organizationId: organizationId ?? null, withDeleted,\n })\n }\n } catch (err) {\n if (this.isDebugVerbosity()) {\n this.debug('coverage:refresh:failed', {\n entity, tenantId: tenantId ?? null, organizationId: organizationId ?? null, withDeleted,\n error: err instanceof Error ? err.message : err,\n })\n }\n }\n })\n .finally(() => { this.pendingCoverageRefreshKeys.delete(key) })\n }\n\n private resolveEventBus(): Pick<EventBus, 'emitEvent'> | null {\n if (!this.eventBusResolver) return null\n try {\n const bus = this.eventBusResolver()\n return bus ?? null\n } catch {\n return null\n }\n }\n\n private isAutoReindexEnabled(): boolean {\n if (this.autoReindexEnabled != null) return this.autoReindexEnabled\n const raw = (process.env.SCHEDULE_AUTO_REINDEX ?? process.env.QUERY_INDEX_AUTO_REINDEX ?? '').trim().toLowerCase()\n if (!raw) { this.autoReindexEnabled = true; return true }\n const parsed = parseBooleanToken(raw)\n this.autoReindexEnabled = parsed === null ? true : parsed\n return this.autoReindexEnabled\n }\n\n private isCoverageOptimizationEnabled(): boolean {\n if (this.coverageOptimizationEnabled != null) return this.coverageOptimizationEnabled\n const raw = (process.env.OPTIMIZE_INDEX_COVERAGE_STATS ?? '').trim().toLowerCase()\n if (!raw) { this.coverageOptimizationEnabled = false; return false }\n this.coverageOptimizationEnabled = parseBooleanToken(raw) === true\n return this.coverageOptimizationEnabled\n }\n\n private async columnExists(table: string, column: string): Promise<boolean> {\n const key = `${table}.${column}`\n if (this.columnCache.has(key)) {\n const cached = this.columnCache.get(key)\n if (cached === true) return true\n this.columnCache.delete(key)\n }\n const db = this.getDb() as any\n const exists = await db\n .selectFrom('information_schema.columns')\n .select(sql<number>`1`.as('one'))\n .where('table_name', '=', table)\n .where('column_name', '=', column)\n .executeTakeFirst()\n const present = !!exists\n if (present) this.columnCache.set(key, true)\n else this.columnCache.delete(key)\n return present\n }\n\n private async getBaseColumnsForEntity(entity: string): Promise<Map<string, string>> {\n const db = this.getDb() as any\n const table = resolveEntityTableName(this.em, entity)\n const rows = await db\n .selectFrom('information_schema.columns')\n .select(['column_name', 'data_type'])\n .where('table_name', '=', table)\n .execute() as Array<{ column_name: string; data_type: string }>\n const map = new Map<string, string>()\n for (const r of rows) map.set(r.column_name, r.data_type)\n return map\n }\n\n private resolveOrganizationScope(opts: QueryOptions): { ids: string[]; includeNull: boolean } | null {\n if (opts.organizationIds !== undefined) {\n const raw = (opts.organizationIds ?? []).map((id) => (typeof id === 'string' ? id.trim() : id))\n const includeNull = raw.some((id) => id == null || id === '')\n const ids = raw.filter((id): id is string => typeof id === 'string' && id.length > 0)\n const unique = Array.from(new Set(ids))\n return { ids: unique, includeNull }\n }\n if (typeof opts.organizationId === 'string' && opts.organizationId.trim().length > 0) {\n return { ids: [opts.organizationId], includeNull: false }\n }\n return null\n }\n\n private resolveCoverageSnapshotScope(\n opts: QueryOptions\n ): { tenantId: string | null; organizationId: string | null } | null {\n const tenantId = opts.tenantId ?? null\n const orgScope = this.resolveOrganizationScope(opts)\n if (!orgScope) return { tenantId, organizationId: null }\n if (orgScope.includeNull) {\n if (orgScope.ids.length === 0) return { tenantId, organizationId: null }\n return null\n }\n if (orgScope.ids.length === 1) return { tenantId, organizationId: orgScope.ids[0] }\n if (orgScope.ids.length === 0) return { tenantId, organizationId: null }\n return null\n }\n\n private applyOrganizationScope(\n q: AnyBuilder,\n column: string,\n scope: { ids: string[]; includeNull: boolean }\n ): AnyBuilder {\n if (scope.ids.length === 0 && !scope.includeNull) {\n return q.where(sql<boolean>`1 = 0`)\n }\n return q.where((eb: any) => {\n const parts: any[] = []\n if (scope.ids.length > 0) parts.push(eb(column, 'in', scope.ids))\n if (scope.includeNull) parts.push(eb(column, 'is', null))\n if (parts.length === 1) return parts[0]\n return eb.or(parts)\n })\n }\n\n private normalizeFilters(filters?: QueryOptions['filters']): NormalizedFilter[] {\n if (!filters) return []\n const normalizeField = (k: string) => k.startsWith('cf_') ? `cf:${k.slice(3)}` : k\n if (Array.isArray(filters)) {\n return (filters as Filter[]).map((filter) => ({\n field: normalizeField(String(filter.field)),\n op: filter.op, value: filter.value,\n }))\n }\n const out: NormalizedFilter[] = []\n const obj = filters as Record<string, unknown>\n const add = (field: string, op: FilterOp, value?: unknown) => out.push({ field, op, value })\n for (const [rawKey, rawVal] of Object.entries(obj)) {\n const field = normalizeField(rawKey)\n if (rawVal !== null && typeof rawVal === 'object' && !Array.isArray(rawVal)) {\n for (const [opKey, opVal] of Object.entries(rawVal as Record<string, unknown>)) {\n switch (opKey) {\n case '$eq': add(field, 'eq', opVal); break\n case '$ne': add(field, 'ne', opVal); break\n case '$gt': add(field, 'gt', opVal); break\n case '$gte': add(field, 'gte', opVal); break\n case '$lt': add(field, 'lt', opVal); break\n case '$lte': add(field, 'lte', opVal); break\n case '$in': add(field, 'in', opVal); break\n case '$nin': add(field, 'nin', opVal); break\n case '$like': add(field, 'like', opVal); break\n case '$ilike': add(field, 'ilike', opVal); break\n case '$exists': add(field, 'exists', opVal); break\n }\n }\n } else {\n add(field, 'eq', rawVal)\n }\n }\n return out\n }\n\n private sanitize(s: string): string {\n return s.replace(/[^a-zA-Z0-9_]/g, '_')\n }\n\n private toArray(value: unknown): readonly unknown[] {\n if (Array.isArray(value)) return value\n if (value === undefined) return []\n return [value]\n }\n\n private parseCount(row: unknown): number {\n if (row && typeof row === 'object' && 'count' in row) {\n const value = (row as { count: unknown }).count\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n return Number.isNaN(parsed) ? 0 : parsed\n }\n if (typeof value === 'bigint') return Number(value)\n }\n return 0\n }\n\n private logSearchDebug(event: string, payload: Record<string, unknown>) {\n if (!this.isDebugVerbosity()) return\n try {\n console.info('[query-index:search]', event, JSON.stringify(payload))\n } catch {\n console.info('[query-index:search]', event, payload)\n }\n }\n\n private applyColumnFilter(\n q: AnyBuilder,\n column: string | RawBuilder<unknown>,\n filter: NormalizedFilter,\n search?: SearchRuntime & { entity: string; field: string; recordIdColumn?: string },\n ): AnyBuilder {\n if (\n (filter.op === 'like' || filter.op === 'ilike') &&\n search?.enabled &&\n typeof filter.value === 'string'\n ) {\n const tokens = tokenizeText(String(filter.value), search.config)\n const hashes = tokens.hashes\n if (hashes.length) {\n const sources: SearchTokenSource[] = (search.searchSources && search.searchSources.length\n ? search.searchSources\n : [{ entity: search.entity, recordIdColumn: search.recordIdColumn ?? '' }]\n ).filter((src) => src.recordIdColumn && src.entity)\n if (sources.length) {\n const engine = this\n q = q.where((eb: any) => eb.or(\n sources.map((src) =>\n eb.exists(engine.buildSearchTokensSub(eb, {\n entity: src.entity, field: search.field, hashes,\n recordIdColumn: src.recordIdColumn,\n tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope ?? null,\n })))\n ))\n this.logSearchDebug('search:filter', {\n entity: search.entity, field: search.field, tokens: tokens.tokens, hashes,\n applied: true, tenantId: search.tenantId ?? null,\n organizationScope: search.organizationScope,\n sources: sources.map((src) => ({ entity: src.entity, recordIdColumn: src.recordIdColumn })),\n })\n return q\n }\n } else {\n this.logSearchDebug('search:skip-empty-hashes', {\n entity: search.entity, field: search.field, value: filter.value,\n })\n }\n return q\n }\n const col: any = column\n switch (filter.op) {\n case 'eq': return q.where(col, '=', filter.value as any)\n case 'ne': return q.where(col, '!=', filter.value as any)\n case 'gt':\n case 'gte':\n case 'lt':\n case 'lte': {\n const operator = filter.op === 'gt' ? '>' : filter.op === 'gte' ? '>=' : filter.op === 'lt' ? '<' : '<='\n return q.where(col, operator, filter.value as any)\n }\n case 'in':\n return q.where(col, 'in', this.toArray(filter.value))\n case 'nin':\n return q.where(col, 'not in', this.toArray(filter.value))\n case 'like':\n return q.where(col, 'like', filter.value as any)\n case 'ilike':\n return q.where(col, 'ilike', filter.value as any)\n case 'exists':\n return filter.value ? q.where(col, 'is not', null) : q.where(col, 'is', null)\n default:\n return q\n }\n }\n\n private resolveCustomEntityColumn(alias: string, field: string): string | null {\n if (field === 'id') return `${alias}.entity_id`\n if (field === 'organization_id' || field === 'organizationId') return `${alias}.organization_id`\n if (field === 'tenant_id' || field === 'tenantId') return `${alias}.tenant_id`\n if (field === 'created_at' || field === 'updated_at' || field === 'deleted_at') return `${alias}.${field}`\n return null\n }\n\n private isDebugVerbosity(): boolean {\n if (this.debugVerbosity != null) return this.debugVerbosity\n this.debugVerbosity = resolveDebugVerbosity()\n return this.debugVerbosity\n }\n\n private isSqlDebugEnabled(): boolean {\n if (this.sqlDebugEnabled != null) return this.sqlDebugEnabled\n this.sqlDebugEnabled = resolveBooleanEnv(['QUERY_ENGINE_DEBUG_SQL'], false)\n return this.sqlDebugEnabled\n }\n\n private isForcePartialIndexEnabled(): boolean {\n if (this.forcePartialIndexEnabled != null) return this.forcePartialIndexEnabled\n this.forcePartialIndexEnabled = resolveBooleanEnv(['FORCE_QUERY_INDEX_ON_PARTIAL_INDEXES'], false)\n return this.forcePartialIndexEnabled\n }\n\n private async resolveCoverageGap(\n entity: string,\n opts: QueryOptions,\n coverageScope?: { tenantId: string | null; organizationId: string | null } | null,\n _sourceTable?: string\n ): Promise<{ stats?: { baseCount: number; indexedCount: number }; scope: 'scoped' | 'global' } | null> {\n const scope = coverageScope ?? this.resolveCoverageSnapshotScope(opts)\n if (!scope) return null\n const tenantId = scope.tenantId\n const organizationId = scope.organizationId\n const withDeleted = !!opts.withDeleted\n\n const snapshot = await this.getStoredCoverageSnapshot(entity, tenantId, organizationId, withDeleted)\n if (!snapshot) {\n this.scheduleCoverageRefresh(entity, tenantId, organizationId, withDeleted)\n return { stats: undefined, scope: 'scoped' }\n }\n\n const baseCount = snapshot.baseCount\n const indexCount = snapshot.indexedCount\n const hasGap = baseCount > 0 && indexCount < baseCount\n if (hasGap || indexCount > baseCount) return { stats: snapshot, scope: 'scoped' }\n return null\n }\n\n // Backward-compatible hook for tests that mock coverage stats\n private async indexCoverageStats(\n entity: string,\n opts: QueryOptions,\n coverageScope?: { tenantId: string | null; organizationId: string | null } | null,\n ): Promise<{ baseCount: number; indexedCount: number } | null> {\n const gap = await this.resolveCoverageGap(entity, opts, coverageScope)\n return gap?.stats ?? null\n }\n\n private async captureSqlTiming<TResult>(\n label: string,\n entity: EntityId,\n execute: () => Promise<TResult> | TResult,\n extra?: Record<string, unknown>,\n profiler?: Profiler\n ): Promise<TResult> {\n const shouldDebug = this.isSqlDebugEnabled() && this.isDebugVerbosity()\n const shouldProfile = profiler?.enabled === true\n if (!shouldDebug && !shouldProfile) return Promise.resolve(execute())\n const startedAt = process.hrtime.bigint()\n try {\n return await Promise.resolve(execute())\n } finally {\n const elapsedMs = Number(process.hrtime.bigint() - startedAt) / 1_000_000\n const context: Record<string, unknown> = { entity, durationMs: Math.round(elapsedMs * 1000) / 1000 }\n if (extra) Object.assign(context, extra)\n if (shouldProfile) profiler!.record(label, context.durationMs as number, extra)\n if (shouldDebug) this.debug(`${label}:timing`, context)\n }\n }\n\n private debug(message: string, context?: Record<string, unknown>): void {\n if (!this.isDebugVerbosity()) return\n if (!this.isSqlDebugEnabled()) return\n if (context) console.debug('[HybridQueryEngine]', message, context)\n else console.debug('[HybridQueryEngine]', message)\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": ["result"]
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.6.3-develop.3753.1.29e9a20dde",
3
+ "version": "0.6.3-develop.3755.1.84e4410d84",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -242,16 +242,16 @@
242
242
  "zod": "^4.4.3"
243
243
  },
244
244
  "peerDependencies": {
245
- "@open-mercato/ai-assistant": "0.6.3-develop.3753.1.29e9a20dde",
246
- "@open-mercato/shared": "0.6.3-develop.3753.1.29e9a20dde",
247
- "@open-mercato/ui": "0.6.3-develop.3753.1.29e9a20dde",
245
+ "@open-mercato/ai-assistant": "0.6.3-develop.3755.1.84e4410d84",
246
+ "@open-mercato/shared": "0.6.3-develop.3755.1.84e4410d84",
247
+ "@open-mercato/ui": "0.6.3-develop.3755.1.84e4410d84",
248
248
  "react": "^19.0.0",
249
249
  "react-dom": "^19.0.0"
250
250
  },
251
251
  "devDependencies": {
252
- "@open-mercato/ai-assistant": "0.6.3-develop.3753.1.29e9a20dde",
253
- "@open-mercato/shared": "0.6.3-develop.3753.1.29e9a20dde",
254
- "@open-mercato/ui": "0.6.3-develop.3753.1.29e9a20dde",
252
+ "@open-mercato/ai-assistant": "0.6.3-develop.3755.1.84e4410d84",
253
+ "@open-mercato/shared": "0.6.3-develop.3755.1.84e4410d84",
254
+ "@open-mercato/ui": "0.6.3-develop.3755.1.84e4410d84",
255
255
  "@testing-library/dom": "^10.4.1",
256
256
  "@testing-library/jest-dom": "^6.9.1",
257
257
  "@testing-library/react": "^16.3.1",
@@ -865,13 +865,16 @@ export class HybridQueryEngine implements QueryEngine {
865
865
  const decrypt = encSvc.decryptEntityPayload.bind(encSvc) as (
866
866
  entityId: EntityId, payload: Record<string, unknown>, tenantId: string | null, organizationId: string | null,
867
867
  ) => Promise<Record<string, unknown>>
868
+ const fallbackOrgId =
869
+ opts.organizationId
870
+ ?? (Array.isArray(opts.organizationIds) && opts.organizationIds.length === 1 ? opts.organizationIds[0] : null)
868
871
  items = await Promise.all(
869
872
  items.map(async (item) => {
870
873
  try {
871
874
  const decrypted = await decrypt(
872
875
  entity, item,
873
876
  item?.tenant_id ?? item?.tenantId ?? opts.tenantId ?? null,
874
- item?.organization_id ?? item?.organizationId ?? null,
877
+ item?.organization_id ?? item?.organizationId ?? fallbackOrgId ?? null,
875
878
  )
876
879
  return { ...item, ...decrypted }
877
880
  } catch (err) {