Commit Graph
12 Commits
Author SHA1 Message Date
james.maesandClaude Opus 5.5 e9ec814762 Merge origin/develop into feature/GH-35-search-admin-tooling
Keeps develop's scheduling section and applies its cron rules (cron-capable
scheduler, valid Quartz expression, time zone ID) to validationCronExpression
through one shared check.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 06:04:44 -05:00
james.maesandClaude Opus 5.5 b421b4002a feat(#35): search admin tooling (playground, validation, record tools, analyzer, failure diagnostics)
Adds diagnostic tools so every QQQ app using the QBit can validate its
search and debug it from the admin UI. All are table or record actions
(processes with a tableName, never added to the app nav), gated by
permissions, rate-limited per user and tool, recorded as diagnostic events,
and read-only except Reindex in Search.

- Search Playground (Quick Search Index): runs a term as the current user
  the way the global search does; per-table path and reason (OpenSearch
  provider, core database search, not searched), the provider's request
  timed, the global search results, the production query's scores,
  highlights and matched clauses, readable / shown flags, query DSL and raw
  response (unreadable hits redacted), term tokens, explain for a hit.
  The form loops back so a user can search again.
- Validate Search Index (Quick Search Index; schedulable with
  validationCronExpression): cluster and index health, alias, leftover
  physical indexes, live mapping and analysis settings, per-table counts,
  sampled missing / stale documents and orphaned documents, index row status
  and failed events. Reports kept in the new quickSearchValidationRun table.
- Test Search Analyzer: _analyze with the index's analyzers, and whether a
  term's tokens are among a text's indexed tokens.
- Inspect Search Document and Reindex in Search on every indexed table and
  on quickSearchFailedEvent rows: database vs index diff, and why a record
  does or does not match a term (token-level reasons, explain, rank).
- Search failure diagnostics: provider and QuickSearchAction failures are
  recorded as SEARCH_FAILED events (never the term, only its length), with
  runtime counters; the Search Diagnostics widget shows provider state,
  recent failures from every server and the latest validation.
- New settings: enableDiagnosticTools, enableRecordDiagnosticActions,
  validationCronExpression, validationCronTimeZoneId, validationSampleSize,
  diagnosticRunsPerMinute, debugPermissionRules (quickSearchDebug).
- History purge covers the two new tables.

Tests: unit (metadata incl. QInstanceValidator, offline tool behaviour
against a closed port, the playground loop through RunProcessAction) and a
Testcontainers OpenSearch integration test for every tool.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 06:02:29 -05:00
james.maesandClaude Opus 5.5 e1771411e1 fix(#29): validate cron zone, warn when basepull is off, document schedulers (#31)
* fix(#29): validate cron zone, warn when basepull is off, document schedulers

A reconcileCronExpression without reconcileCronTimeZoneId passed the
QBit's validation, then QQQ's QInstanceValidator rejected the reconcile
process schedule at startup ("a cron schedule must specify a
cronTimeZoneId"); QQQ has no default zone. validate() now applies the
same checks QQQ does (Quartz CronExpression.validateExpression, a zone
from TimeZone.getAvailableIDs) and requires the zone, naming both
fields. It also rejects a cron on a scheduler in the instance that does
not support cron: QQQ's SimpleScheduler runs fixed intervals only and
fails when the schedule manager starts.

Config-driven tables without their basepull timestamp field now log the
same startup warning as annotated tables, once per table, through one
shared helper. A field set to null is an opt-out and stays quiet.

README and MIGRATION-1.0 document that schedules run only when the host
starts through QApplicationLauncher (qqq-middleware-javalin), and that a
reconcile cron needs a Quartz scheduler and a time zone ID.

Closes #29

* docs(producer): keep develop's hidden-and-password Javadoc after the merge

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 06:00:59 -05:00
james.maesandClaude Opus 5.5 9c9d2d7e21 docs(#26): fix migration guide and README gaps (#27)
* docs(#26): fix migration guide and README gaps

The migration guide now names the permissions a host must grant and has
a schema section for the 0.x to 1.0 table changes, including the new
quickSearchFailedEvent table and the status value lengths. The
plaintext credentials setter is spelled withAllowPlaintextCredentials,
and the README and PRD point at 1.0.0-RC.2 as the current release.

Closes #26

* docs(#26): name each table in the migration schema step

The schema step now says which table each STRING to TEXT change belongs
to and includes the required, unique quickSearchIndex.tableName, matching
the schema section.

Refs #26

* docs(readme): name 1.1.0-RC.1 as the current release candidate

Maven Central's newest is 1.1.0-RC.1 (develop is the 1.1 line). Keep the
1.0 line's 1.0.0-RC.2 for hosts that stay on 1.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 05:57:02 -05:00
james.maesandClaude Opus 5.5 316ac9484f feat: serve QQQ /qqq/v1/search from OpenSearch (record-search provider)
Implements QQQ core's RecordSearchProviderInterface so the Next UI global
search (POST /qqq/v1/search) is served from the Quick Search index for the
tables this QBit indexes. The provider returns record ids only; core re-reads
them through QueryAction, so table permissions, record security locks and
labels stay core's job. One bounded _msearch per call, with a short backoff
after a failure during which core falls back to its own LIKE search.

Builds against the released QQQ 4.1.0-RC.2, the first release that carries
the SPI (replaces the 4.1.0-SNAPSHOT pin from PR #32).

Re-signed from PR #32 (originally 75dc2b3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 13:23:22 -05:00
james.maesandClaude Opus 5.5 e06b06000b fix(indexing): real-time inserts index display values (#28)
Real-time INSERT events were indexed from the event's own records, which
carry raw values only, so a foreign key was indexed as its id and the
record label as "2 - email" until the next basepull. Inserts now take the
same path as updates: the listener re-reads the written records inside
the write's transaction with display values and possible-value labels.

A failed re-read is handled as for updates (#13): logged at once, then
recorded in quickSearchFailedEvent after commit for basepull replay,
never failing the host's insert, and nothing recorded on rollback.

Tests: listener unit tests for the PVS label and record label of a
just-inserted record, and for a failed insert re-read (commit and
rollback); an OpenSearch Testcontainers test that a just-inserted
record is searchable by its possible-value label and carries it in
fieldValues and the record label.

Closes #28

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 07:54:35 -05:00
james.maes 2b627e767a docs: record the 1.0.0-RC.2 release (#12) (#23)
CHANGELOG gains the RC.2 entry and the #13 to #17 fixes; TODO and SESSION-STATE reflect RC.2 and the remaining GA items.
2026-10-06 21:12:27 -05:00
james.maes 12afb08deb docs: record the 1.0.0-RC.1 release (#12) (#11)
* docs: record the 1.0.0-RC.1 release and the orb RC mechanics

* docs: changelog entry, README version and PRD status for 1.0.0-RC.1

Refs #12.
2026-10-06 15:45:42 -05:00
james.maes 0cd892d1a0 feat: 1.0 release readiness (#10)
* docs: add 1.0 PRD, deep-dive audit, plan, and session state

* build: target qqq 4.1.0-RC.1, opensearch-java 3.10.0, wrapper 3.9.11, real JaCoCo gate

* feat: add 1.0 config surface, instance-scoped runtime, and deprecated static facade

* feat: implement the 4.1 QBit contract with a record-change listener and failed-event capture

* feat: opensearch client with auth modes, TLS, timeouts, mapping v2, aliases, versioned bulk writes

* feat: trustworthy indexing steps and permission-aware bounded search

* docs: rewrite README for 1.0, add CHANGELOG and migration guide

* feat: table picker and result screens for the maintenance processes; close out 1.0 planning docs

* docs: add AGENTS.md so Codex shares the CLAUDE.md guidance

* fix: keep the live index after an alias swap, atomic legacy upgrade, exact paging under record locks

From the PR #10 review: never delete the new physical index once the alias points at it, upgrade a legacy concrete index in one aliases request, base hasMore on raw hits so filtered pages stay reachable, and deduplicate requested table names.

* docs: explain the hasMore trade-off under record locks

* docs: session state for the RC.1 hand-off
2026-10-05 09:50:05 -05:00
james.maes 24c0da4f63 chore: clean slate for v1 clean-room rewrite
Remove all existing Java source and test files. Remove template docs.
Remove unused javalin dependency. Raise JaCoCo thresholds to 70%/90%.
2026-03-28 15:14:30 -05:00
james.maes 23f4305f1b feat(tests): add tests for Step and Producer classes
- Add FullReindexStepTest with 7 tests
- Add BasepullIndexStepTest with 8 tests
- Add QuickSearchQBitProducerTest with 12 tests
- Update CLAUDE.md with project status
- Add docs/TODO.md and docs/SESSION-STATE.md
2026-01-09 14:54:31 -06:00
james.maes ffefd8f148 Initial commit 2026-01-09 11:56:58 -06:00