Skip to content

Commit 233222e

Browse files
huangyiireneclaude
andauthored
feat(spec)!: close timeDimensions[].dateRange's string arm to the date-range preset vocabulary (#16041) (#16618)
* feat(spec): close timeDimensions[].dateRange's string arm to the date-range preset vocabulary (wip) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno * feat(spec): changeset, ADR-0087 registration and regenerated projections for the closed dateRange vocabulary (wip 2) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno * chore(spec): regenerate api-surface, export-origins, declaration-map and reference docs for AnalyticsDateRangePreset (wip 3) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno * test(spec): pin the two isomorphic dateRange aliases (ADR-0122) and compile the schema example (wip 4) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno * test(service-analytics): re-spell the single-day dateRange fixture in the array form The closed string vocabulary for timeDimensions[].dateRange retires the bare-date spelling this fixture authored, so the package's required TypeScript Type Check went red on one line (TS2322 at line 187). The fixture now writes the same single-day window as ['2026-01-20', '2026-01-20']; the strategy lowers both spellings to the identical $gte/$lte bounds, so the expected values are untouched. The test's title still names the retired dialect on purpose: a comment above it records that retiring the test belongs to the driver-alignment card, together with the strategy's degeneration. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno * chore(spec): regenerate content/docs/references/index.mdx on the merged tree Regeneration commit for the forward merge of origin/main (554a160) into this branch, kept apart from the merge commit so the two can be read separately. `gen:schema` + `gen:docs` on the merged tree changed exactly one file: the references index, whose counts are now the union of both sides — main's ResumeFailureDetails (API 436 -> 437) plus this branch's AnalyticsDateRange / AnalyticsDateRangePreset (Data 166 -> 168), total 1575 -> 1577. No other generated artifact moved. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno * test(driver-memory): retire the 15 date-range pins whose input the closed dateRange contract no longer admits Not a test disabled to get green. #16041 closed the string arm of timeDimensions[].dateRange to the date-range-presets.ts vocabulary (maintainer ruling, decision batch #57), and this retirement is the maintainer's option-B decision of 2026-09-07, chosen over routing the fixtures around the schema door because that would have kept a live pin on the silent-widening fallback #16041 exists to abolish. The three memory-analytics-date-range-{dst,timezone,utc-window} files fed the retired relative dialect ('last 3 days', 'last 7 days', 'last 1 week', 'last 2 weeks', 'last 1 month', 'last 3 months', 'last 1 year') and one garbage string through asQuery = AnalyticsQuerySchema.parse, so on this branch they read 15 failed | 37 passed (52) plus three TS2322, on input production can no longer deliver through any door. Re-spelling was measured, not assumed: driving the built dist directly, only 'today' produces a window; every other preset (last_7_days, last_week, ...) falls to parseDateRangeString's [range, range] fallback and matches every row, because the parser keys on startsWith('last '). So 0 of the 15 cases are expressible until #16322 aligns the parser. Form: it.todo per retired case, original title kept and suffixed with the reason; a site comment at each naming #16041 and #16322 and stating the coverage lost; the two surviving helpers' `range` parameter retyped from string to AnalyticsDateRange (the closed contract), which is what clears the TS2322. No surviving assertion changed. The dst file's driver harness (CUBE / asQuery / probesSelected / probesFor) had no surviving caller and is removed; its cell table and all eight controls survive. COVERAGE LOST until #16322 reinstates it in preset form: - dst: all 13 driver cells, i.e. the ENTIRE `last N UNIT` arithmetic-leg DST coverage in driver-memory goes to zero: spring-forward and fall-back, the day / week / month / year legs, both hemispheres, the two non-whole-hour zones (St_Johns -03:30, Chatham +12:45). - timezone: the one `last N` case anchoring on the SUPPLIED zone's calendar day and midnight (Asia/Shanghai, 'last 7 days'). - utc-window: the fallback fence on 'not a range at all'; its zone-independence was a property of an answer that matched every row, and #16322 owes the driver-side refusal pin in its place. What survives: the 'today' leg's DST and zone coverage, i.e. the 7 timezone cells including the 23-hour America/New_York spring-forward day and the 11 utc-window cells, plus every control on the dst cell table. Reinstatement note for #16322: last_7_days / last_30_days / last_90_days are rolling day-leg windows; last_week / last_month / last_quarter / last_year are calendar windows, not n units back, so the week / month / year cells need re-measured transition instants under preset semantics. Measured: driver-memory typecheck exit 2 (three TS2322) before, exit 0 after; the three files 15 failed | 37 passed before, 37 passed | 15 todo after, also under TZ=America/New_York; full package 1095 passed | 15 todo (1110); spec and runtime pins unmoved (235/235, 37/37); dist byte-identical under a forced rebuild, so the 16 dependents cannot observe a test-only diff. The same 15 failures are what reddened Temporal Conformance on d8a3fd2 (its non-SQL leg runs driver-memory under TZ=America/New_York); the InnoDB line in that job's tail is the MySQL container's echo of a passing negative test and appears in main's green run too. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T6HeZvT9wdSJD1ZxJb5Eno --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 4fe00b8 commit 233222e

