From 80ae4f4cb3a86a418b7a2659f65e023e0eb64c7c Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 2 Oct 2026 17:28:38 +0000 Subject: [PATCH 1/2] docs(spec): field-scale docblock states the server sum/avg width gap and the ruled end-state The A-prime paragraph promised that a computed result over a no-fixed-width `number` column rounds to the widest decimal count among its inputs. That holds only where the renderer sees the inputs (the grid summary footer, the object-metric tile's min/max). A server-side sum/avg carries no width: the analytics column metadata has format/currency/percentScale and no width member. The docblock now says so, records the ruled end-state (the analytics result reports the width) and its trigger, and names the two declared channels an author has today (a field scale, or a format). No schema, key, export or runtime change. Claude-Session: https://claude.ai/code/session_01UtnxvdiN376GF3sgXwAw4d Co-authored-by: Claude --- ...1183-field-scale-server-aggregate-width.md | 13 ++++++++++ packages/spec/src/data/field-scale.ts | 26 ++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 .changeset/21183-field-scale-server-aggregate-width.md diff --git a/.changeset/21183-field-scale-server-aggregate-width.md b/.changeset/21183-field-scale-server-aggregate-width.md new file mode 100644 index 00000000000..1f834be80b8 --- /dev/null +++ b/.changeset/21183-field-scale-server-aggregate-width.md @@ -0,0 +1,13 @@ +--- +"@objectstack/spec": patch +--- + +`resolveFieldScale`'s module docblock (`@objectstack/spec/data`) no longer promises a decimal width that a server-side `sum` / `avg` does not deliver + +Clause-②: no + +- The `number` paragraph said a computed result over a column with no fixed width rounds to the widest decimal count among the values that entered it. That holds only where the renderer sees those values: the grid summary footer, and the `object-metric` tile's `min` / `max`. +- A server-side `sum` / `avg` over a `number` that declares no `scale` does not get that width yet. The tile receives one number, and the analytics result's column metadata (`AnalyticsResultResponseSchema`) carries `format` / `currency` / `percentScale` and no width. The `object-metric` tile shows that answer as a whole number. With no measure `format`, the dataset-bound tile prints an integer as it is and rounds any other value to at most two decimals. +- The docblock now records the ruled end-state: the analytics result reports the width, either the widest decimal count among the values the server read or the field's declared `scale`. It also records the trigger that starts the build: the first first-party `object-metric` tile or dataset measure doing `sum` / `avg` over such a field with no `format`. +- Until then, an author who needs decimals there declares a field `scale` (the `object-metric` tile reads it) or a `format`: the `object-metric` tile's own, or the dataset measure's. +- ⛔ No schema, parse, export, key or runtime change. diff --git a/packages/spec/src/data/field-scale.ts b/packages/spec/src/data/field-scale.ts index 53b1946930c..d3e46411282 100644 --- a/packages/spec/src/data/field-scale.ts +++ b/packages/spec/src/data/field-scale.ts @@ -68,7 +68,31 @@ * private `?? 0` and read the width through {@link resolveFieldScale}, and a * computed result over a no-fixed-width column rounds to the widest decimal * count among the values that entered it — derived from the data, ⛔ never a - * constant. Grouping is not this key's to decide: + * constant. That rule binds TODAY only the computed results whose inputs the + * renderer sees: the grid summary footer, which computes over the rows it + * holds, and the `object-metric` tile's `min` / `max`, whose answer is itself + * one of those inputs. A server-side `sum` / `avg` is not one of them: the + * tile receives one number, and `AnalyticsResultResponseSchema`'s column + * metadata (`@objectstack/spec/api`) carries `format` / `currency` / + * `percentScale` and no width. So a `sum` / `avg` over a `number` with no + * declared `scale` does NOT yet show the width this rule derives — measured + * at `.objectui-sha` pin `89cad75d5570`, the `object-metric` tile still shows + * it as a whole number, and the dataset-bound tile, given no measure + * `format`, prints an integer answer as it is and rounds any other to at + * most two decimals. The end-state is ruled (maintainer ruling 5933283974 on + * objectui#11254, batch 261 item 4, letter A deferred, 「其他四张同意」): the + * analytics result REPORTS the width — its column metadata carries the + * widest decimal count among the values the server read, or the field's + * declared `scale` when there is one — and the tile rounds to that. Nothing + * is built before its trigger, the first first-party producer: an + * `object-metric` tile or dataset measure doing `sum` / `avg` over a `number` + * that declares no `scale` and whose author wrote no `format`. Then A is + * built in one go, with no new decision. Until then an author who needs + * decimals there has two declared channels: the field's `scale`, which the + * `object-metric` tile reads through {@link resolveFieldScale}, or a + * `format` — the `object-metric` tile's own, or on a dataset-bound tile the + * measure's, the only channel that reaches that face while its column + * metadata has no width member. Grouping is not this key's to decide: * `FieldSchema.useGrouping` decides, and the renderer's interim heuristic * for an absent `useGrouping` reads the DECLARED `scale` only — a declared * `scale: 0` marks a discrete integer (a year, a fiscal period, an ordinal) From 97a757c2162d44ea4b86c4d340b50d8ab2bc4acb Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 2 Oct 2026 17:46:46 +0000 Subject: [PATCH 2/2] chore(changeset): drop the spec patch changeset; the edited docblock ships in no published file Measured after `pnpm --filter @objectstack/spec build`: the module docblock of `src/data/field-scale.ts` reaches none of the paths in spec's `files[]` (`dist`, `json-schema`, `liveness`, `prompts`, `llms.txt`, `README.md`, `src/**/*.zod.ts`, `api-surface`, `spec-changes.json`). The new text, and the pre-existing module docblock text, both hit 0 files; the positive control, the TSDoc on `resolveFieldScale` itself, hits `dist/data/index.d.ts` and `index.d.mts`. A diff that publishes nothing takes `skip-changeset`. Claude-Session: https://claude.ai/code/session_01UtnxvdiN376GF3sgXwAw4d Co-authored-by: Claude --- .../21183-field-scale-server-aggregate-width.md | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 .changeset/21183-field-scale-server-aggregate-width.md diff --git a/.changeset/21183-field-scale-server-aggregate-width.md b/.changeset/21183-field-scale-server-aggregate-width.md deleted file mode 100644 index 1f834be80b8..00000000000 --- a/.changeset/21183-field-scale-server-aggregate-width.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@objectstack/spec": patch ---- - -`resolveFieldScale`'s module docblock (`@objectstack/spec/data`) no longer promises a decimal width that a server-side `sum` / `avg` does not deliver - -Clause-②: no - -- The `number` paragraph said a computed result over a column with no fixed width rounds to the widest decimal count among the values that entered it. That holds only where the renderer sees those values: the grid summary footer, and the `object-metric` tile's `min` / `max`. -- A server-side `sum` / `avg` over a `number` that declares no `scale` does not get that width yet. The tile receives one number, and the analytics result's column metadata (`AnalyticsResultResponseSchema`) carries `format` / `currency` / `percentScale` and no width. The `object-metric` tile shows that answer as a whole number. With no measure `format`, the dataset-bound tile prints an integer as it is and rounds any other value to at most two decimals. -- The docblock now records the ruled end-state: the analytics result reports the width, either the widest decimal count among the values the server read or the field's declared `scale`. It also records the trigger that starts the build: the first first-party `object-metric` tile or dataset measure doing `sum` / `avg` over such a field with no `format`. -- Until then, an author who needs decimals there declares a field `scale` (the `object-metric` tile reads it) or a `format`: the `object-metric` tile's own, or the dataset measure's. -- ⛔ No schema, parse, export, key or runtime change.