@dataworks-technology/cli 1.5.0 → 1.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude-plugin/marketplace.json +1 -1
- package/dist/generated/metrics.d.ts +10 -0
- package/dist/generated/metrics.d.ts.map +1 -1
- package/dist/generated/metrics.js +51 -0
- package/dist/generated/metrics.js.map +1 -1
- package/dist/lib/discover.d.ts +9 -3
- package/dist/lib/discover.d.ts.map +1 -1
- package/dist/lib/discover.js +43 -6
- package/dist/lib/discover.js.map +1 -1
- package/dist/lib/metric-names.d.ts +2 -2
- package/dist/lib/metric-names.d.ts.map +1 -1
- package/dist/lib/metric-names.js +2 -2
- package/dist/lib/metric-names.js.map +1 -1
- package/dist/lib/query-metrics.d.ts +40 -0
- package/dist/lib/query-metrics.d.ts.map +1 -1
- package/dist/lib/query-metrics.js +147 -15
- package/dist/lib/query-metrics.js.map +1 -1
- package/dist/mcp/server.d.ts +32 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +113 -8
- package/dist/mcp/server.js.map +1 -1
- package/oclif.manifest.json +159 -159
- package/package.json +1 -2
- package/plugins/dataworks/.claude-plugin/plugin.json +2 -2
- package/plugins/dataworks/.codex-plugin/plugin.json +3 -3
- package/{skills → plugins/dataworks/skills}/dataworks-cli/SKILL.md +13 -6
- package/plugins/dataworks/skills/query-dataworks-metrics/SKILL.md +48 -6
- /package/{skills → plugins/dataworks/skills}/dataworks-cli/agents/openai.yaml +0 -0
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
{
|
|
11
11
|
"name": "dataworks",
|
|
12
12
|
"source": "./plugins/dataworks",
|
|
13
|
-
"description": "Query Dataworks athlete metrics using the authenticated local CLI session"
|
|
13
|
+
"description": "Query Dataworks athlete metrics and operate the Dataworks platform using the authenticated local CLI session."
|
|
14
14
|
}
|
|
15
15
|
]
|
|
16
16
|
}
|
|
@@ -12,4 +12,14 @@ export declare const metricLabels: Record<string, string>;
|
|
|
12
12
|
export declare const allMetricNames: readonly string[];
|
|
13
13
|
/** Category lookup for a canonical metric name. */
|
|
14
14
|
export declare const metricCategoryByName: Record<string, MetricCategory>;
|
|
15
|
+
/**
|
|
16
|
+
* Columns the Data Explorer accepts per category. It allowlists the column names
|
|
17
|
+
* it will place in SQL, and silently ignores an aggregate naming anything else,
|
|
18
|
+
* so grouping and aggregate fields must be checked against this.
|
|
19
|
+
*/
|
|
20
|
+
export declare const metricColumns: {
|
|
21
|
+
METRICS_TYPE_A: string[];
|
|
22
|
+
METRICS_TYPE_B: string[];
|
|
23
|
+
METRICS_TYPE_C: string[];
|
|
24
|
+
};
|
|
15
25
|
//# sourceMappingURL=metrics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/generated/metrics.ts"],"names":[],"mappings":"AAGA,2DAA2D;AAC3D,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAEpF,iEAAiE;AACjE,eAAO,MAAM,gBAAgB;;;;CA4CwB,CAAC;AAEtD,sDAAsD;AACtD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsC/C,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAA2C,CAAC;AAExF,mDAAmD;AACnD,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAsC/D,CAAC"}
|
|
1
|
+
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../../src/generated/metrics.ts"],"names":[],"mappings":"AAGA,2DAA2D;AAC3D,MAAM,MAAM,cAAc,GAAG,gBAAgB,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;AAEpF,iEAAiE;AACjE,eAAO,MAAM,gBAAgB;;;;CA4CwB,CAAC;AAEtD,sDAAsD;AACtD,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAsC/C,CAAC;AAEF,uDAAuD;AACvD,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAA2C,CAAC;AAExF,mDAAmD;AACnD,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAsC/D,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,aAAa;;;;CA6C2B,CAAC"}
|
|
@@ -128,4 +128,55 @@ export const metricCategoryByName = {
|
|
|
128
128
|
"power-cycling": "METRICS_TYPE_C",
|
|
129
129
|
"pwr_instant": "METRICS_TYPE_C"
|
|
130
130
|
};
|
|
131
|
+
/**
|
|
132
|
+
* Columns the Data Explorer accepts per category. It allowlists the column names
|
|
133
|
+
* it will place in SQL, and silently ignores an aggregate naming anything else,
|
|
134
|
+
* so grouping and aggregate fields must be checked against this.
|
|
135
|
+
*/
|
|
136
|
+
export const metricColumns = {
|
|
137
|
+
"METRICS_TYPE_A": [
|
|
138
|
+
"timestamp",
|
|
139
|
+
"datasetdatasourcepublicid",
|
|
140
|
+
"eventpublicid",
|
|
141
|
+
"athletepublicid",
|
|
142
|
+
"metric",
|
|
143
|
+
"current"
|
|
144
|
+
],
|
|
145
|
+
"METRICS_TYPE_B": [
|
|
146
|
+
"timestamp",
|
|
147
|
+
"datasetdatasourcepublicid",
|
|
148
|
+
"eventpublicid",
|
|
149
|
+
"athletepublicid",
|
|
150
|
+
"metric",
|
|
151
|
+
"current",
|
|
152
|
+
"max",
|
|
153
|
+
"min",
|
|
154
|
+
"avg"
|
|
155
|
+
],
|
|
156
|
+
"METRICS_TYPE_C": [
|
|
157
|
+
"timestamp",
|
|
158
|
+
"datasetdatasourcepublicid",
|
|
159
|
+
"eventpublicid",
|
|
160
|
+
"athletepublicid",
|
|
161
|
+
"metric",
|
|
162
|
+
"current",
|
|
163
|
+
"max",
|
|
164
|
+
"min",
|
|
165
|
+
"avg",
|
|
166
|
+
"z1_timespent",
|
|
167
|
+
"z1_percentage",
|
|
168
|
+
"z2_timespent",
|
|
169
|
+
"z2_percentage",
|
|
170
|
+
"z3_timespent",
|
|
171
|
+
"z3_percentage",
|
|
172
|
+
"z4_timespent",
|
|
173
|
+
"z4_percentage",
|
|
174
|
+
"z5_timespent",
|
|
175
|
+
"z5_percentage",
|
|
176
|
+
"z6_timespent",
|
|
177
|
+
"z6_percentage",
|
|
178
|
+
"z7_timespent",
|
|
179
|
+
"z7_percentage"
|
|
180
|
+
]
|
|
181
|
+
};
|
|
131
182
|
//# sourceMappingURL=metrics.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/generated/metrics.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../src/generated/metrics.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/discover.d.ts
CHANGED
|
@@ -19,7 +19,11 @@ export interface AthleteSummary {
|
|
|
19
19
|
export interface EventSummary {
|
|
20
20
|
publicId: string;
|
|
21
21
|
name: string | null;
|
|
22
|
-
|
|
22
|
+
startsAt: string | null;
|
|
23
|
+
location: string | null;
|
|
24
|
+
type: string | null;
|
|
25
|
+
/** Dataset the event was reached through, when discovered that way. */
|
|
26
|
+
datasetPublicId?: string;
|
|
23
27
|
}
|
|
24
28
|
export interface DiscoverInput {
|
|
25
29
|
search?: string;
|
|
@@ -40,10 +44,12 @@ export interface EventListOutput {
|
|
|
40
44
|
search: string | null;
|
|
41
45
|
events: EventSummary[];
|
|
42
46
|
/**
|
|
43
|
-
* Set when
|
|
44
|
-
* as "no events exist"
|
|
47
|
+
* Set when listEvents returned null AND no events could be reached through
|
|
48
|
+
* datasets. Callers must not read that as "no events exist".
|
|
45
49
|
*/
|
|
46
50
|
unavailable: boolean;
|
|
51
|
+
/** Where the events came from: the events API, or the dataset relation. */
|
|
52
|
+
source: "events" | "datasets" | "none";
|
|
47
53
|
}
|
|
48
54
|
export declare function listAthletes(input?: DiscoverInput, options?: {
|
|
49
55
|
dependencies?: Partial<DiscoverDependencies>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/lib/discover.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,cAAc,CAAC;IAC/B,OAAO,EAAE,OAAO,cAAc,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,
|
|
1
|
+
{"version":3,"file":"discover.d.ts","sourceRoot":"","sources":["../../src/lib/discover.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,cAAc,CAAC;IAC/B,OAAO,EAAE,OAAO,cAAc,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,uEAAuE;IACvE,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,cAAc,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB;;;OAGG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB,2EAA2E;IAC3E,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;CACxC;AA2FD,wBAAsB,YAAY,CAChC,KAAK,GAAE,aAAkB,EACzB,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAA;CAAO,GAC7D,OAAO,CAAC,iBAAiB,CAAC,CAmC5B;AAED,wBAAsB,UAAU,CAC9B,KAAK,GAAE,aAAkB,EACzB,OAAO,GAAE;IAAE,YAAY,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAA;CAAO,GAC7D,OAAO,CAAC,eAAe,CAAC,CAqE1B"}
|
package/dist/lib/discover.js
CHANGED
|
@@ -16,7 +16,20 @@ const listAthletesDocument = `query listAthletes($limit: Int, $nextToken: String
|
|
|
16
16
|
}`;
|
|
17
17
|
const listEventsDocument = `query listEvents($limit: Int, $nextToken: String, $tenant: String!) {
|
|
18
18
|
listEvents(limit: $limit, nextToken: $nextToken, tenant: $tenant) {
|
|
19
|
-
items { publicId name
|
|
19
|
+
items { publicId name startsAt location type }
|
|
20
|
+
nextToken
|
|
21
|
+
}
|
|
22
|
+
}`;
|
|
23
|
+
/**
|
|
24
|
+
* Events reached through their datasets.
|
|
25
|
+
*
|
|
26
|
+
* listEvents currently returns null on this API, but every dataset exposes its
|
|
27
|
+
* event, so a race can still be identified by name rather than inferred from an
|
|
28
|
+
* ID prefix. Used only when the events API gives nothing.
|
|
29
|
+
*/
|
|
30
|
+
const datasetEventsDocument = `query listDatasets($limit: Int, $nextToken: String, $tenant: String!) {
|
|
31
|
+
listDatasets(limit: $limit, nextToken: $nextToken, tenant: $tenant) {
|
|
32
|
+
items { publicId name event { publicId name startsAt location type } }
|
|
20
33
|
nextToken
|
|
21
34
|
}
|
|
22
35
|
}`;
|
|
@@ -99,12 +112,35 @@ export async function listEvents(input = {}, options = {}) {
|
|
|
99
112
|
const dependencies = { ...defaultDependencies, ...options.dependencies };
|
|
100
113
|
try {
|
|
101
114
|
const tenantId = await resolveTenant(input, dependencies);
|
|
102
|
-
const
|
|
103
|
-
const all = items.map((event) => ({
|
|
115
|
+
const toSummary = (event, datasetPublicId) => ({
|
|
104
116
|
publicId: String(event.publicId),
|
|
105
117
|
name: event.name ?? null,
|
|
106
|
-
|
|
107
|
-
|
|
118
|
+
startsAt: event.startsAt ?? null,
|
|
119
|
+
location: event.location ?? null,
|
|
120
|
+
type: event.type ?? null,
|
|
121
|
+
...(datasetPublicId ? { datasetPublicId } : {}),
|
|
122
|
+
});
|
|
123
|
+
const direct = await collect(listEventsDocument, "listEvents", tenantId, dependencies);
|
|
124
|
+
let source = direct.unavailable ? "none" : "events";
|
|
125
|
+
let all = direct.items.map((event) => toSummary(event));
|
|
126
|
+
// The events API returns null on this deployment. Datasets still carry their
|
|
127
|
+
// event, so fall back rather than leaving the caller to infer an ID.
|
|
128
|
+
if (!all.length) {
|
|
129
|
+
const viaDatasets = await collect(datasetEventsDocument, "listDatasets", tenantId, dependencies);
|
|
130
|
+
const seen = new Set();
|
|
131
|
+
const derived = [];
|
|
132
|
+
for (const dataset of viaDatasets.items) {
|
|
133
|
+
const event = dataset.event;
|
|
134
|
+
if (!event?.publicId || seen.has(String(event.publicId)))
|
|
135
|
+
continue;
|
|
136
|
+
seen.add(String(event.publicId));
|
|
137
|
+
derived.push(toSummary(event, String(dataset.publicId)));
|
|
138
|
+
}
|
|
139
|
+
if (derived.length) {
|
|
140
|
+
all = derived;
|
|
141
|
+
source = "datasets";
|
|
142
|
+
}
|
|
143
|
+
}
|
|
108
144
|
const search = input.search?.trim() || null;
|
|
109
145
|
const needle = search ? normalize(search) : null;
|
|
110
146
|
const matched = needle
|
|
@@ -119,7 +155,8 @@ export async function listEvents(input = {}, options = {}) {
|
|
|
119
155
|
count: Math.min(matched.length, limit),
|
|
120
156
|
search,
|
|
121
157
|
events: matched.slice(0, limit),
|
|
122
|
-
unavailable,
|
|
158
|
+
unavailable: all.length === 0 && direct.unavailable,
|
|
159
|
+
source,
|
|
123
160
|
};
|
|
124
161
|
}
|
|
125
162
|
catch (error) {
|
package/dist/lib/discover.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/lib/discover.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"discover.js","sourceRoot":"","sources":["../../src/lib/discover.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* What lives here is the CLI-owned layer the SDK does not define: the everyday
|
|
7
7
|
* wordings a user or model is likely to type, and display units.
|
|
8
8
|
*/
|
|
9
|
-
import { allMetricNames, metricCategories, metricLabels, type MetricCategory } from "../generated/metrics.js";
|
|
10
|
-
export { allMetricNames, metricCategories, metricLabels, type MetricCategory };
|
|
9
|
+
import { allMetricNames, metricCategories, metricColumns, metricLabels, type MetricCategory } from "../generated/metrics.js";
|
|
10
|
+
export { allMetricNames, metricCategories, metricColumns, metricLabels, type MetricCategory, };
|
|
11
11
|
/** Normalize wording to a lookup key: "Heart Rate" and "heart-rate" both give "heartrate". */
|
|
12
12
|
export declare function compactMetricName(value: string): string;
|
|
13
13
|
export interface ResolvedMetricName {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metric-names.d.ts","sourceRoot":"","sources":["../../src/lib/metric-names.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,cAAc,EACd,gBAAgB,EAEhB,YAAY,EACZ,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,
|
|
1
|
+
{"version":3,"file":"metric-names.d.ts","sourceRoot":"","sources":["../../src/lib/metric-names.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,cAAc,EACd,gBAAgB,EAEhB,aAAa,EACb,YAAY,EACZ,KAAK,cAAc,EACpB,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,YAAY,EACZ,KAAK,cAAc,GACpB,CAAC;AA+FF,8FAA8F;AAC9F,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAKvD;AAOD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,cAAc,CAAC;IACzB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB;AAED,oFAAoF;AACpF,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAQnF;AAED,2DAA2D;AAC3D,wBAAgB,aAAa,IAAI,MAAM,EAAE,CAExC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,SAAI,GAAG,MAAM,EAAE,CAyBzE;AASD,sEAAsE;AACtE,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C"}
|
package/dist/lib/metric-names.js
CHANGED
|
@@ -6,8 +6,8 @@
|
|
|
6
6
|
* What lives here is the CLI-owned layer the SDK does not define: the everyday
|
|
7
7
|
* wordings a user or model is likely to type, and display units.
|
|
8
8
|
*/
|
|
9
|
-
import { allMetricNames, metricCategories, metricCategoryByName, metricLabels, } from "../generated/metrics.js";
|
|
10
|
-
export { allMetricNames, metricCategories, metricLabels };
|
|
9
|
+
import { allMetricNames, metricCategories, metricCategoryByName, metricColumns, metricLabels, } from "../generated/metrics.js";
|
|
10
|
+
export { allMetricNames, metricCategories, metricColumns, metricLabels, };
|
|
11
11
|
/**
|
|
12
12
|
* Units for metrics whose scale the catalogue states explicitly, either in the
|
|
13
13
|
* SDK's category comments or its label text. Metrics whose unit upstream leaves
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metric-names.js","sourceRoot":"","sources":["../../src/lib/metric-names.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,EACL,cAAc,EACd,gBAAgB,EAChB,oBAAoB,EACpB,YAAY,GAEb,MAAM,yBAAyB,CAAC;AAEjC,OAAO,
|
|
1
|
+
{"version":3,"file":"metric-names.js","sourceRoot":"","sources":["../../src/lib/metric-names.ts"],"names":[],"mappings":"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"}
|
|
@@ -2,8 +2,11 @@ import { executeGraphql } from "./graphql-transport.js";
|
|
|
2
2
|
import { type MetricCategory } from "./metric-names.js";
|
|
3
3
|
import { requireSession } from "./session.js";
|
|
4
4
|
export type { MetricCategory };
|
|
5
|
+
export type MetricAggregate = "count" | "avg" | "sum" | "max" | "min";
|
|
5
6
|
export interface QueryMetricsInput {
|
|
6
7
|
athleteId?: string;
|
|
8
|
+
/** Several athletes at once, for comparing them in one query. */
|
|
9
|
+
athleteIds?: string[];
|
|
7
10
|
athleteName?: string;
|
|
8
11
|
metric: string;
|
|
9
12
|
metricCategory?: MetricCategory;
|
|
@@ -15,6 +18,20 @@ export interface QueryMetricsInput {
|
|
|
15
18
|
datasetDatasourceId?: string;
|
|
16
19
|
tenantId?: string;
|
|
17
20
|
timeoutMs?: number;
|
|
21
|
+
/** Compute server-side instead of returning rows, e.g. a maximum over all history. */
|
|
22
|
+
aggregate?: MetricAggregate;
|
|
23
|
+
/** Column to aggregate; defaults to `current`, the metric value. */
|
|
24
|
+
aggregateField?: string;
|
|
25
|
+
/** Column to group by; defaults to `athletepublicid`. */
|
|
26
|
+
groupBy?: string;
|
|
27
|
+
/** Keep only samples whose value is at least this. */
|
|
28
|
+
minValue?: number;
|
|
29
|
+
/** Keep only samples whose value is at most this. */
|
|
30
|
+
maxValue?: number;
|
|
31
|
+
/** Column to sort by; defaults to `timestamp`. */
|
|
32
|
+
orderBy?: string;
|
|
33
|
+
/** Several events at once, for spanning a series of races. */
|
|
34
|
+
eventIds?: string[];
|
|
18
35
|
}
|
|
19
36
|
export interface MetricPosition {
|
|
20
37
|
latitude: number;
|
|
@@ -30,6 +47,16 @@ export interface MetricRow {
|
|
|
30
47
|
position: MetricPosition | null;
|
|
31
48
|
eventId: string | null;
|
|
32
49
|
datasetDatasourceId: string | null;
|
|
50
|
+
/**
|
|
51
|
+
* Every other column the category provides — the rolling max/min/avg, and the
|
|
52
|
+
* seven training zones for heart rate and power. Kept as a map so a column
|
|
53
|
+
* added upstream reaches callers without a code change here.
|
|
54
|
+
*/
|
|
55
|
+
extra: Record<string, unknown>;
|
|
56
|
+
}
|
|
57
|
+
export interface MetricAggregateGroup {
|
|
58
|
+
key: string | null;
|
|
59
|
+
value: number | null;
|
|
33
60
|
}
|
|
34
61
|
export interface QueryMetricsOutput {
|
|
35
62
|
environment: "uat" | "live";
|
|
@@ -48,6 +75,10 @@ export interface QueryMetricsOutput {
|
|
|
48
75
|
};
|
|
49
76
|
filters: {
|
|
50
77
|
eventId: string | null;
|
|
78
|
+
/** Echoes a multi-event request; compare against each row's eventId. */
|
|
79
|
+
eventIds: string[] | null;
|
|
80
|
+
/** Echoes a multi-athlete request; an athlete with no data simply has no rows. */
|
|
81
|
+
athleteIds: string[] | null;
|
|
51
82
|
datasetDatasourceId: string | null;
|
|
52
83
|
from: string | null;
|
|
53
84
|
to: string | null;
|
|
@@ -60,6 +91,13 @@ export interface QueryMetricsOutput {
|
|
|
60
91
|
queryExecutionId: string | null;
|
|
61
92
|
queryTimeMs: number | null;
|
|
62
93
|
rows: MetricRow[];
|
|
94
|
+
/** Present only when an aggregate was requested; `rows` is empty in that case. */
|
|
95
|
+
aggregate: {
|
|
96
|
+
function: MetricAggregate;
|
|
97
|
+
field: string;
|
|
98
|
+
groupBy: string;
|
|
99
|
+
groups: MetricAggregateGroup[];
|
|
100
|
+
} | null;
|
|
63
101
|
}
|
|
64
102
|
export interface QueryMetricsDependencies {
|
|
65
103
|
graphql: typeof executeGraphql;
|
|
@@ -67,6 +105,8 @@ export interface QueryMetricsDependencies {
|
|
|
67
105
|
sleep: (milliseconds: number, signal?: AbortSignal) => Promise<void>;
|
|
68
106
|
now: () => number;
|
|
69
107
|
}
|
|
108
|
+
/** Trimmed, de-duplicated, empties dropped. */
|
|
109
|
+
export declare function normalizeIdList(values: string[] | undefined): string[];
|
|
70
110
|
export declare function queryMetrics(input: QueryMetricsInput, options?: {
|
|
71
111
|
dependencies?: Partial<QueryMetricsDependencies>;
|
|
72
112
|
signal?: AbortSignal;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"query-metrics.d.ts","sourceRoot":"","sources":["../../src/lib/query-metrics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAExD,OAAO,EACL,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"query-metrics.d.ts","sourceRoot":"","sources":["../../src/lib/query-metrics.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { executeGraphql } from "./graphql-transport.js";
|
|
2
2
|
import { CliError, toCliError } from "./errors.js";
|
|
3
|
-
import { metricCategories, resolveMetricName, suggestMetricNames, } from "./metric-names.js";
|
|
3
|
+
import { metricCategories, metricColumns, resolveMetricName, suggestMetricNames, } from "./metric-names.js";
|
|
4
4
|
import { requireSession } from "./session.js";
|
|
5
5
|
const listAthletesDocument = `query listAthletes($limit: Int, $nextToken: String, $tenant: String!) {
|
|
6
6
|
listAthletes(limit: $limit, nextToken: $nextToken, tenant: $tenant) {
|
|
@@ -228,6 +228,15 @@ function parsedValue(value, canonicalMetric) {
|
|
|
228
228
|
}
|
|
229
229
|
return decoded;
|
|
230
230
|
}
|
|
231
|
+
/** Columns surfaced as named fields; everything else lands in `extra`. */
|
|
232
|
+
const coreColumns = new Set([
|
|
233
|
+
"timestamp",
|
|
234
|
+
"athletepublicid",
|
|
235
|
+
"metric",
|
|
236
|
+
"current",
|
|
237
|
+
"eventpublicid",
|
|
238
|
+
"datasetdatasourcepublicid",
|
|
239
|
+
]);
|
|
231
240
|
function normalizedRow(row, metric) {
|
|
232
241
|
const timestamp = row.timestamp;
|
|
233
242
|
const rawValue = row.current;
|
|
@@ -241,18 +250,93 @@ function normalizedRow(row, metric) {
|
|
|
241
250
|
position: metric.canonical === "latlong" ? positionFrom(rawValue) : null,
|
|
242
251
|
eventId: optionalString(row.eventpublicid),
|
|
243
252
|
datasetDatasourceId: optionalString(row.datasetdatasourcepublicid),
|
|
253
|
+
extra: Object.fromEntries(Object.entries(row).filter(([key, value]) => !coreColumns.has(key) && value !== null && value !== undefined)),
|
|
244
254
|
};
|
|
245
255
|
}
|
|
256
|
+
const aggregateFunctions = new Set(["count", "avg", "sum", "max", "min"]);
|
|
257
|
+
const defaultAggregateField = "current";
|
|
258
|
+
const defaultGroupBy = "athletepublicid";
|
|
259
|
+
/**
|
|
260
|
+
* Resolve the aggregate triple, or nothing when no aggregate was asked for.
|
|
261
|
+
*
|
|
262
|
+
* The Data Explorer only aggregates when aggregate, aggregateField and groupBy are
|
|
263
|
+
* all present and every column passes its allowlist; otherwise it quietly returns
|
|
264
|
+
* plain rows instead. A caller asking for a maximum and silently receiving raw
|
|
265
|
+
* samples is the worst outcome, so the defaults are filled in here and anything
|
|
266
|
+
* unusable is rejected rather than sent.
|
|
267
|
+
*/
|
|
268
|
+
function resolveAggregate(input, category) {
|
|
269
|
+
if (!input.aggregate)
|
|
270
|
+
return undefined;
|
|
271
|
+
const fn = input.aggregate.toLowerCase();
|
|
272
|
+
if (!aggregateFunctions.has(fn)) {
|
|
273
|
+
throw new CliError(`Unsupported aggregate "${input.aggregate}"`, "AGGREGATE_INVALID", 2, { supported: [...aggregateFunctions].sort() });
|
|
274
|
+
}
|
|
275
|
+
const field = input.aggregateField?.trim() || defaultAggregateField;
|
|
276
|
+
const groupBy = input.groupBy?.trim() || defaultGroupBy;
|
|
277
|
+
const allowed = metricColumns[category];
|
|
278
|
+
for (const [label, column] of [
|
|
279
|
+
["aggregate_field", field],
|
|
280
|
+
["group_by", groupBy],
|
|
281
|
+
]) {
|
|
282
|
+
if (!allowed.includes(column)) {
|
|
283
|
+
throw new CliError(`${label} "${column}" is not a column of ${category}`, "AGGREGATE_COLUMN_INVALID", 2, { column, allowed: [...allowed] });
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
return { function: fn, field, groupBy };
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Read the aggregate rows the Data Explorer returns. It aliases the computed
|
|
290
|
+
* column as `<function>_<field>`, e.g. `max_current`, beside the grouping column.
|
|
291
|
+
*/
|
|
292
|
+
function aggregateGroups(raw, aggregate) {
|
|
293
|
+
const alias = `${aggregate.function}_${aggregate.field}`;
|
|
294
|
+
return raw.map((row) => {
|
|
295
|
+
const rawValue = row[alias] ?? row[alias.toUpperCase()];
|
|
296
|
+
const value = Number(rawValue);
|
|
297
|
+
return {
|
|
298
|
+
key: optionalString(row[aggregate.groupBy]),
|
|
299
|
+
value: Number.isFinite(value) ? value : null,
|
|
300
|
+
};
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
/** Checked before any lookup, so a bad range costs no network round-trip. */
|
|
304
|
+
function ensureValueRange(input) {
|
|
305
|
+
for (const bound of [input.minValue, input.maxValue]) {
|
|
306
|
+
if (bound === undefined)
|
|
307
|
+
continue;
|
|
308
|
+
if (typeof bound !== "number" || !Number.isFinite(bound)) {
|
|
309
|
+
throw new CliError("min_value and max_value must be finite numbers", "VALUE_FILTER_INVALID", 2);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
if (input.minValue !== undefined &&
|
|
313
|
+
input.maxValue !== undefined &&
|
|
314
|
+
input.minValue > input.maxValue) {
|
|
315
|
+
throw new CliError("min_value must not be greater than max_value", "VALUE_FILTER_INVALID", 2);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
/** Trimmed, de-duplicated, empties dropped. */
|
|
319
|
+
export function normalizeIdList(values) {
|
|
320
|
+
return [...new Set((values ?? []).map((value) => value.trim()).filter(Boolean))];
|
|
321
|
+
}
|
|
246
322
|
function ensureQueryIsScoped(input) {
|
|
323
|
+
const athleteIds = normalizeIdList(input.athleteIds);
|
|
247
324
|
const count = Number(Boolean(input.athleteId?.trim())) +
|
|
248
|
-
Number(Boolean(input.athleteName?.trim()))
|
|
325
|
+
Number(Boolean(input.athleteName?.trim())) +
|
|
326
|
+
Number(athleteIds.length > 0);
|
|
249
327
|
if (count > 1) {
|
|
250
|
-
throw new CliError("Provide at most one of athlete_id or
|
|
328
|
+
throw new CliError("Provide at most one of athlete_id, athlete_name, or athlete_ids", "ATHLETE_SELECTOR_INVALID", 2);
|
|
329
|
+
}
|
|
330
|
+
if (input.eventId?.trim() && normalizeIdList(input.eventIds).length) {
|
|
331
|
+
throw new CliError("Provide at most one of event_id or event_ids", "EVENT_SELECTOR_INVALID", 2);
|
|
251
332
|
}
|
|
252
333
|
// Without a scope this would sweep every athlete in the tenant, which is never
|
|
253
334
|
// what was asked for and is expensive to run.
|
|
254
|
-
if (count === 0 &&
|
|
255
|
-
|
|
335
|
+
if (count === 0 &&
|
|
336
|
+
!input.eventId?.trim() &&
|
|
337
|
+
!normalizeIdList(input.eventIds).length &&
|
|
338
|
+
!input.datasetDatasourceId?.trim()) {
|
|
339
|
+
throw new CliError("Provide athlete_id, athlete_name, athlete_ids, event_id, event_ids, or dataset_datasource_id to scope the query", "QUERY_SCOPE_REQUIRED", 2);
|
|
256
340
|
}
|
|
257
341
|
}
|
|
258
342
|
async function executeAndPoll(queryInput, tenantId, timeoutMs, dependencies, signal) {
|
|
@@ -303,8 +387,21 @@ export async function queryMetrics(input, options = {}) {
|
|
|
303
387
|
throw new CliError("timeout_ms must be an integer from 1000 to 120000", "TIMEOUT_INVALID", 2);
|
|
304
388
|
}
|
|
305
389
|
const metric = resolveMetric(input);
|
|
390
|
+
// Validate before the athlete lookup: a malformed aggregate should not cost a
|
|
391
|
+
// network round-trip before it is rejected.
|
|
392
|
+
const aggregate = resolveAggregate(input, metric.category);
|
|
393
|
+
ensureValueRange(input);
|
|
394
|
+
const orderBy = input.orderBy?.trim() || "timestamp";
|
|
395
|
+
if (!metricColumns[metric.category].includes(orderBy)) {
|
|
396
|
+
throw new CliError(`order_by "${orderBy}" is not a column of ${metric.category}`, "ORDER_BY_INVALID", 2, { column: orderBy, allowed: [...metricColumns[metric.category]] });
|
|
397
|
+
}
|
|
306
398
|
// An event- or datasource-scoped question needs no athlete: "latest heart rate
|
|
307
399
|
// for this race" is a legitimate shape the tool used to be unable to express.
|
|
400
|
+
const athleteIds = normalizeIdList(input.athleteIds);
|
|
401
|
+
const eventIds = normalizeIdList(input.eventIds);
|
|
402
|
+
// A single athlete is resolved so the caller gets a name back; a list is passed
|
|
403
|
+
// straight through, since resolving each would cost a lookup per athlete and
|
|
404
|
+
// rows already carry the athlete they belong to.
|
|
308
405
|
const athlete = input.athleteId || input.athleteName
|
|
309
406
|
? await resolveAthlete(input, tenantId, dependencies)
|
|
310
407
|
: undefined;
|
|
@@ -320,8 +417,28 @@ export async function queryMetrics(input, options = {}) {
|
|
|
320
417
|
operator: "in",
|
|
321
418
|
value: athlete.athlete.publicId,
|
|
322
419
|
});
|
|
420
|
+
else if (athleteIds.length)
|
|
421
|
+
rules.push({
|
|
422
|
+
field: "athletepublicid",
|
|
423
|
+
operator: "in",
|
|
424
|
+
value: athleteIds.join(","),
|
|
425
|
+
});
|
|
323
426
|
if (input.eventId)
|
|
324
427
|
rules.push({ field: "eventpublicid", operator: "in", value: input.eventId });
|
|
428
|
+
else if (eventIds.length)
|
|
429
|
+
rules.push({
|
|
430
|
+
field: "eventpublicid",
|
|
431
|
+
operator: "in",
|
|
432
|
+
value: eventIds.join(","),
|
|
433
|
+
});
|
|
434
|
+
for (const [operator, bound] of [
|
|
435
|
+
[">=", input.minValue],
|
|
436
|
+
["<=", input.maxValue],
|
|
437
|
+
]) {
|
|
438
|
+
if (bound === undefined)
|
|
439
|
+
continue;
|
|
440
|
+
rules.push({ field: "current", operator, value: String(bound) });
|
|
441
|
+
}
|
|
325
442
|
if (input.datasetDatasourceId)
|
|
326
443
|
rules.push({
|
|
327
444
|
field: "datasetdatasourcepublicid",
|
|
@@ -334,22 +451,27 @@ export async function queryMetrics(input, options = {}) {
|
|
|
334
451
|
rules.push({ field: "timestamp", operator: "<=", value: String(to.timestamp) });
|
|
335
452
|
const order = input.order ?? "newest";
|
|
336
453
|
const queryInput = {
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
"eventpublicid",
|
|
341
|
-
"athletepublicid",
|
|
342
|
-
"metric",
|
|
343
|
-
"current",
|
|
344
|
-
],
|
|
454
|
+
// Ask for everything the category offers, so heart rate and power carry
|
|
455
|
+
// their rolling max/min/avg and zone breakdown rather than value alone.
|
|
456
|
+
columns: [...metricColumns[metric.category]],
|
|
345
457
|
metricCategory: metric.category,
|
|
346
458
|
filterRules: JSON.stringify({ combinator: "and", rules }),
|
|
347
459
|
limit,
|
|
348
|
-
|
|
460
|
+
// Ordering by timestamp is invalid once the rows are collapsed into groups.
|
|
461
|
+
orderBy: aggregate ? aggregate.groupBy : orderBy,
|
|
349
462
|
orderDirection: order === "newest" ? "DESC" : "ASC",
|
|
463
|
+
...(aggregate
|
|
464
|
+
? {
|
|
465
|
+
aggregate: aggregate.function,
|
|
466
|
+
aggregateField: aggregate.field,
|
|
467
|
+
groupBy: aggregate.groupBy,
|
|
468
|
+
}
|
|
469
|
+
: {}),
|
|
350
470
|
};
|
|
351
471
|
const result = await executeAndPoll(queryInput, tenantId, timeoutMs, dependencies, options.signal);
|
|
352
|
-
const
|
|
472
|
+
const raw = rowsFrom(result);
|
|
473
|
+
const rows = aggregate ? [] : raw.map((row) => normalizedRow(row, metric));
|
|
474
|
+
const groups = aggregate ? aggregateGroups(raw, aggregate) : null;
|
|
353
475
|
return {
|
|
354
476
|
environment: session.environment,
|
|
355
477
|
tenantId,
|
|
@@ -363,6 +485,8 @@ export async function queryMetrics(input, options = {}) {
|
|
|
363
485
|
metric,
|
|
364
486
|
filters: {
|
|
365
487
|
eventId: input.eventId ?? null,
|
|
488
|
+
eventIds: eventIds.length ? eventIds : null,
|
|
489
|
+
athleteIds: athleteIds.length ? athleteIds : null,
|
|
366
490
|
datasetDatasourceId: input.datasetDatasourceId ?? null,
|
|
367
491
|
from: from?.iso ?? null,
|
|
368
492
|
to: to?.iso ?? null,
|
|
@@ -375,6 +499,14 @@ export async function queryMetrics(input, options = {}) {
|
|
|
375
499
|
queryExecutionId: result.queryExecutionId ?? null,
|
|
376
500
|
queryTimeMs: result.queryTimeMs ?? null,
|
|
377
501
|
rows,
|
|
502
|
+
aggregate: aggregate
|
|
503
|
+
? {
|
|
504
|
+
function: aggregate.function,
|
|
505
|
+
field: aggregate.field,
|
|
506
|
+
groupBy: aggregate.groupBy,
|
|
507
|
+
groups: groups ?? [],
|
|
508
|
+
}
|
|
509
|
+
: null,
|
|
378
510
|
};
|
|
379
511
|
}
|
|
380
512
|
catch (error) {
|