25 files changed

Lines changed: 895 additions & 170 deletions
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
"@objectstack/spec": minor
3+
"@objectstack/runtime": minor
4+
---
5+
6+
feat(spec)!: `timeDimensions[].dateRange`'s string arm closes to the date-range preset vocabulary; any other string is refused with `400 ANALYTICS_DATE_RANGE_UNRECOGNIZED` (#16041)
7+
8+
<!-- adr-0087: registered analytics-time-dimension-date-range-vocabulary-closed -->
9+
10+
**BREAKING** — an accept-set narrowing on a published analytics contract.
11+
`AnalyticsQuerySchema.timeDimensions[].dateRange` (and with it the
12+
`POST /analytics/query` / `/analytics/sql` bodies, `AnalyticsQueryRequestSchema`,
13+
and the `AnalyticsQuery` type every driver and `AnalyticsService.query` caller is
14+
typed against) used to accept ANY string. It now accepts exactly the thirteen
15+
dashboard date-range preset names, derived from `data/date-range-presets.ts`
16+
(`z.enum(DATE_RANGE_PRESETS)` — the vocabulary's single source of truth since
17+
#4614, so the two cannot drift), or the unchanged `[start, end]` array arm.
18+
Shipped as `minor` under the repo's launch-window convention for breaking
19+
changes; the hand-migration prescription is registered under protocol major 18.
20+
Maintainer ruling on #16041 (2026-09-06, decision batch #57, option A —
21+
contract first, 「同意」): 「本项目以协议为基准。所以开发应该对其协议,协议有问题应该立卡修改协议」.
22+
23+
## What was wrong
24+
25+
The arm was a bare `z.string()` whose only documented example — `"Last 7 days"`,
26+
in the schema's own comment — was a value no driver could parse. `driver-memory`
27+
recognised exactly `today` and a case-sensitive `last N <unit>` and fell every
28+
other string through to a `[range, range]` pseudo-window that (measured through
29+
mingo, 2026-09-05) matched **every `Date`-typed row**, 2099 included, because a
30+
`Date` compares above a `String` under BSON cross-type ordering. The SQL
31+
strategies read the same bare string as a single ISO day. A dashboard asking for
32+
one week silently got all of history on one backend and one day on the other,
33+
at HTTP 200 on both.
34+
35+
## What it does now
36+
37+
- The string arm is `AnalyticsDateRangePresetSchema = z.enum(DATE_RANGE_PRESETS)`
38+
(`today`, `yesterday`, `this_week`, `last_week`, `this_month`, `last_month`,
39+
`this_quarter`, `last_quarter`, `this_year`, `last_year`, `last_7_days`,
40+
`last_30_days`, `last_90_days`); the schema example is corrected to
41+
`'last_7_days'`.
42+
- Any other value raises ONE prescriptive issue at `timeDimensions.N.dateRange`
43+
(`analyticsDateRangeRefusalMessage`: the value, the vocabulary, the array
44+
spelling for an explicit window). `@objectstack/spec/data` exports the
45+
structural predicate `isAnalyticsDateRangeRefusalIssue` for doors.
46+
- `POST /analytics/query` and `/analytics/sql` answer the ADR-0112 envelope
47+
**`400 ANALYTICS_DATE_RANGE_UNRECOGNIZED`** — a new `ERROR_CODE_LEDGER` member
48+
registered under `@objectstack/runtime` — and the analytics service is never
49+
reached. A body wrong in more places than the `dateRange` stays the generic
50+
`400 VALIDATION_FAILED` + `details.fields[]`.
51+
52+
## FROM → TO
53+
54+
| you wrote | write instead |
55+
|:--|:--|
56+
| `dateRange: 'Last 7 days'` / `'last 7 days'` | `dateRange: 'last_7_days'` |
57+
| `dateRange: 'Last 30 days'` / `'last 30 days'` | `dateRange: 'last_30_days'` |
58+
| `dateRange: 'last 3 months'` | `dateRange: 'last_90_days'`, or an explicit `['{90_days_ago}', '{today}']` |
59+
| `dateRange: '2026-01-20'` (the SQL single-day dialect) | `dateRange: ['2026-01-20', '2026-01-20']` |
60+
| `dateRange: 'This week'` | `dateRange: 'this_week'` |
61+
| `dateRange: ['2026-01-01', '2026-01-31']` | unchanged |
62+
63+
Measured in this repository at the ruling: three authored `'Last 7 days'`, all
64+
in `packages/spec` tests (re-spelled here), and no published dashboard authors
65+
the string arm at all — the shipped console lowers presets to the array arm
66+
before querying. The drivers' own refusal of a non-conforming value that reaches
67+
them in-process (past the schema) is the sibling card #16322, blocked by this
68+
one; the fenced `service-analytics` fixture that authors the retired bare-ISO
69+
spelling is that card's to re-triage.

