Function: resolveColumnOrigin()
function resolveColumnOrigin(
definition: {
aggregations?: {
alias: string;
field?: string;
fn: "min" | "max" | "count" | "avg" | "sum";
}[];
columns: string[];
filter?: FilterNode;
groupBy?: {
bucket?: "year" | "month" | "day" | "week" | "quarter";
field: string;
}[];
schemaVersion: 1;
sort: {
by: string;
direction: "asc" | "desc";
}[];
subject: string;
timezone: string;
totals?: boolean;
},
key: string,
hasField: (fieldKey: string) => boolean
): ColumnOrigin;Defined in: shared/insights/validate-definition.ts:73
Resolve an output key (a columns entry or a sort.by) to its origin:
aggregation alias first, then groupBy output, then bare subject field.
This is THE resolution order — validateDefinition and the server compiler
both consume it, so a key can never validate as one origin and compile as
another. (Each previously hand-rolled the lookup and disagreed: a grouped
report selecting a bare field validated cleanly but threw at compile time,
and an aggregation alias shadowing a field key validated as the field but
compiled as the aggregate.)
Parameters
| Parameter | Type | Description |
|---|---|---|
definition | { aggregations?: { alias: string; field?: string; fn: "min" | "max" | "count" | "avg" | "sum"; }[]; columns: string[]; filter?: FilterNode; groupBy?: { bucket?: "year" | "month" | "day" | "week" | "quarter"; field: string; }[]; schemaVersion: 1; sort: { by: string; direction: "asc" | "desc"; }[]; subject: string; timezone: string; totals?: boolean; } | - |
definition.aggregations? | { alias: string; field?: string; fn: "min" | "max" | "count" | "avg" | "sum"; }[] | - |
definition.columns | string[] | The SELECT list — and the ONLY source of output columns, for grouped runs as much as detail runs: the compiler derives its projection from columns alone and never from groupBy/aggregations. So an empty columns has no compilable projection at all (not merely a semantically odd one), which makes it a STRUCTURAL failure and puts the check here rather than in validateDefinition. Keeping it in the schema also means every surface that parses a definition — run input, saved-report create/update, normalizeSavedReportDefinition on read, canned reports in the registry — fails closed without having to remember a second validation pass. |
definition.filter? | FilterNode | - |
definition.groupBy? | { bucket?: "year" | "month" | "day" | "week" | "quarter"; field: string; }[] | - |
definition.schemaVersion | 1 | - |
definition.sort | { by: string; direction: "asc" | "desc"; }[] | - |
definition.subject | string | - |
definition.timezone | string | - |
definition.totals? | boolean | - |
key | string | - |
hasField | (fieldKey: string) => boolean | - |