Skip to content

Commit 2b56571

Browse files
os-zhuangclaude
andauthored
fix(reports): split matrix reports to rows × columns (ADR-0021 D2) (#382)
The four matrix reports flattened their across-dimension into `rows` (the pre-9.1 stopgap, which the dataset renderer degraded to a flat grouped table). spec 9.1 added `Report.columns` for the true cross-tab axis, so move the second dimension into `columns`: - accounts_by_industry_type: industry × type - lead_inflow_by_month_source: lead_source × last_contacted_date - cases_opened_by_day_priority: priority × created_date - pipeline_coverage_by_quarter: forecast_category × close_date The two summary reports keep their multi-level `rows` (legit down-axis nesting, no across). Refresh three doc comments that referenced the retired `groupingsDown`/`groupingsAcross` fields. Bumps @objectstack/spec to ^9.2.0 (the `columns` field landed in 9.1). Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
1 parent a67f1e7 commit 2b56571

6 files changed

Lines changed: 27 additions & 12 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636
"@objectstack/runtime": "^9.0.0",
3737
"@objectstack/service-analytics": "^9.0.0",
3838
"@objectstack/service-automation": "^9.0.0",
39-
"@objectstack/spec": "^9.0.0"
39+
"@objectstack/spec": "^9.2.0"
4040
},
4141
"optionalDependencies": {
4242
"better-sqlite3": "^12.10.0"

pnpm-lock.yaml

Lines changed: 17 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/reports/account.report.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ export const AccountsByIndustryTypeReport: ReportInput = {
66
name: 'accounts_by_industry_type',
77
label: 'Accounts by Industry and Type',
88
description: 'Matrix report showing accounts by industry and type',
9-
dataset: 'account_metrics', rows: ['industry', 'type'], values: ['account_count', 'annual_revenue_sum'],
9+
dataset: 'account_metrics', rows: ['industry'], columns: ['type'], values: ['account_count', 'annual_revenue_sum'],
1010
type: 'matrix',
1111
runtimeFilter: { is_active: true },
1212
};

src/reports/case.report.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,6 @@ export const CasesOpenedByDayPriorityReport: ReportInput = {
3131
name: 'cases_opened_by_day_priority',
3232
label: 'Cases Opened by Priority × Day',
3333
description: 'Daily case inflow split by priority',
34-
dataset: 'case_metrics', rows: ['priority', 'created_date'], values: ['case_count'],
34+
dataset: 'case_metrics', rows: ['priority'], columns: ['created_date'], values: ['case_count'],
3535
type: 'matrix',
3636
};

src/reports/lead.report.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,6 @@ export const LeadInflowByMonthSourceReport: ReportInput = {
1313
name: 'lead_inflow_by_month_source',
1414
label: 'Lead Engagement by Month × Source',
1515
description: 'Contacted-lead volume per month, broken down by acquisition channel',
16-
dataset: 'lead_metrics', rows: ['lead_source', 'last_contacted_date'], values: ['lead_count'],
16+
dataset: 'lead_metrics', rows: ['lead_source'], columns: ['last_contacted_date'], values: ['lead_count'],
1717
type: 'matrix',
1818
};

src/reports/opportunity.report.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,23 @@ export const WonOpportunitiesByOwnerReport: ReportInput = {
3030
/**
3131
* Quarterly pipeline coverage — the matrix view that powers the classic
3232
* sales-ops "pipeline coverage" conversation: each forecast category against
33-
* the quarter the deal is expected to close in. Uses the spec's
34-
* `dateGranularity` on `groupingsAcross` so the server can bucket close_date
35-
* into quarters in a single aggregate query.
33+
* the quarter the deal is expected to close in. `close_date` is the across
34+
* dimension (`columns`); the dataset's `dateGranularity` buckets it into
35+
* quarters in a single server-side aggregate query.
3636
*/
3737
export const PipelineCoverageByQuarterReport: ReportInput = {
3838
name: 'pipeline_coverage_by_quarter',
3939
label: 'Pipeline Coverage by Forecast × Quarter',
4040
description: 'Open pipeline amount by forecast category, bucketed by close quarter',
41-
dataset: 'opportunity_metrics', rows: ['forecast_category', 'close_date'], values: ['total_amount', 'opp_count'],
41+
dataset: 'opportunity_metrics', rows: ['forecast_category'], columns: ['close_date'], values: ['total_amount', 'opp_count'],
4242
type: 'matrix',
4343
runtimeFilter: { stage: { $nin: ['closed_won', 'closed_lost'] } },
4444
};
4545

4646
/**
4747
* Sales-rep funnel — two-level summary that mirrors how reps drill into their
48-
* own book of business. Tests the multi-level `groupingsDown` rendering and
49-
* the `aggregate`-mixed-with-`detail` column pattern.
48+
* own book of business. Exercises multi-level `rows` grouping (owner → stage)
49+
* over the dataset's measures.
5050
*/
5151
export const OpportunityFunnelByOwnerStageReport: ReportInput = {
5252
name: 'opportunity_funnel_owner_stage',

0 commit comments

Comments
 (0)