content/docs/references/api/analytics.mdx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,14 +83,22 @@ const result = AnalyticsEndpoint.parse(data);
8383
| **measures** | `string[]` || List of metrics to calculate |
8484
| **dimensions** | `string[]` | optional | List of dimensions to group by |
8585
| **where** | `any` | optional | Filtering criteria (canonical Query DSL FilterCondition). An authored `FilterArray` is lowered by `parseFilterAST` on the client before the wire; this field admits only the lowered `FilterCondition` (see `FilterArray` in `data/filter.zod.ts`). |
86-
| **timeDimensions** | `{ dimension: string; granularity?: Enum<'second' \| 'minute' \| 'hour' \| 'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>; dateRange?: string \| string[] }[]` | optional | |
86+
| **timeDimensions** | `{ dimension: string; granularity?: Enum<'second' \| 'minute' \| 'hour' \| 'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>; dateRange?: Enum<'today' \| 'yesterday' \| 'this_week' \| 'last_week' \| 'this_month' \| 'last_month' \| …> \| string[] }[]` | optional | Time-bucketed dimensions. Each entry names a dimension, an optional bucket `granularity`, and an optional `dateRange` — a preset name from the closed date-range vocabulary (e.g. `'last_7_days'`) or an explicit `[start, end]` window; an unrecognised string answers `400 ANALYTICS_DATE_RANGE_UNRECOGNIZED` instead of silently widening. |
8787
| **order** | `Record<string, Enum<'asc' \| 'desc'>>` | optional | |
8888
| **limit** | `number` | optional | |
8989
| **offset** | `number` | optional | |
9090
| **timezone** | `string` | optional | |
9191
| **query** | `never` | optional | [REMOVED] `query` was removed from AnalyticsQueryRequest in @objectstack/spec 17.0.0. The `{ cube, query: {...} }` envelope was the dialect of the retired degraded analytics shim — the real engine never understood it. Move the query.* fields to the body top level: `{ cube, measures, dimensions?, where?, timeDimensions?, order?, limit?, offset?, timezone? }`. |
9292
| **format** | `never` | optional | [REMOVED] `format` was removed from AnalyticsQueryRequest in @objectstack/spec 17.0.0. It was never implemented — every response is the JSON envelope. Delete the key; for CSV/XLSX use the export surface instead. |
9393

