Skip to content

feat(query): upgrade query architecture, analytics and cursor - #2908

Open
Ahoo-Wang wants to merge 18 commits into
mainfrom
agent/query-service-architecture-upgrade
Open

feat(query): upgrade query architecture, analytics and cursor#2908
Ahoo-Wang wants to merge 18 commits into
mainfrom
agent/query-service-architecture-upgrade

Conversation

@Ahoo-Wang

@Ahoo-Wang Ahoo-Wang commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Summary

This PR consolidates the complete Query Service architecture upgrade into one review surface, from execution-correctness foundations through Query/Analytics/Cursor contracts and planned MongoDB/Elasticsearch backends.

  • establish per-subscription, fail-closed query execution and error observation
  • introduce the unified Gateway, immutable admission/normalization/planning model, trusted policy boundary, and provenance-preserving mandatory predicates
  • preserve legacy execution while separating rollout mode (LEGACY | SHADOW | PLANNED) from semantic validation (COMPATIBLE | STRICT)
  • promote the approved experimental Query/Analytics/Cursor contracts and backend-facing immutable plans
  • add cursor signing, persistent leases, complete initial budget ceilings, continuation replay protection, and reaping
  • add planned MongoDB and Elasticsearch record/analytics backends with storage-aware Spring composition and shared TCK coverage
  • add WebFlux/OpenAPI/API-client integration, Elasticsearch index lifecycle support, and application rollout/rollback runbooks

Contract and compatibility

  • QueryService keeps its existing seven public methods and QueryType keeps its existing seven values
  • the experimental Query/Analytics/Cursor API is intentionally upgraded; consumers of earlier experimental binaries must recompile
  • analytics OpenAPI encodes GLOBAL/BY grouping and metric field requirements with strict oneOf schemas
  • cursor continuations carry the complete initial execution-budget ceiling and may only keep or tighten it
  • no generated client was hand-edited; OpenAPI/schema sources and snapshots were updated at the authoritative boundary

Safety and rollout

  • authority, policy, mandatory filters, budgets, deadlines, and result completeness are enforced before data is published
  • planned backend results are validated for cardinality, consistency, schema shape, and cursor safety
  • shadow execution is bounded and health-observed; it never replaces the legacy primary result
  • Elasticsearch Snapshot CUTOVER is denied unless an explicit write-fence guard is supplied
  • no production index cutover, alias switch, deployment, or live data mutation was performed by this change

Validation

  • ./gradlew detekt build
  • module checks for query, API, MongoDB, Elasticsearch, schema, OpenAPI, API client, Spring, starter, and WebFlux
  • ./gradlew allLocalTest allContractTest allIntegrationTest
  • focused MongoDB/Elasticsearch planned and shadow integration tests
  • cd documentation && pnpm docs:build
  • GitHub Local, Contract, Integration, Java compatibility, Static Analysis, Benchmark, Compensation, Codecov, and Codacy checks

Consolidation

This single PR supersedes the former stacked review PRs #2909, #2910, #2915, #2916, #2917, #2918, and #2924. Their commits are retained here. GitHub automatically marked those PRs MERGED when their head commits became contained by this consolidated base branch; none of them was merged into main independently.

Primary review boundaries:

  • public experimental Query/Analytics/Cursor contracts
  • policy and mandatory-filter fail-closed behavior
  • cursor budget/lease protocol
  • backend binding/readiness and result-completeness rules
  • shadow observability and production rollout/cutover runbooks

This also supersedes the earlier operator-by-operator approach from closed PR #2903.

@github-actions github-actions Bot added area: documentation Changes to project documentation area: spring Changes to Spring or WebFlux integrations labels Aug 6, 2026
@codacy-production

codacy-production Bot commented Aug 6, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 5754 complexity

Metric Results
Complexity 5754

View in Codacy

NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.

@codecov

codecov Bot commented Aug 6, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 69.29825% with 1400 lines in your changes missing coverage. Please review.
✅ Project coverage is 86.11%. Comparing base (63ad981) to head (af0d4ff).
⚠️ Report is 15 commits behind head on main.

Files with missing lines Patch % Lines
...csearch/query/planned/ElasticsearchQueryBinding.kt 68.28% 68 Missing and 63 partials ⚠️
.../query/planned/ElasticsearchRecordQueryCompiler.kt 50.00% 68 Missing and 28 partials ⚠️
...planned/ElasticsearchSnapshotRecordQueryBackend.kt 65.67% 56 Missing and 36 partials ⚠️
...o/query/planned/MongoSnapshotRecordQueryBackend.kt 66.26% 44 Missing and 41 partials ⚠️
...ery/lifecycle/ElasticsearchIndexLifecycleClient.kt 63.59% 52 Missing and 27 partials ⚠️
...uery/lifecycle/ElasticsearchIndexLifecycleModel.kt 67.59% 33 Missing and 37 partials ⚠️
.../mongo/query/planned/MongoAnalyticsQueryBackend.kt 56.52% 34 Missing and 36 partials ⚠️
...ow/mongo/query/planned/MongoRecordQueryCompiler.kt 75.39% 26 Missing and 37 partials ⚠️
...e/ReactiveElasticsearchIndexLifecycleRepository.kt 61.63% 24 Missing and 37 partials ⚠️
...y/lifecycle/ElasticsearchIndexLifecycleExecutor.kt 68.50% 41 Missing and 16 partials ⚠️
... and 20 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #2908      +/-   ##
============================================
- Coverage     92.35%   86.11%   -6.24%     
- Complexity     6822     8670    +1848     
============================================
  Files           984     1089     +105     
  Lines         26118    39659   +13541     
  Branches       2684     5071    +2387     
