Found while working on #16042 (the AnalyticsQuery.timezone repair in the same function's file). ⛔ Deliberately NOT fixed there — that card's fence was dateRange, and this is a different field with a different consumer. Refs #16042, #15825.
The shape
AnalyticsQuery.timeDimensions[].granularity is declared by the spec (packages/spec/src/data/analytics.zod.ts:324, granularity: TimeUpdateInterval.optional()), and a cube dimension declares which granularities it offers (granularities: ['day']). packages/drivers/driver-memory/src/memory-analytics.ts never reads either.
Measured on origin/main @ 1328902ce:
git grep -c 'granularity' -- packages/drivers/driver-memory/src/memory-analytics.ts
(0 hits)
Positive control on the same file in the same session: git grep -c 'dateRange' returns 4, and git grep -c 'timeDimensions' returns 1. So the zero is a real absence, not a broken grep.
Measured through the public entry, against the BUILT package
Two rows on the same UTC calendar day, grouped by the time dimension with granularity: 'day':
rows: 2026-09-06T01:00:00.000Z, 2026-09-06T23:00:00.000Z
query: dimensions: ['events.createdAt'],
timeDimensions: [{ dimension: 'events.createdAt', granularity: 'day' }]
result: [ {events.createdAt: '2026-09-06T01:00:00.000Z', events.count: 1},
{events.createdAt: '2026-09-06T23:00:00.000Z', events.count: 1} ]
⇒ two groups, not one. The $group stage keys on the raw field path (memory-analytics.ts:786, groupStage._id[dimName] = '$' + fieldPath), so a time dimension buckets one group per distinct timestamp — one bar per row in a "new accounts by month" chart, which is the exact symptom #3588 catalogued and repaired for service-analytics.
Why this is a card and not "unimplemented"
Same declared-≠-enforced shape as #16042, one field over: the schema declares the knob, the cube metadata enumerates the granularities a dimension offers, and this implementation quietly drops both. The request is accepted, no warning is emitted, and the answer is silently ungrouped.
The other implementations do read it — service-analytics' preview-evaluator.ts:215 calls bucketDate(raw, gran, timezone), and objectql's engine.ts routes a non-UTC reference timezone to applyInMemoryAggregation(raw, ast, tz) precisely so bucketing stays uniform. ⚠️ I measured that they READ it; I did not verify they bucket correctly.
Note this is orthogonal to #16042, which repaired the dateRange WINDOW (which rows are selected). This is the GROUPING (how selected rows are folded). #16042 changes no grouping behaviour.
Prior art already in the tree
bucketDate(value, granularity, timezone) in packages/services/service-analytics/src/preview-evaluator.ts:129 is the whole rule, and it already takes the reference timezone — so a repair here would want #16042's resolution rather than a second dialect.
Unlabelled on purpose: routing, domain:*, type and priority belong to triage.
Generated by Claude Code
Found while working on #16042 (the
AnalyticsQuery.timezonerepair in the same function's file). ⛔ Deliberately NOT fixed there — that card's fence wasdateRange, and this is a different field with a different consumer. Refs #16042, #15825.The shape
AnalyticsQuery.timeDimensions[].granularityis declared by the spec (packages/spec/src/data/analytics.zod.ts:324,granularity: TimeUpdateInterval.optional()), and a cube dimension declares which granularities it offers (granularities: ['day']).packages/drivers/driver-memory/src/memory-analytics.tsnever reads either.Measured on
origin/main@1328902ce:Positive control on the same file in the same session:
git grep -c 'dateRange'returns 4, andgit grep -c 'timeDimensions'returns 1. So the zero is a real absence, not a broken grep.Measured through the public entry, against the BUILT package
Two rows on the same UTC calendar day, grouped by the time dimension with
granularity: 'day':⇒ two groups, not one. The
$groupstage keys on the raw field path (memory-analytics.ts:786,groupStage._id[dimName] = '$' + fieldPath), so a time dimension buckets one group per distinct timestamp — one bar per row in a "new accounts by month" chart, which is the exact symptom #3588 catalogued and repaired forservice-analytics.Why this is a card and not "unimplemented"
Same declared-≠-enforced shape as #16042, one field over: the schema declares the knob, the cube metadata enumerates the granularities a dimension offers, and this implementation quietly drops both. The request is accepted, no warning is emitted, and the answer is silently ungrouped.
The other implementations do read it —⚠️ I measured that they READ it; I did not verify they bucket correctly.
service-analytics'preview-evaluator.ts:215callsbucketDate(raw, gran, timezone), andobjectql'sengine.tsroutes a non-UTC reference timezone toapplyInMemoryAggregation(raw, ast, tz)precisely so bucketing stays uniform.Note this is orthogonal to #16042, which repaired the
dateRangeWINDOW (which rows are selected). This is the GROUPING (how selected rows are folded). #16042 changes no grouping behaviour.Prior art already in the tree
bucketDate(value, granularity, timezone)inpackages/services/service-analytics/src/preview-evaluator.ts:129is the whole rule, and it already takes the reference timezone — so a repair here would want #16042's resolution rather than a second dialect.Unlabelled on purpose: routing,
domain:*, type and priority belong to triage.Generated by Claude Code