94+
### Nested Shape: `AnalyticsQueryRequest.timeDimensions[number]`
95+
96+
| Property | Type | Required | Description |
97+
| :--- | :--- | :--- | :--- |
98+
| **dimension** | `string` || |
99+
| **granularity** | `Enum<'second' \| 'minute' \| 'hour' \| 'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>` | optional | |
100+
| **dateRange** | `Enum<'today' \| 'yesterday' \| 'this_week' \| 'last_week' \| 'this_month' \| 'last_month' \| …> \| string[]` | optional | Time window for this dimension: a date-range PRESET name from the closed vocabulary in `data/date-range-presets.ts` (today, yesterday, this_week, last_week, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_7_days, last_30_days, last_90_days — e.g. `'last_7_days'`), or an explicit `[start, end]` array of ISO dates / `{date-macro}` tokens (e.g. `["2023-01-01", "2023-01-31"]`). Any other string is refused at the schema with `400 ANALYTICS_DATE_RANGE_UNRECOGNIZED`. |
101+
94102

95103
---
96104

content/docs/references/api/contract.mdx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const result = ApiErrorSchema.parse(data);
2727

2828
| Property | Type | Required | Description |
2929
| :--- | :--- | :--- | :--- |
30-
| **code** | `Enum<'VALIDATION_ERROR' \| 'INVALID_FIELD' \| 'MISSING_REQUIRED_FIELD' \| 'INVALID_FORMAT' \| 'VALUE_TOO_LONG' \| 'VALUE_TOO_SHORT' \| 'VALUE_OUT_OF_RANGE' \| … +298 more>` || Error code (e.g. VALIDATION_ERROR; StandardErrorCode ∪ the ledger the serving side registers — ERROR_CODE_LEDGER for framework packages) |
30+
| **code** | `Enum<'VALIDATION_ERROR' \| 'INVALID_FIELD' \| 'MISSING_REQUIRED_FIELD' \| 'INVALID_FORMAT' \| 'VALUE_TOO_LONG' \| 'VALUE_TOO_SHORT' \| 'VALUE_OUT_OF_RANGE' \| … +299 more>` || Error code (e.g. VALIDATION_ERROR; StandardErrorCode ∪ the ledger the serving side registers — ERROR_CODE_LEDGER for framework packages) |
3131
| **declaredCode** | `string` | optional | The producer-declared code, verbatim, when it is not a member of the closed `code` vocabulary — the open, author-authored channel (app-specific spellings; ADR-0112) |
3232
| **message** | `string` || Readable error message |
3333
| **userMessage** | `string` | optional | Producer-marked user-facing refusal text, verbatim. Present exactly when the producer opted in at throw time; consumers render it to end users and keep their generic substitution for anything unmarked. Status-agnostic; never replaces `message`. |
@@ -93,6 +93,7 @@ const result = ApiErrorSchema.parse(data);
9393
* `ACTION_DISABLED`
9494
* `ALREADY_REVERTED`
9595
* `AMBIGUOUS_MATCH`
96+
* `ANALYTICS_DATE_RANGE_UNRECOGNIZED`
9697
* `ANALYTICS_QUERY_FAILED`
9798
* `APPROVAL_ACTIONS_FAILED`
9899
* `APPROVAL_APPROVE_FAILED`

content/docs/references/api/error-code-ledger.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ const result = ErrorCode.parse(data);
209209
* `ACTION_DISABLED`
210210
* `ALREADY_REVERTED`
211211
* `AMBIGUOUS_MATCH`
212+
* `ANALYTICS_DATE_RANGE_UNRECOGNIZED`
212213
* `ANALYTICS_QUERY_FAILED`
213214
* `APPROVAL_ACTIONS_FAILED`
214215
* `APPROVAL_APPROVE_FAILED`

content/docs/references/data/analytics.mdx

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ This layer decouples the "Physical Data" (Tables/Columns) from the
2020
## TypeScript Usage
2121

