Skip to content

feat(analytics): server-side totals for matrix reports (subtotals + grand total)#1779

Merged
os-zhuang merged 3 commits into
mainfrom
feat/matrix-server-side-totals
Jun 12, 2026
Merged

feat(analytics): server-side totals for matrix reports (subtotals + grand total)#1779
os-zhuang merged 3 commits into
mainfrom
feat/matrix-server-side-totals

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

Closes #1753.

What

queryDataset selections now accept a totals option:

selection.totals = { groupings: [rowDims, columnDims, []] }  // [] = grand total

Each grouping is a subset of selection.dimensions; the DatasetExecutor re-runs the full selection grouped only by those dimensions and returns the marginal aggregates on AnalyticsResult.totals (one entry per grouping, in request order, same measure columns as the primary rows).

Why explicit groupings

The server sees a flat dimensions array — it cannot infer the matrix's rows/columns split, so the caller names the marginals it wants. A matrix report asks for per-row subtotals (group by row dims), per-column subtotals (group by column dims), and the grand total ([]).

Design notes

  • True aggregates, not re-aggregation. Each totals query goes through the same executor pipeline as the primary grid, so an avg total is the average over all underlying rows (not an average of bucket averages) and count_distinct stays correct — the ADR-0021 governance line that made the client renderer refuse to invent totals.
  • Measure-scoped filters, derived measures, and compareTo all apply to totals identically (the pipeline is reused, not duplicated).
  • order/limit/offset are dropped for totals queries — totals cover the full selection, and an order key may reference a dimension the grouping drops.
  • Dimension display labels (select option labels, lookup record names, date buckets) resolve on totals rows the same way as primary rows.
  • A grouping that isn't a subset of the selected dimensions is rejected with a clear error.
  • Works unchanged through the ADR-0037 draft-preview path (previewDrafts) — the in-memory evaluator already handles dimensionless queries.
  • The REST POST /analytics/dataset/query endpoint passes the selection through verbatim, so no endpoint changes were needed.

Consumer follow-up

objectui's DatasetMatrixTable (packages/plugin-report/src/DatasetReportRenderer.tsx) can now request totals: { groupings: [rows, columns, []] } and render the supplied totals row/column — tracked as the consumer half of #1753.

🤖 Generated with Claude Code

os-zhuang and others added 2 commits June 12, 2026 15:15
fix(app-shell): NavigationSyncEffect baseline race — readiness gate, sys_ filter, ADR-0010 lock filter (#1668)

objectui@e95cc25b2c0d2fa680e232151721e71c19630659
queryDataset selections accept totals.groupings — dimension subsets the
executor re-runs the full selection against (measure-scoped filters,
derived measures, compareTo included), returning marginal aggregates on
AnalyticsResult.totals. Each subtotal/grand total is the measure's true
aggregate over the underlying rows, never re-derived from bucketed
values (ADR-0021 governance line). Dimension display labels resolve on
totals rows the same way as the primary grid.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 12, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 12, 2026 10:54am

Request Review

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@github-actions github-actions Bot added documentation Improvements or additions to documentation tooling labels Jun 12, 2026
xuyushun441-sys added a commit to objectstack-ai/objectui that referenced this pull request Jun 12, 2026
…#1669)

Framework PR objectstack-ai/objectstack#1779 (issue #1753) added
server-side totals to queryDataset. The matrix renderer now requests
totals: { groupings: [rows, columns, []] } and renders the returned
pre-aggregated rows: a trailing Total column per measure (row
subtotals), a trailing Total row (column subtotals), and the grand
total at their intersection — matched to pivot headers via the same
bucketId logic. No totals in the response (older server) renders
exactly as before; the client never re-aggregates (ADR-0021).

Co-authored-by: Jack Zhuang <277994282+os-zhuang@users.noreply.github.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
@os-zhuang
os-zhuang merged commit 6c7a8d7 into main Jun 12, 2026
12 checks passed
@os-zhuang
os-zhuang deleted the feat/matrix-server-side-totals branch June 12, 2026 15:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Matrix reports: server-side totals row/column (subtotals + grand total)

2 participants