============================================
+ Hits          24121    34154   +10033     
- Misses         1094     3244    +2150     
- Partials        903     2261    +1358     
Flag Coverage Δ
contract 47.28% <ø> (?)
integration 66.99% <54.58%> (?)
local 81.18% <55.81%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@Ahoo-Wang Ahoo-Wang changed the title refactor: establish query service architecture foundation refactor: establish query execution correctness foundation Aug 6, 2026
@Ahoo-Wang
Ahoo-Wang marked this pull request as ready for review August 6, 2026 14:24
Copilot AI lite review requested due to automatic review settings August 6, 2026 14:24

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 6, 2026 14:45

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 7, 2026 00:17

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 9ddeba24fd

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread wow-query/src/main/kotlin/me/ahoo/wow/query/filter/QueryHandler.kt
Comment thread wow-query/src/main/kotlin/me/ahoo/wow/query/filter/QueryHandler.kt Outdated
Copilot AI review requested due to automatic review settings August 7, 2026 00:52

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 7, 2026 01:31

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Copilot AI review requested due to automatic review settings August 9, 2026 07:29

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@github-actions github-actions Bot added area: api Changes to API, OpenAPI, or schema contracts area: infrastructure Changes to storage or transport integrations labels Aug 9, 2026
@Ahoo-Wang Ahoo-Wang changed the title refactor: establish query execution correctness foundation feat(query): upgrade query architecture, analytics and cursor Aug 9, 2026
@Ahoo-Wang
Ahoo-Wang marked this pull request as draft August 9, 2026 07:29

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 310b33364c

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@Ahoo-Wang
Ahoo-Wang marked this pull request as ready for review August 10, 2026 13:47
Copilot AI review requested due to automatic review settings August 10, 2026 13:47

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review this pull request because it exceeds the maximum number of lines (20,000). Try reducing the number of changed lines and requesting a review from Copilot again.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: af0d4ff590

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


private fun openPit(): Mono<PitLease> = client.openPointInTime(
OpenPointInTimeRequest.of { request ->
request.index(binding.indexName).keepAlive { keepAlive -> keepAlive.time(PIT_KEEP_ALIVE) }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Align PIT lifetime with the cursor lease TTL

When QueryCursorLeaseConfiguration.leaseTtl is legally configured above two minutes, a grouped snapshot analytics cursor remains valid in the lease store after this hard-coded Elasticsearch PIT has expired; resuming it after two minutes therefore fails with an incomplete/backend error despite an unexpired token. Even the default two-minute lease can outlive the PIT slightly because the lease is issued after opening and querying it, so derive keep_alive from the configured lease TTL with margin or reject incompatible TTLs.

Useful? React with 👍 / 👎.

val frozen = session.objectValue(source, 0)
val identity = (frozen.values[Documents.ID_FIELD] as? NormalizedValue.Text)?.value
?: mappingFailure()
val document = frozen.toLogicalDocument().apply(projection, binding.identityOutputField)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Decode Mongo epoch-millis fields during materialization

For every Mongo binding whose schema declares LogicalFieldType.Instant, binding validation requires MongoValueEncoding.EPOCH_MILLIS, so the driver supplies a numeric value; this materialization only reshapes the frozen document and leaves that value as NormalizedValue.Int64 rather than InstantValue (including array elements). Fresh evidence in the final tree is that the Mongo mapper still has no schema-aware decode step, so planned Mongo record queries expose the wrong logical type even though the Elasticsearch mapper was corrected.

Useful? React with 👍 / 👎.

Comment on lines +123 to +125
.map { response ->
if (response.id().isBlank() || response.shards().failed() != 0) incomplete()
PitLease(response.id())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Close partially opened PITs before rejecting them

When Elasticsearch returns a nonblank PIT id together with one or more failed shards, this branch throws before Mono.usingWhen receives a PitLease, so none of its cleanup callbacks can close the contexts that were opened successfully. Repeated queries while a shard is degraded can therefore accumulate PIT resources until their keep-alive expires; construct the lease from the returned id and explicitly close it before propagating the incomplete-result failure. The record-page and lifecycle-verification PIT open paths use the same reject-before-acquisition pattern.

Useful? React with 👍 / 👎.

Comment on lines +294 to +299
is QueryCursorPosition.Analytics -> {
writeByte(ANALYTICS_POSITION)
writeInt(position.dimensionAliases.size)
position.dimensionAliases.forEach { alias -> writeBoundedUtf8(alias.value) }
writeValues(position.afterKey)
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Enforce the cursor dimension limit before issuing a token

When a grouped analytics query has 33 or more dimensions, which the default admission and unrestricted planning constraints allow, this encoder writes every alias and returns a continuation token successfully, but decoding that token applies MAX_POSITION_VALUES = 32 to both the alias and after-key counts. The next request therefore rejects a framework-issued token as INVALID_CURSOR_TOKEN; either reject plans above 32 dimensions before backend execution or make the codec encode/decode bounds consistent.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: api Changes to API, OpenAPI, or schema contracts area: documentation Changes to project documentation area: infrastructure Changes to storage or transport integrations area: spring Changes to Spring or WebFlux integrations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants