Skip to content

fix(search): populate FTS for NSID-keyed collections#59

Merged
tompscanlan merged 2 commits into
flo-bit:mainfrom
tompscanlan:fix/fts-nsid-keyed-collections
Jun 15, 2026
Merged

fix(search): populate FTS for NSID-keyed collections#59
tompscanlan merged 2 commits into
flo-bit:mainfrom
tompscanlan:fix/fts-nsid-keyed-collections

Conversation

@tompscanlan

Copy link
Copy Markdown
Collaborator

Problem

When a collection is keyed directly by its NSID (no short alias / collection field), shortNameForNsid(config, nsid) returns undefined. Two of the three record paths used shortNameForNsid directly:

  • buildFtsStatements skipped FTS sync, so full-text search stayed empty for NSID-keyed collections.
  • lookupExistingRecords skipped them, so replay/update detection (and FTS reconciliation) was broken.

Only the records-insert path carried the NSID fallback, so rows landed in the records table but never in FTS. The repo's own search.test.ts uses NSID-keyed configs and was failing 7/12 on a clean checkout.

Fix

Add a small resolveCollectionKey(config, nsid) helper in contrail-base that returns the storage key (short alias, or the NSID itself when keyed directly), or null when unknown. Use it at all three record paths so they resolve collections consistently. This also de-duplicates the fallback expression the insert path was inlining.

Tests

  • New resolve-collection-key.test.ts unit-tests the helper (alias-keyed, NSID-keyed, unknown).
  • Existing search.test.ts (12 tests) now passes; it was the failing regression test.
  • Full suite: 406 passed, 0 failed.

Changeset included (patch: contrail-base, contrail-appview).

shortNameForNsid returns undefined when a collection is keyed directly by
its NSID, so the FTS-sync and existing-record lookup paths skipped those
collections, leaving full-text search empty and replay/update detection
broken. Add a resolveCollectionKey helper that returns the storage key
(alias or NSID) and use it at all three record paths.
A collection keyed directly by its NSID (no short alias, omitted
`collection` field) was only handled at the records/FTS layer via
`resolveCollectionKey`. The real ingestion entry points still skipped it:
`getCollectionNsids`/`getDiscoverableNsids`/`getDependentNsids` produced
undefined NSIDs (Jetstream never subscribed, backfill never ran),
`shortNameForNsid` returned undefined (notify rejected the URI as
"collection not tracked"), and `validateConfig` rejected the config.

Make `CollectionConfig.collection` optional, normalize an omitted value to
the map key in `resolveConfig`, accept NSID-keyed entries in
`validateConfig`, and resolve the NSID as `collection ?? key` at every
collection-list and lookup site so behavior is correct on both raw and
resolved configs.

Add config-layer regression tests and an end-to-end notify->ingest test
for an NSID-keyed collection.
@tompscanlan tompscanlan force-pushed the fix/fts-nsid-keyed-collections branch from 584cb94 to deac05c Compare June 15, 2026 23:03
@tompscanlan tompscanlan merged commit 74a2d3d into flo-bit:main Jun 15, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant