---
id: CAP-PFM-QRY-017
title: Maintain the fields and freshness of Quick Search
feature: FEAT-PFM-QRY-06
product_area: platform
module: queries
revision: 1
status: draft
product_intent: proposed
implementation_evidence: observed
supersedes: []
source_sha:
  services-platform: ad3f6a6582843008ed0f5a17b131878d15829af1
  react-console: baf6dae382d6f41dce976c7f848667ccc37e076f
intent_sources:
  - 'services-platform:docs/quick-search.md#2. The shared index and the document (D-29, Andrew 2026-10-19)'
purpose: >-
  Let administrators control searchable fields while Rhythm maintains and repairs the derived search
  documents.
outcomes:
  - Customers choose the fields used for search.
  - Source changes trigger document maintenance.
  - Repair and health state make index problems actionable.
concepts:
  - CON-PFM-QRY-005
actors:
  - ACT-PFM-007
  - ACT-PFM-012
  - ACT-PFM-016
surfaces:
  - api
  - job
preconditions: []
postconditions: []
permissions:
  - key: platform.quick-search-settings.read
    where_checked: api
    scope: tenant
  - key: platform.quick-search-settings.update
    where_checked: api
    scope: tenant
  - key: platform.quick-search-settings.rebuild
    where_checked: api
    scope: tenant
  - key: <application>.<dataset>.query (the owner's key)
    where_checked: service
    scope: tenant
rules:
  - id: BR-CAP-PFM-QRY-017-01
    proved_by: [ATS-PFM-QRY-017-01, TST-PFM-QRY-418]
    statement: >-
      Settings read, update and rebuild use separate permissions plus dataset query access, with inaccessible
      record types omitted from the settings list.
    kind: permission
    enforced_at:
      - api
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/e2e/quick-search-configurations.e2e.spec.js#refuses a
      rebuild to a caller who may change the field list, which is a different power
    origin: none
  - id: BR-CAP-PFM-QRY-017-02
    proved_by: [ATS-PFM-QRY-017-02, TST-PFM-QRY-418]
    statement: >-
      Reading never-configured settings returns default fields, version zero and unprovisioned state without
      writing.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/e2e/quick-search-configurations.e2e.spec.js#wrote nothing:
      reading what a tenant would get does not provision it
    origin: none
  - id: BR-CAP-PFM-QRY-017-03
    proved_by: [ATS-PFM-QRY-017-03, TST-PFM-QRY-418]
    statement: >-
      Search field configuration accepts one to thirty distinct eligible dataset fields in three tiers,
      excludes hidden or unsupported content types, and rejects all detected problems together without
      writing.
    kind: validation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/e2e/quick-search-configurations.e2e.spec.js#reports every
      problem of a list in one refusal, so one round trip fixes them all
    origin: none
  - id: BR-CAP-PFM-QRY-017-04
    proved_by: [ATS-PFM-QRY-016-13, ATS-PFM-QRY-017-04, ATS-PFM-QRY-017-13, TST-PFM-QRY-418]
    statement: >-
      Configuration updates use the read version, leave unchanged lists and versions alone, and atomically
      record a changed target with the rebuild it requires.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/e2e/quick-search-configurations.e2e.spec.js#committed the
      target beside it, so the configuration and the rebuild it owes are one fact
    origin: none
  - id: BR-CAP-PFM-QRY-017-05
    proved_by: [ATS-PFM-QRY-017-05, TST-PFM-QRY-423, TST-PFM-QRY-445]
    statement: >-
      Rebuilding fills a new generation while the existing one serves searches, publishes after validation,
      and coalesces concurrent full rebuild requests for the same record type.
    kind: lifecycle
    enforced_at:
      - service
      - database
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/integration/db/quick-search-rebuild-jobs.table.integration.spec.js#refuses
      a second open full rebuild of the same record type
    origin: none
  - id: BR-CAP-PFM-QRY-017-06
    proved_by: [ATS-PFM-QRY-017-06, TST-PFM-QRY-433]
    statement: >-
      Change handling claims record versions before projection, removes documents for missing source records
      and avoids writing late updates after deletion.
    kind: invariant
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/integration/services/indexing/handle-change-events.integration.spec.js#removes
      the document of a record the projection no longer finds, leaving no tombstone in the provider
    origin: 'services-platform:docs/quick-search.md#2. The shared index and the document (D-29, Andrew 2026-10-19)'
  - id: BR-CAP-PFM-QRY-017-07
    proved_by: [ATS-PFM-QRY-017-07, TST-PFM-QRY-433]
    statement: >-
      Organization renames refresh current affiliates, address changes refresh linked contacts, and fan-out
      beyond two hundred contacts becomes rebuild work.
    kind: calculation
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/integration/services/indexing/handle-change-events.integration.spec.js#re-indexes
      only the contacts with a current affiliation to that organization, not one whose affiliation ended
    origin: none
  - id: BR-CAP-PFM-QRY-017-08
    proved_by: [ATS-PFM-QRY-017-08, TST-PFM-QRY-433]
    statement: >-
      A workspace’s provider failure affects only its events, while events for unindexed, deleting or missing
      workspaces settle without provider writes.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/integration/services/indexing/handle-change-events.integration.spec.js#writes
      the other tenant’s document, so one tenant’s provider failure stops nothing else
    origin: none
  - id: BR-CAP-PFM-QRY-017-09
    proved_by: [ATS-PFM-QRY-017-09, TST-PFM-QRY-418]
    statement: >-
      Retired fields degrade the index and trigger rebuilding without the field while remaining visible as
      unavailable in configuration, and saves retaining them are rejected.
    kind: policy
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/e2e/quick-search-configurations.e2e.spec.js#refuses a field
      list that keeps the archived field, by the rule any ineligible field is refused by
    origin: none
  - id: BR-CAP-PFM-QRY-017-10
    proved_by: [ATS-PFM-QRY-017-10, TST-PFM-QRY-435, TST-PFM-QRY-438]
    statement: >-
      Repair resubmits owed rebuilds every fifteen minutes with hourly automatic backoff per type, reconciles
      types nightly in assigned hours, and retains deletion counters for at least fourteen days.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/integration/services/maintenance/resubmit-targets.integration.spec.js#submits
      nothing on a second pass in the same hour
    origin: none
  - id: BR-CAP-PFM-QRY-017-11
    proved_by: [ATS-PFM-QRY-017-11, ATS-PFM-QRY-017-14, ATS-PFM-QRY-017-15, ATS-PFM-QRY-018-16, ATS-PFM-QRY-019-12, TST-PFM-QRY-439]
    statement: >-
      Provisioning creates workspace index resources and purge removes them, waits for active rebuilds, and
      suppresses writes during workspace deletion.
    kind: lifecycle
    enforced_at:
      - service
    must_prove: true
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/integration/services/maintenance/tenant-participant.integration.spec.js#purges
      the tenant once the rebuild has settled, the job’s own three tables included
    origin: none
  - id: BR-CAP-PFM-QRY-017-12
    proved_by: [ATS-PFM-QRY-017-16, TST-PFM-QRY-438]
    statement: >-
      Provider-setting release changes advance the expected index settings and trigger automatic rebuilds
      through the repair pass.
    kind: policy
    enforced_at:
      - service
    must_prove: false
    provenance: documented
    source: 'services-platform:docs/quick-search.md#3.4 Repair schedules (plan §9.7, §10.4 and §10.6)'
    origin: none
scenarios:
  - id: SC-CAP-PFM-QRY-017-01
    given: An organization has current and former affiliates.
    when: Its rename event is processed.
    then: Current affiliates’ documents reflect the new name without updating former affiliates.
    provenance: test
    source: >-
      services-platform:modules/quick-search/tests/integration/services/indexing/handle-change-events.integration.spec.js#re-indexes
      the contacts of the organization, so each hit shows the name the organization has now
edge_cases: []
constraints: []
depends_on:
  - CAP-PFM-QRY-002
related:
  - CAP-PFM-QRY-016
journeys:
  - JNY-PFM-QRY-005
open_questions: []
operations:
  - listQuickSearchConfigurations
  - getQuickSearchConfiguration
  - listQuickSearchFields
  - replaceQuickSearchConfiguration
  - rebuildQuickSearchIndex
tables:
  - quick-search-configurations.table.ts
  - quick-search-index-states.table.ts
  - quick-search-documents.table.ts
  - quick-search-rebuild-jobs.table.ts
  - quick-search-rebuild-job-steps.table.ts
  - quick-search-rebuild-job-events.table.ts
evidence:
  - 'Pinned reference: services-platform:docs/quick-search.md'
  - 'Pinned reference: services-platform:modules/quick-search/tests/e2e/quick-search-configurations.e2e.spec.js'
  - >-
    Pinned reference:
    services-platform:modules/quick-search/tests/integration/db/quick-search-rebuild-jobs.table.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/quick-search/tests/integration/services/indexing/handle-change-events.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/quick-search/tests/integration/services/maintenance/resubmit-targets.integration.spec.js
  - >-
    Pinned reference:
    services-platform:modules/quick-search/tests/integration/services/maintenance/tenant-participant.integration.spec.js
controls: [TC-AVL-005, TC-AZ-001, TC-AZ-002, TC-AZ-003, TC-AZ-004, TC-CRY-001, TC-CRY-002, TC-CRY-003, TC-CRY-004, TC-DAT-001, TC-DAT-002, TC-DAT-003, TC-DAT-004, TC-MON-001, TC-PI-001, TC-PI-003, TC-PI-005, TC-PRV-001, TC-PRV-002, TC-TEN-001, TC-TEN-002, TC-TEN-003, TC-VEN-001, TC-VEN-002, TC-VEN-003]
exercised_by: [FAS-PFM-QRY-06-01, FAS-PFM-QRY-06-02, FAS-PFM-QRY-06-03, FAS-PFM-QRY-06-04, FAS-PFM-QRY-06-05, FAS-PFM-QRY-07-03, FAS-PFM-QRY-08-02]
suites: [TST-PFM-QRY-418, TST-PFM-QRY-423, TST-PFM-QRY-433, TST-PFM-QRY-435, TST-PFM-QRY-438, TST-PFM-QRY-439, TST-PFM-QRY-445]
---

# Maintain the fields and freshness of Quick Search

## Purpose

Let administrators control searchable fields while Rhythm maintains and repairs the derived search documents.

## How It Works

An administrator reads the available search fields and current configuration. They submit a revised field list through the API. Platform validates all fields and records the new target together with its owed rebuild. The old generation continues serving while the new one is prepared. Publication switches to the validated generation. Source change events refresh individual documents and related contacts. Repair passes revisit owed or inconsistent work. Retired metadata remains visible as a configuration problem until it is corrected. Workspace deletion waits for outstanding rebuild activity before purge completes.

## Relationships

Index administration supports typed lookup and reacts to changes declared by the applications that own records.