2222
```typescript
23-
import { AggregationMetricType, AnalyticsQuerySchema, CubeSchema, CubeJoinSchema, DimensionSchema, DimensionType, MetricSchema, TimeUpdateInterval } from '@objectstack/spec/data';
24-
import type { AggregationMetricType, AnalyticsQuery, Cube, CubeJoin, Dimension, DimensionType, Metric, TimeUpdateInterval } from '@objectstack/spec/data';
23+
import { AggregationMetricType, AnalyticsDateRangeSchema, AnalyticsDateRangePresetSchema, AnalyticsQuerySchema, CubeSchema, CubeJoinSchema, DimensionSchema, DimensionType, MetricSchema, TimeUpdateInterval } from '@objectstack/spec/data';
24+
import type { AggregationMetricType, AnalyticsDateRange, AnalyticsDateRangePreset, AnalyticsQuery, Cube, CubeJoin, Dimension, DimensionType, Metric, TimeUpdateInterval } from '@objectstack/spec/data';
2525

2626
// Validate data
2727
const result = AggregationMetricType.parse(data);
@@ -44,6 +44,48 @@ const result = AggregationMetricType.parse(data);
4444
* `boolean`
4545

4646

47+
---
48+
49+
## AnalyticsDateRange
50+
51+
### Union Options
52+
53+
This schema accepts one of the following structures:
54+
55+
#### Option 1
56+
57+
Allowed Values: `today`, `yesterday`, `this_week`, `last_week`, `this_month`, `last_month`, `this_quarter`, `last_quarter`, `this_year`, `last_year`, `last_7_days`, `last_30_days`, `last_90_days`
58+
59+
---
60+
61+
#### Option 2
62+
63+
Type: `string[]`
64+
65+
---
66+
67+
68+
---
69+
70+
## AnalyticsDateRangePreset
71+
72+
### Allowed Values
73+
74+
* `today`
75+
* `yesterday`
76+
* `this_week`
77+
* `last_week`
78+
* `this_month`
79+
* `last_month`
80+
* `this_quarter`
81+
* `last_quarter`
82+
* `this_year`
83+
* `last_year`
84+
* `last_7_days`
85+
* `last_30_days`
86+
* `last_90_days`
87+
88+
4789
---
4890

4991
## AnalyticsQuery
@@ -56,12 +98,20 @@ const result = AggregationMetricType.parse(data);
5698
| **measures** | `string[]` || List of metrics to calculate |
5799
| **dimensions** | `string[]` | optional | List of dimensions to group by |
58100
| **where** | `any` | optional | Filtering criteria (canonical Query DSL FilterCondition). An authored `FilterArray` is lowered by `parseFilterAST` on the client before the wire; this field admits only the lowered `FilterCondition` (see `FilterArray` in `data/filter.zod.ts`). |
59-
| **timeDimensions** | `{ dimension: string; granularity?: Enum<'second' \| 'minute' \| 'hour' \| 'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>; dateRange?: string \| string[] }[]` | optional | |
101+
| **timeDimensions** | `{ dimension: string; granularity?: Enum<'second' \| 'minute' \| 'hour' \| 'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>; dateRange?: Enum<'today' \| 'yesterday' \| 'this_week' \| 'last_week' \| 'this_month' \| 'last_month' \| …> \| string[] }[]` | optional | Time-bucketed dimensions. Each entry names a dimension, an optional bucket `granularity`, and an optional `dateRange` — a preset name from the closed date-range vocabulary (e.g. `'last_7_days'`) or an explicit `[start, end]` window; an unrecognised string answers `400 ANALYTICS_DATE_RANGE_UNRECOGNIZED` instead of silently widening. |
60102
| **order** | `Record<string, Enum<'asc' \| 'desc'>>` | optional | |
61103
| **limit** | `number` | optional | |
62104
| **offset** | `number` | optional | |
63105
| **timezone** | `string` | optional | |
64106

107+
### Nested Shape: `AnalyticsQuery.timeDimensions[number]`
108+
109+
| Property | Type | Required | Description |
110+
| :--- | :--- | :--- | :--- |
111+
| **dimension** | `string` || |
112+
| **granularity** | `Enum<'second' \| 'minute' \| 'hour' \| 'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>` | optional | |
113+
| **dateRange** | `Enum<'today' \| 'yesterday' \| 'this_week' \| 'last_week' \| 'this_month' \| 'last_month' \| …> \| string[]` | optional | Time window for this dimension: a date-range PRESET name from the closed vocabulary in `data/date-range-presets.ts` (today, yesterday, this_week, last_week, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_7_days, last_30_days, last_90_days — e.g. `'last_7_days'`), or an explicit `[start, end]` array of ISO dates / `{date-macro}` tokens (e.g. `["2023-01-01", "2023-01-31"]`). Any other string is refused at the schema with `400 ANALYTICS_DATE_RANGE_UNRECOGNIZED`. |
114+
65115

66116
---
67117

content/docs/references/index.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Protocol Reference
3-
description: Every schema published by @objectstack/spec — 1575 schemas across 14 protocol modules
3+
description: Every schema published by @objectstack/spec — 1577 schemas across 14 protocol modules
44
---
55

66
{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
@@ -23,7 +23,7 @@ counts are sums of the rows they head. Regenerate with
2323
| [API Protocol](/docs/references/api) | 31 | 437 | REST contracts, endpoints, routing, realtime, batch, discovery. |
2424
| [Automation Protocol](/docs/references/automation) | 13 | 73 | Flows and their nodes, approvals, ETL pipelines, webhooks, state machines, execution records. |
2525
| [Cloud Protocol](/docs/references/cloud) | 11 | 94 | Environments, packages and versions, marketplace, developer portal, tenancy. |
26-
| [Data Protocol](/docs/references/data) | 29 | 166 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. |
26+
| [Data Protocol](/docs/references/data) | 29 | 168 | Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer. |
2727
| [Identity Protocol](/docs/references/identity) | 5 | 27 | Users and accounts, organizations, positions, SCIM provisioning. |
2828
| [Integration Protocol](/docs/references/integration) | 1 | 24 | The single connector protocol (ADR-0097) — catalog descriptors and provider-bound instances. |
2929
| [Kernel Protocol](/docs/references/kernel) | 30 | 162 | Plugin lifecycle and manifests, capabilities and security, metadata loading, service registry. |
@@ -33,7 +33,7 @@ counts are sums of the rows they head. Regenerate with
3333
| [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. |
3434
| [System Protocol](/docs/references/system) | 33 | 272 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. |
3535
| [UI Protocol](/docs/references/ui) | 16 | 153 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. |
36-
| **Total** | **198** | **1575** | 14 protocol modules |
36+
| **Total** | **198** | **1577** | 14 protocol modules |
3737

3838
---
3939

@@ -149,13 +149,13 @@ Environments, packages and versions, marketplace, developer portal, tenancy.
149149

150150
## Data Protocol
151151

152-
**Source:** `packages/spec/src/data/` · **Import:** `@objectstack/spec/data` · **29 pages, 166 schemas**
152+
**Source:** `packages/spec/src/data/` · **Import:** `@objectstack/spec/data` · **29 pages, 168 schemas**
153153

154154
Objects, fields, queries, filters, datasources and drivers — the ObjectQL layer.
155155

156156
| File | Schemas |
157157
| :--- | :--- |
158-
| [`analytics.zod.ts`](/docs/references/data/analytics) | `AggregationMetricType`, `AnalyticsQuery`, `Cube`, `CubeJoin`, `Dimension`, `DimensionType`, `Metric`, `TimeUpdateInterval` |
158+
| [`analytics.zod.ts`](/docs/references/data/analytics) | `AggregationMetricType`, `AnalyticsDateRange`, `AnalyticsDateRangePreset`, `AnalyticsQuery`, `Cube`, `CubeJoin`, `Dimension`, `DimensionType`, `Metric`, `TimeUpdateInterval` |
159159
| [`context-tokens.zod.ts`](/docs/references/data/context-tokens) | `ContextToken`, `ContextTokenPlaceholder` |
160160
| [`data-engine.zod.ts`](/docs/references/data/data-engine) | `BaseEngineOptions`, `DataEngineAggregateOptions`, `DataEngineAggregateRequest`, `DataEngineCountOptions`, `DataEngineCountRequest`, `DataEngineDeleteOptions`, `DataEngineDeleteRequest`, `DataEngineExecuteRequest`, `DataEngineFilter`, `DataEngineFindOneRequest`, `DataEngineFindRequest`, `DataEngineInsertOptions`, `DataEngineInsertRequest`, `DataEngineQueryOptions`, `DataEngineRequest`, `DataEngineSort`, `DataEngineUpdateOptions`, `DataEngineUpdateRequest`, `DataEngineVectorFindRequest`, `DroppedFieldsEvent`, `EngineAggregateOptions`, `EngineCountOptions`, `EngineDeleteOptions`, `EngineQueryOptions`, `EngineUpdateOptions` |
161161
| [`datasource.zod.ts`](/docs/references/data/datasource) | `Datasource`, `DriverDefinition`, `DriverType`, `ExternalDatasourceSettings`, `SchemaMode` |

0 commit comments

Comments
 (0)