Skip to content

spec: declare the aggregate × field-type compatibility matrix (AggregationFunction × FieldType) that dataset measures are refused against (spec half of #16099) #16353

Description

@os-zhuang

Spec half of #16099, split by director ruling (decision batch #59, 2026-09-06, "both legs, table in spec"). The two consumer legs — compile-time refusal in dataset-compiler (#16099 itself, services) and an authoring-time lint rule (devx sub-card) — are pm:blocked on this card and consume this one table.

Why

A dataset measure pairing avg with a Field.datetime compiles to AVG(col) and reaches the backend: SQLite renders a mean of epoch milliseconds, Postgres fails with 42883. Nothing between author and driver correlates aggregate with the field's type. Which pairs are accepted is a narrowing of a published acceptance set, so it is a contract, declared once in @objectstack/spec and executed by both legs.

Scope

  • Export a compatibility table from the spec (next to AggregationFunction / DatasetMeasureSchema), e.g. AGGREGATE_FIELD_TYPE_COMPATIBILITY: Record<AggregationFunction, readonly FieldType[]> plus a predicate isAggregateCompatibleWithFieldType(aggregate, fieldType).
  • Starting rows (director's ruling; the spec seat finalises against the full FieldType membership):
    • count, countDistinct: any type
    • sum: numeric types only (number, currency, integer-class) — excludes percent (analytics-service.ts already calls that pair incoherent)
    • avg: numeric types including percent
    • min, max: numeric types plus temporal (date, datetime)
    • every other pair: refused
  • TSDoc states the rule and the reason (backend-divergent results, Prime Directive Add comprehensive test suite for Zod schema validation #12).
  • Clause-② conformance limb: yes (a previously accepted authoring shape becomes refused once the consumers land) — carry needs:contract-review on the landing PR; changeset states the narrowing.

Out of scope

Acceptance

  • table and predicate exported and pinned in the api-surface baselines
  • every AggregationFunction member has a row; every FieldType member is classified
  • changeset present

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions