Files
james.maesandClaude Opus 5.5 27a170f208 feat: data-driven Quick Search config, valid create screen, global pause, cancel
The searchable tables and fields are now standard QQQ records:
quick_search_index (the registry; new source and ownerEdited columns) and
the new quick_search_index_field (weight, role, analyzer, snippet and
label flags). Indexing, search, the record-search provider and the
diagnostics read the effective config from them through
QuickSearchConfigStore (30 s cache, dropped by the tables' customizers),
so changes need no redeploy.

Code (@QuickSearchable, searchableTables) only seeds the records:
QuickSearchConfigPrimer adds missing tables and fields at startup and
queues their builds, updates rows nobody edited, never overwrites rows an
admin edited (ownerEdited) and never re-adds what an admin removed
(quick_search_config_tombstone). Basepull builds queued tables
(PENDING_BUILD, BUILDING) and recreates a missing index; an empty index
is rebuilt. Without the config tables the code config is used as before.

The generic Create and Delete of quick_search_index are replaced by
streamed-ETL processes with review steps: Add Search Index (eligible
readable tables only, estimated record count, default fields, sensitive
and hidden fields never indexed), Apply Search Index Changes (previews
field changes, then rebuilds), Disable / Remove Search Index (delete or
keep documents), Cancel Index Run (cooperative flag between batches; runs
end CANCELLED with counts) and Pause / Resume Indexing (global pause in
quick_search_settings; search keeps serving; changes are deferred and
replayed). Field roles shape documents (TITLE label, SUBTITLE, DISPLAY
values, KEYWORD and EXACT outside the snippet) and WORD, ENGLISH and EXACT
analyzers get their own document objects and mapping templates.

Config tables are audited at field level and permission-gated; the
processes need quick_search_admin. Upgrade notes and DDL:
docs/MIGRATION-1.1.md, "Data-driven configuration".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 15:30:47 -05:00

6.3 KiB

CLAUDE.md

This file provides guidance to Claude Code when working with code in this repository.

Project Overview

QBit Quick Search - A QQQ QBit providing OpenSearch-backed full-text search across QQQ applications.

Build Commands

./mvnw compile          # Compile (always use the wrapper: Maven 3.10 cannot read the parent POM)
./mvnw test             # Run unit tests
./mvnw test -Dtest=ClassName  # Run single test class
./mvnw package          # Build JAR
CI=true ./mvnw verify   # Full verify: integration tests (Docker) and the JaCoCo gate
./mvnw verify -Dopensearch.test.image=opensearchproject/opensearch:3.9.0   # other server line
./mvnw verify -Dqqq.snapshot.version=4.1.0-RC.1   # other qqq 4.1 build (profile is active by default)

Integration tests (require Docker) run via mvn verify using maven-failsafe-plugin. Unit tests exclude *IntegrationTest.java and *IT.java. Integration tests use @ExtendWith(RequiresDockerCondition.class): skipped without Docker locally, failed when CI=true.

Architecture

Entry point: QuickSearchQBitProducer implements QBitMetaDataProducer<QuickSearchQBitConfig>. QQQ's default produce() registers QBitMetaData (com.kingsrook.qbits:quick-search), validates the config, runs the component producers in metadata/ (tables, processes, PVS, app), then postProduceActions discovers searchable tables, builds the QuickSearchRuntime, registers QuickSearchRecordChangeListener and QuickSearchRuntimeService, and in FAIL_FAST mode prepares the index. produce(QInstance) adds everything to the instance (0.x call style still works).

Key Classes:

  • QuickSearchQBitConfig - Host-facing config: connection (opensearchUrl), authMode, tls, timeouts, startup mode, scheduling, permission rules, search bounds, tables. List-based, null-safe validate.
  • QuickSearchRuntime - Instance-scoped live state (discovered tables, lazy client, publisher, enabled cache), held on the config and resolved via QuickSearchRuntime.get() from QContext. QuickSearchQBitContext is a deprecated static facade over it.
  • opensearch/QuickSearchOpenSearchClient - All OpenSearch operations; the configured index name is an alias over {alias}-v2-{epoch} physical indexes (mapping v2, _meta.quickSearchMappingVersion); versioned bulk writes (external_gte); alias swap; wraps every error in QException.
  • opensearch/OpenSearchTransportFactory - Builds the transport for NONE/BASIC (Apache HttpClient 5 with TLS, timeouts, customizer SPI) or AWS_SIGV4 (AwsSdk2Transport); resolves ${env.X} secrets.
  • listeners/QuickSearchRecordChangeListener - Real-time path: builds events in the write's transaction, publishes after commit, records failures in quick_search_failed_event.
  • processes/AbstractIndexingStep - Keyset paging by primary key with display values, run records, drift detection, run purge. BasepullIndexStep (replays failed events, start-anchored watermark with overlap), ReconcileIndexStep (in place, orphan sweep), FullReindexStep (all tables: new physical index plus alias swap; one table: reconcile algorithm).
  • actions/QuickSearchAction - Permission-aware search (table READ filter, QueryAction post-filter), bounds, tableNames, limitPerTable, tableLabel.
  • actions/QuickSearchRecordSearchProvider - QQQ core RecordSearchProviderInterface (POST /qqq/v1/search): claims indexed, enabled tables; one _msearch per call returning ordered record ids per table; bounded by recordSearchTimeoutMillis; failures make core fall back and start a 30 s backoff (QuickSearchRuntime.markRecordSearchFailed). Registered, with default table searchFields, when serveCoreRecordSearch is true.
  • metadata/* - Component producers and the table/process helpers.

Tables Produced: quick_search_index, quick_search_index_field, quick_search_settings, quick_search_config_tombstone, quick_search_index_run, quick_search_failed_event, quick_search_diagnostic_event, quick_search_validation_run (plus PVSs).

Data-driven config (config/): the records are the source of truth. QuickSearchConfigStore builds the effective QuickSearchableTableConfigs from quick_search_index + quick_search_index_field (30 s cache, dropped by the tables' customizers); QuickSearchRuntime.getDiscoveredTables()/getTableConfig() return them, getCodeTables() the code defaults. QuickSearchConfigPrimer seeds records from code (never over ownerEdited rows or tombstones). QBit writes to config tables go through QuickSearchConfigWrites.asSystem so customizers do not treat them as owner edits. Admin processes live in processes/config/ (streamed ETL with review steps).

Annotation Discovery: @QuickSearchable(tableName = "...") on entity classes; @QuickSearchField(weight, includeLabel) on fields; hidden fields are excluded.

Code Style

  • 3-space indentation, opening braces on next line
  • Javadoc flower box comments (80-char width with ** borders)
  • Fluent-style setters (withX())
  • Use wrapper types (Integer, Boolean) not primitives

Dependencies

  • Java 21
  • Parent com.kingsrook:qbit-build-parent:2.0.0 (qqq 4.0.0). 1.0 needs qqq 4.1, so the qqq-snapshot profile is active by default and imports qqq-bom-pom ahead of the parent's BOM; remove that activation when the parent moves to 4.1 (ADR-0007). 1.1 imports 4.1.0-RC.4: the record-search provider SPI arrived in RC.2, the developer panel contract (DeveloperPanelProviderInterface) in RC.4
  • OpenSearch Java Client 3.10.0; optional AWS SDK v2 apache-client and sts for AWS_SIGV4
  • Apache HttpClient5 and jackson-datatype-jsr310, versions managed by the qqq BOM (keep them unpinned so they match its httpcore5 and jackson)
  • JUnit 5 + AssertJ + Mockito for testing
  • Testcontainers 1.21.4 for integration tests (requires Docker)

Knowledge base

Second-brain vault notes covering this repo and the QQQ platform it plugs into:

  • Platform hub: $SECOND_BRAIN_VAULT/knowledge/qqq/qqq-hub.md (start here; read knowledge/qqq/architecture/metadata-model.md for QBit mechanics)
  • This repo's dossier: $SECOND_BRAIN_VAULT/knowledge/qqq/repos/qbit-quick-search.md (reviewed at develop @ 8d9ec2711fde, 2026-07-04)
  • Production-readiness audit + P0-P3 roadmap: $SECOND_BRAIN_VAULT/projects/qbit-quick-search.md

Note: the dossier was reviewed before the qqq 4.0 re-pin; trust this file for build and dependency facts.