From 1673bcff3c2d53d67a761d121c674e3c6a65c0f1 Mon Sep 17 00:00:00 2001 From: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com> Date: Sat, 25 Jul 2026 10:46:36 +0800 Subject: [PATCH] feat(spec)!: prune dead ReportColumnSchema/ReportGroupingSchema exports + unread report chart groupBy (#3463) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Deep-cleanup close-out of the report-chart disposition (follow-up to #3441, umbrella #1878/#1890). After the ADR-0021 single-form cutover a dataset-bound report expresses columns/grouping as dataset measure/dimension name arrays (`values`/`rows`/`columns` = `z.array(z.string())`), so ReportColumnSchema / ReportGroupingSchema were referenced by no schema body — they survived only as public type exports and were marked @deprecated in #3441. - Remove ReportColumnSchema / ReportGroupingSchema and their type exports (ReportColumn / ReportGrouping / ReportColumnInput / ReportGroupingInput) from @objectstack/spec/ui; drop the now-orphan ResponsiveConfigSchema import. - Remove ReportChart.groupBy — the [EXPERIMENTAL — not enforced] series-split field from #3441. The dataset-bound DatasetReportRenderer plots a single xAxis×yAxis series and never read it; only the retired legacy ReportViewer fallback consumed a top-level groupBy. ReportChartSchema is non-strict, so residual chart.groupBy in stored metadata is silently stripped on parse. - Drop manifest ratchet keys ui/ReportColumn, ui/ReportGrouping; regenerate content/docs/references/ui/report.mdx and the spec API-surface snapshot. No first-party or example report authored these objects or chart.groupBy. Ships as minor per the launch-window breaking-as-minor policy; changeset carries the FROM→TO migration. Co-Authored-By: Claude Fable 5 --- .../prune-report-column-grouping-schemas.md | 38 ++++++++++++++++ content/docs/references/ui/report.mdx | 32 +------------- packages/spec/api-surface.json | 6 --- packages/spec/json-schema.manifest.json | 2 - packages/spec/src/ui/report.zod.ts | 44 +------------------ 5 files changed, 41 insertions(+), 81 deletions(-) create mode 100644 .changeset/prune-report-column-grouping-schemas.md diff --git a/.changeset/prune-report-column-grouping-schemas.md b/.changeset/prune-report-column-grouping-schemas.md new file mode 100644 index 000000000..b9bb56d36 --- /dev/null +++ b/.changeset/prune-report-column-grouping-schemas.md @@ -0,0 +1,38 @@ +--- +"@objectstack/spec": minor +--- + +feat(spec)!: prune the dead `ReportColumnSchema`/`ReportGroupingSchema` exports + the unread report chart `groupBy` (#3463, #1878/#1890) + +Deep-cleanup close-out of the report-chart disposition (follow-up to #3441). +After the ADR-0021 single-form cutover a dataset-bound report expresses its +columns/grouping as dataset **measure/dimension name arrays** — `values`, +`rows` and `columns` are `z.array(z.string())`, not object literals — so +`ReportColumnSchema` / `ReportGroupingSchema` were referenced by **no schema +body**. They survived only as public type exports and were marked +`@deprecated` in #3441; this removes them. + +- Deleted `ReportColumnSchema` / `ReportGroupingSchema` and their type + exports `ReportColumn` / `ReportGrouping` / `ReportColumnInput` / + `ReportGroupingInput` from `@objectstack/spec/ui`. The manifest ratchet + keys `ui/ReportColumn` / `ui/ReportGrouping` are dropped in the same PR. +- Deleted `ReportChart.groupBy` — the `[EXPERIMENTAL — not enforced]` + series-split field flagged in #3441. The dataset-bound `DatasetReportRenderer` + plots a single `xAxis`×`yAxis` series and never read it; only the retired + legacy `ReportViewer` fallback ever consumed a top-level `groupBy`. + `ReportChartSchema` is non-strict, so any residual `chart.groupBy` in stored + metadata is silently stripped on parse — no tombstone needed. +- Regenerated `content/docs/references/ui/report.mdx` and the spec API-surface + snapshot. + +**Migration**: nothing an author writes changes. +- No first-party or example report authored `ReportColumn` / `ReportGrouping` + objects or `chart.groupBy` — a dataset-bound report already expresses + columns as `values` (measure names) and grouping as `rows` / `columns` + (dimension names). +- TypeScript consumers importing `ReportColumn` / `ReportGrouping` / + `ReportColumnInput` / `ReportGroupingInput` (or the `*Schema` values) from + `@objectstack/spec/ui` have no replacement type — model report columns as + the dataset's measure names and grouping as its dimension names. objectui's + `SpecReportColumn*` / `SpecReportGrouping*` re-exports are removed in the + companion objectui change. diff --git a/content/docs/references/ui/report.mdx b/content/docs/references/ui/report.mdx index 70c9ba36f..8688e53b4 100644 --- a/content/docs/references/ui/report.mdx +++ b/content/docs/references/ui/report.mdx @@ -14,8 +14,8 @@ Report Type Enum ## TypeScript Usage ```typescript -import { JoinedReportBlock, Report, ReportChart, ReportColumn, ReportGrouping, ReportType } from '@objectstack/spec/ui'; -import type { JoinedReportBlock, Report, ReportChart, ReportColumn, ReportGrouping, ReportType } from '@objectstack/spec/ui'; +import { JoinedReportBlock, Report, ReportChart, ReportType } from '@objectstack/spec/ui'; +import type { JoinedReportBlock, Report, ReportChart, ReportType } from '@objectstack/spec/ui'; // Validate data const result = JoinedReportBlock.parse(data); @@ -95,34 +95,6 @@ const result = JoinedReportBlock.parse(data); | **annotations** | `{ type: Enum<'line' \| 'region'>; axis: Enum<'x' \| 'y'>; value: number \| string; endValue?: number \| string; … }[]` | optional | | | **interaction** | `{ tooltips: boolean; zoom: boolean; brush: boolean; clickAction?: string }` | optional | | | **aria** | `{ ariaLabel?: string; ariaDescribedBy?: string; role?: string }` | optional | ARIA accessibility attributes | -| **groupBy** | `string` | optional | [EXPERIMENTAL — not enforced] Additional series-split grouping; not read by the dataset-bound report renderer (liveness #1878/#1890) | - - ---- - -## ReportColumn - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **field** | `string` | ✅ | Field name | -| **label** | `string` | optional | Override label | -| **aggregate** | `Enum<'sum' \| 'avg' \| 'max' \| 'min' \| 'count' \| 'unique'>` | optional | Aggregation function | -| **responsive** | `{ breakpoint?: Enum<'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'>; hiddenOn?: Enum<'xs' \| 'sm' \| 'md' \| 'lg' \| 'xl' \| '2xl'>[]; columns?: object; order?: object }` | optional | Responsive visibility for this column | - - ---- - -## ReportGrouping - -### Properties - -| Property | Type | Required | Description | -| :--- | :--- | :--- | :--- | -| **field** | `string` | ✅ | Field to group by | -| **sortOrder** | `Enum<'asc' \| 'desc'>` | ✅ | | -| **dateGranularity** | `Enum<'day' \| 'week' \| 'month' \| 'quarter' \| 'year'>` | optional | For date fields | --- diff --git a/packages/spec/api-surface.json b/packages/spec/api-surface.json index e10cd9d3c..f98dfdcb1 100644 --- a/packages/spec/api-surface.json +++ b/packages/spec/api-surface.json @@ -3371,12 +3371,6 @@ "ReportChart (type)", "ReportChartInput (type)", "ReportChartSchema (const)", - "ReportColumn (type)", - "ReportColumnInput (type)", - "ReportColumnSchema (const)", - "ReportGrouping (type)", - "ReportGroupingInput (type)", - "ReportGroupingSchema (const)", "ReportInput (type)", "ReportNavItem (type)", "ReportNavItemSchema (const)", diff --git a/packages/spec/json-schema.manifest.json b/packages/spec/json-schema.manifest.json index 1f216ddd5..0af0962fa 100644 --- a/packages/spec/json-schema.manifest.json +++ b/packages/spec/json-schema.manifest.json @@ -1751,8 +1751,6 @@ "ui/RecordRelatedListProps", "ui/Report", "ui/ReportChart", - "ui/ReportColumn", - "ui/ReportGrouping", "ui/ReportNavItem", "ui/ReportType", "ui/ResponsiveConfig", diff --git a/packages/spec/src/ui/report.zod.ts b/packages/spec/src/ui/report.zod.ts index 6e5ace9c7..db88acba9 100644 --- a/packages/spec/src/ui/report.zod.ts +++ b/packages/spec/src/ui/report.zod.ts @@ -7,7 +7,7 @@ import { FilterConditionSchema } from '../data/filter.zod'; import { ChartConfigSchema } from './chart.zod'; import { SnakeCaseIdentifierSchema } from '../shared/identifiers.zod'; import { I18nLabelSchema, AriaPropsSchema } from './i18n.zod'; -import { ResponsiveConfigSchema, PerformanceConfigSchema } from './responsive.zod'; +import { PerformanceConfigSchema } from './responsive.zod'; /** * Report Type Enum @@ -20,37 +20,6 @@ export const ReportType = z.enum([ 'joined' // Joined multiple blocks ]); -/** - * Report Column Schema - * - * @deprecated Unreferenced by the single-form (ADR-0021) report shape — a - * dataset-bound report selects `values` (measure names) and `rows`/`columns` - * (dimension names) as `z.array(z.string())`, not `ReportColumn` objects. Kept - * only as a public type export (objectui re-exports it as `SpecReportColumn`); - * slated for removal in a future governed prune (liveness #1878/#1890). - */ -export const ReportColumnSchema = lazySchema(() => z.object({ - field: z.string().describe('Field name'), - label: I18nLabelSchema.optional().describe('Override label'), - aggregate: z.enum(['sum', 'avg', 'max', 'min', 'count', 'unique']).optional().describe('Aggregation function'), - /** Responsive visibility/priority per breakpoint */ - responsive: ResponsiveConfigSchema.optional().describe('Responsive visibility for this column'), -})); - -/** - * Report Grouping Schema - * - * @deprecated Unreferenced by the single-form (ADR-0021) report shape — - * grouping is expressed by dataset dimension names in `rows`/`columns`. Kept - * only as a public type export (objectui re-exports it as `SpecReportGrouping`); - * slated for removal in a future governed prune (liveness #1878/#1890). - */ -export const ReportGroupingSchema = lazySchema(() => z.object({ - field: z.string().describe('Field to group by'), - sortOrder: z.enum(['asc', 'desc']).default('asc'), - dateGranularity: z.enum(['day', 'week', 'month', 'quarter', 'year']).optional().describe('For date fields'), -})); - /** * Report Chart Schema * @@ -64,13 +33,6 @@ export const ReportChartSchema = lazySchema(() => ChartConfigSchema.extend({ xAxis: z.string().describe('Dataset dimension name for the X-axis (bound-dataset dimension, not a raw field)'), /** Dataset **measure** name for the Y-axis (from the report's bound dataset). */ yAxis: z.string().describe('Dataset measure name for the Y-axis (bound-dataset measure, not a raw field)'), - /** - * ⚠️ EXPERIMENTAL — NOT ENFORCED (liveness #1878/#1890). An additional - * series-split grouping. The dataset-bound `DatasetReportRenderer` plots a - * single `xAxis`×`yAxis` series and does not read this; only the legacy - * `ReportViewer` fallback consumed a top-level `groupBy`. - */ - groupBy: z.string().optional().describe('[EXPERIMENTAL — not enforced] Additional series-split grouping; not read by the dataset-bound report renderer (liveness #1878/#1890)'), })); /** @@ -223,8 +185,6 @@ export type JoinedReportBlockInput = z.input; * which allow optional fields with defaults to be omitted. */ export type Report = z.infer; -export type ReportColumn = z.infer; -export type ReportGrouping = z.infer; export type ReportChart = z.infer; /** @@ -232,8 +192,6 @@ export type ReportChart = z.infer; * Use these when defining reports in configuration files. */ export type ReportInput = z.input; -export type ReportColumnInput = z.input; -export type ReportGroupingInput = z.input; export type ReportChartInput = z.input; /**