Skip to content

Commit 261c529

Browse files
docs(query): stop enumerating a false closed set for the aggregate option keys (#20813)
Fixes #20792 Clause-②: no Two hand-written docs sentences presented the aggregate option set as a closed three-key list. The list is false on both paths. This PR keeps each sentence's true point and drops the enumeration; no key list is pasted into prose (the generated reference owns it). ## Changes 1. `content/docs/protocol/objectql/query-syntax.mdx` (Analytics: Revenue by Month) - Before: "`engine.aggregate()` accepts only `where` / `groupBy` / `aggregations` (plus a `timezone` for bucketing): there is no `orderBy` or `limit` on this path, so sort the returned rows yourself." - After: "`engine.aggregate()` takes a closed option set with no `orderBy` or `limit` (the full list is under `EngineAggregateOptions` in the Data Engine reference), so sort the returned rows yourself. It does carry a `timezone` for bucketing." 2. `content/docs/data-modeling/queries.mdx` (UTC bucketing callout) - Before: "the `POST /api/v1/data/:object/query` route forwards only `where` / `groupBy` / `aggregations`, so a query sent over REST always buckets on UTC calendar boundaries." - After: "the `POST /api/v1/data/:object/query` route does not forward `timezone` to the engine, so a query sent over REST always buckets on UTC calendar boundaries." 3. `content/docs/kernel/contracts/data-engine.mdx` (### EngineAggregateOptions, added in a second commit 7837c5c) - Before: an interface literal listing four of the eight keys, with groupBy typed as a string array. - After: a one-line pointer to the generated reference, `/docs/references/data/data-engine#engineaggregateoptions`; the `AggregationNode` interface and the `distinct` removal note are kept. ## Code anchors (origin/main at 96e7244) - `packages/objectql/src/engine.ts:562-565`: `ENGINE_AGGREGATE_OPTION_KEYS` = context, where, groupBy, aggregations, having, timezone, search, searchFields. Enforced at `:16277` (`rejectUnknownEngineOptions`). No orderBy / limit, so the kept point holds. - `packages/metadata-protocol/src/protocol.ts:11324-11343`: the engine.aggregate call inside `findData` forwards where, groupBy, aggregations, having, search, searchFields, context. `timezone` is not in the bag, and no `timezone` read exists in `findData` (`:10937` to the call), so REST buckets on UTC. - `packages/rest/src/rest-server.ts:8808,8849`: `POST /data/:object/query` calls `p.findData(...)`, confirming the route reaches that path. - Generated reference already lists all eight keys: `content/docs/references/data/data-engine.mdx:891-906`. ## Census (hand-written `content/docs/**`, excluding references/ and releases/) Prose patterns: "only `where`", "accepts only", "forwards only", "groupBy` / `aggregations`", aggregate()-with-only/accepts/forwards, "drops having/search/timezone". Interface and type-literal patterns (added after review): `EngineAggregateOptions`, `AggregateOptions`, `groupBy?:`, `aggregations?:`, aggregate-signature blocks. Hits: the three fixed above (`query-syntax.mdx` sentence, `queries.mdx` sentence, `kernel/contracts/data-engine.mdx` interface literal). Checked and left: `kernel/contracts/data-engine.mdx:28,39` (an import and the `aggregate(...)` signature, which name the type and copy no keys), `:573` (deprecated schema names), `query-syntax.mdx:74-75` (the QueryAST literal for find, not the aggregate option set), `query-syntax.mdx:85`, `:1434`, `api/error-catalog.mdx:301`, `api/data-api.mdx:194`. No further enumeration. ## Acceptance notes - Stale comment on `ENGINE_DRIVER_PASSTHROUGH_KEYS` deliberately left out of this PR, as ruled. - No changeset: docs-only, content/docs is not a published surface. ## Verification Gate list from `node scripts/pm/dispatch-gates.mjs --commands` (40 families), each run at head 7837c5c with exit 0 (after building `@objectstack/lint...`, `@objectstack/spec` and `@objectstack/client-react...` for the gates that read built output); `--ran` reconciliation: 40 derived, 40 run, 0 NOT-MEASURED, 0 UNRUN. --- 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01VDtqoecgES7ScQYGbFVDRv --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent eac538c commit 261c529

3 files changed

Lines changed: 10 additions & 12 deletions

File tree

‎content/docs/data-modeling/queries.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -669,8 +669,8 @@ transparent to the query — you get the same buckets either way.
669669
<Callout type="warn">
670670
Buckets are computed in **UTC**. A non-UTC reference timezone is only reachable through
671671
`ObjectQL.aggregate(object, { …, timezone })`; the `POST /api/v1/data/:object/query`
672-
route forwards only `where` / `groupBy` / `aggregations`, so a query sent over REST
673-
always buckets on UTC calendar boundaries.
672+
route does not forward `timezone` to the engine, so a query sent over REST always
673+
buckets on UTC calendar boundaries.
674674

675675
The optional `alias` on a structured `groupBy` node is honoured only on the in-memory
676676
path. The SQL driver ignores it and always projects the bucket under the **field name**,

‎content/docs/kernel/contracts/data-engine.mdx‎

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -466,14 +466,11 @@ const result = await engine.aggregate('task', {
466466

467467
### EngineAggregateOptions
468468

469-
```typescript
470-
interface EngineAggregateOptions {
471-
where?: FilterCondition; // Pre-aggregation filter (WHERE)
472-
groupBy?: string[]; // GROUP BY fields
473-
aggregations?: AggregationNode[]; // Aggregation definitions
474-
context?: ExecutionContext;
475-
}
469+
The option keys are listed in the generated
470+
[`EngineAggregateOptions` reference](/docs/references/data/data-engine#engineaggregateoptions).
471+
`aggregations` takes `AggregationNode` entries:
476472

473+
```typescript
477474
interface AggregationNode {
478475
function: 'count' | 'sum' | 'avg' | 'min' | 'max' | 'count_distinct';
479476
field?: string; // Field to aggregate (optional for COUNT(*))

‎content/docs/protocol/objectql/query-syntax.mdx‎

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1334,9 +1334,10 @@ const products = await engine.find('product', {
13341334
### Analytics: Revenue by Month
13351335

13361336
`month` is not a column — bucket the `created_at` instant with `dateGranularity`. Note
1337-
that `engine.aggregate()` accepts only `where` / `groupBy` / `aggregations` (plus a
1338-
`timezone` for bucketing): there is no `orderBy` or `limit` on this path, so sort the
1339-
returned rows yourself.
1337+
that `engine.aggregate()` takes a closed option set with no `orderBy` or `limit` (the
1338+
full list is under `EngineAggregateOptions` in the
1339+
[Data Engine reference](/docs/references/data/data-engine)), so sort the returned rows
1340+
yourself. It does carry a `timezone` for bucketing.
13401341

13411342
```typescript
13421343
const monthlyRevenue = await engine.aggregate('order', {

0 commit comments

Comments
 (0)