|
| 1 | +--- |
| 2 | +'@objectstack/spec': minor |
| 3 | +--- |
| 4 | + |
| 5 | +feat(spec)!: retire the cube metric types `number`, `string` and `boolean` — a measure's `sql` is a column reference, so the custom-SQL-expression types had nothing left to compute (#21000) |
| 6 | + |
| 7 | +**BREAKING** — three members leave `AggregationMetricType`, so a cube measure's |
| 8 | +`measures.<metric>.type` no longer accepts `number`, `string` or `boolean`. ADR-0049 |
| 9 | +enforce-or-remove. They declared "a custom SQL expression returning a number / |
| 10 | +string / boolean": the measure's `sql` was the whole computation. A cube member's |
| 11 | +`sql` is a column reference since `cube-member-sql-expression-retired` (#20943), so |
| 12 | +the three were left naming nothing: measured before this change, the raw-SQL |
| 13 | +analytics path returned the referenced column UNAGGREGATED (a bare column in a |
| 14 | +grouped statement — by SQL's own rules an error on PostgreSQL and an arbitrary row's |
| 15 | +value on SQLite), and the ObjectQL path refused the measure. The six aggregates — `count`, `sum`, |
| 16 | +`avg`, `min`, `max`, `count_distinct` — are unchanged and are now the whole |
| 17 | +vocabulary. |
| 18 | + |
| 19 | +### FROM → TO |
| 20 | + |
| 21 | +| removed | what to write instead | |
| 22 | +| --- | --- | |
| 23 | +| `measures.<metric>.type: 'number'`, `'string'` or `'boolean'` | the aggregate the measure means: `sum`, `avg`, `min` or `max` over the column; `count` (over `'*'` for a row count, or over a column for its non-null values); or `count_distinct`. | |
| 24 | +| a measure whose old expression computed a value per row | keep that value as a field of the object (a stored or formula field) and aggregate the field. | |
| 25 | +| a measure whose old expression combined measures (a ratio, a difference) | `derived: { op, of: [...] }` on an ADR-0021 dataset over the same object. | |
| 26 | + |
| 27 | +**The one-line fix: give the measure an aggregate type.** There is no mechanical |
| 28 | +rewrite — the column alone does not say whether `amount` meant its sum, its average |
| 29 | +or its largest value — so `os migrate meta` lists nothing for this change. |
| 30 | + |
| 31 | +Each retired member is refused at parse with a prescription naming the six |
| 32 | +aggregates, at the measure's `type`, and in `tsc` (the members are gone from the |
| 33 | +`AggregationMetricType` type). A value the enum never declared keeps zod's own |
| 34 | +message. |
| 35 | + |
| 36 | +### The retirement kit |
| 37 | + |
| 38 | +- **Value-level retirement.** `AggregationMetricType` is declared through |
| 39 | + `enumWithRetiredValues` (`shared/retired-key.ts`), with the prescriptions |
| 40 | + module-private. No authorable KEY and no def changed, so nothing lands in |
| 41 | + `RETIRED_KEYS_BY_MAJOR`, and the four surface ratchets (`api-surface`, |
| 42 | + `authorable-surface`, `json-schema.manifest`, `api-surface-signatures`) are |
| 43 | + byte-identical. |
| 44 | +- **No D2 conversion, by design.** A stored or built cube that still carries one of |
| 45 | + the three is REFUSED, never rewritten or dropped: the boot door |
| 46 | + (`ObjectStackDefinitionSchema`, which a built artifact is parsed through), the |
| 47 | + `analytics_cube` write door and `defineStack` refuse it with the prescription, and |
| 48 | + the rehydration seam replays no conversion over it. |
| 49 | +- **D3 entry `cube-metric-expression-types-retired`**, with its step-18 rationale |
| 50 | + fragment, carries the judgement the upgrader owes: which aggregate each measure |
| 51 | + meant. |
| 52 | +- **Liveness.** The `analytics_cube` row `measures.type` stays `live`, re-verified |
| 53 | + 2026-10-02, with the narrowing recorded. |
| 54 | +- **Docs.** The `data/analytics` reference page is regenerated. |
| 55 | +- **No deprecation window**, per the project's startup-stage posture. |
| 56 | + |
| 57 | +### Reach, measured |
| 58 | + |
| 59 | +- This repository authors no cube measure of the three types outside tests: |
| 60 | + `examples/**`, `packages/**` (the platform objects included) and the skills and |
| 61 | + docs carry none. The showcase cube's `type: 'string'` entries are dimensions, |
| 62 | + whose `DimensionType` is a separate enum and is unchanged. |
| 63 | +- objectui at its pinned commit carries no `AggregationMetricType` mirror and no |
| 64 | + cube measure of the three types. |
| 65 | +- Out-of-repo authored cubes: NOT MEASURED. |
| 66 | + |
| 67 | +Clause-②: no (narrowing) |
| 68 | + |
| 69 | +<!-- adr-0087: registered cube-metric-expression-types-retired --> |
0 commit comments