Context
ADR-0021 report drill-down (objectui#1649) scopes the destination object list with equality filters (?filter[field]=value → ObjectQL triple [field, '=', value]).
A dimension with dateGranularity (e.g. created_date bucketed by month/quarter/day) groups rows into a time bucket, not a single value. Drilling into the "2026-Q2" bucket should open every record whose close_date falls in that quarter — a range (>= start AND < end), which the equality contract can't express.
Current behavior: objectui's ReportView.handleDatasetDrill skips granularity-bucketed dimensions, so the drill lands on a superset (correct rows included, but not scoped to the bucket). This is now the common case for the matrix "X by time" reports (e.g. hotcrm pipeline_coverage_by_quarter, cases_opened_by_day_priority — see hotcrm#382).
Proposal
Two pieces:
- A bucket→range mapping for each granularity (day/week/month/quarter/year →
[bucketStart, nextBucketStart)). Natural home is shared spec/analytics util so server and client agree on bucket boundaries.
- A drill filter contract that carries a range, e.g.
?filter[close_date][gte]=...&filter[close_date][lt]=..., consumed by the object list's URL-filter parser (ObjectView urlFilters, currently equality-only).
Affected
- framework: granularity bucket-boundary util (analytics or spec)
- objectui:
ObjectView urlFilters parser (add range ops) + ReportView.handleDatasetDrill (emit a range for granularity dims instead of skipping)
Found during the ADR-0021 report epic.
Context
ADR-0021 report drill-down (objectui#1649) scopes the destination object list with equality filters (
?filter[field]=value→ ObjectQL triple[field, '=', value]).A dimension with
dateGranularity(e.g.created_datebucketed by month/quarter/day) groups rows into a time bucket, not a single value. Drilling into the "2026-Q2" bucket should open every record whoseclose_datefalls in that quarter — a range (>= start AND < end), which the equality contract can't express.Current behavior: objectui's
ReportView.handleDatasetDrillskips granularity-bucketed dimensions, so the drill lands on a superset (correct rows included, but not scoped to the bucket). This is now the common case for the matrix "X by time" reports (e.g. hotcrmpipeline_coverage_by_quarter,cases_opened_by_day_priority— see hotcrm#382).Proposal
Two pieces:
[bucketStart, nextBucketStart)). Natural home is shared spec/analytics util so server and client agree on bucket boundaries.?filter[close_date][gte]=...&filter[close_date][lt]=..., consumed by the object list's URL-filter parser (ObjectViewurlFilters, currently equality-only).Affected
ObjectViewurlFilters parser (add range ops) +ReportView.handleDatasetDrill(emit a range for granularity dims instead of skipping)Found during the ADR-0021 report epic.