Replace fixed DSL fields with parameterized metric expressions

This commit is contained in:
Peter Stockings
2026-10-04 10:24:12 +11:00
parent 418e03583a
commit d660b86bb0
18 changed files with 402 additions and 137 deletions
+4 -13
View File
@@ -38,7 +38,6 @@ def extract(text):
"cohorts": [],
"comparison": "period",
"reduce": None,
"long_run": 10.0,
"route": None,
}
seen, lines = set(), text.splitlines()
@@ -61,12 +60,6 @@ def extract(text):
if not 1 <= minutes <= 180:
raise QueryError("Use 1–180 matched minutes per run.", number)
options["reduce"] = minutes
elif match := re.fullmatch(r"long run distance >= (\d+(?:\.\d+)?) km", line):
once("long_run", number)
distance = float(match[1])
if not 1 <= distance <= 100:
raise QueryError("Use a long-run threshold of 1–100 km.", number)
options["long_run"] = distance
elif match := re.fullmatch(r"route similar to (\d+)", line):
once("route", number)
options["route"] = int(match[1])
@@ -156,6 +149,8 @@ def extract(text):
def validate(q, catalog):
if q["source"] in {"days", "health"} and any("best_distance" in s for s in q["derived"]):
raise QueryError("best_time requires the runs source.")
if q["flag"] and q["source"] in {"laps", "segments", "intervals"} and not q["reduce"]:
raise QueryError("Reduce recordings to independent runs before using a deviation flag.")
if q["reduce"] and q["source"] not in {"intervals", "segments"}:
@@ -201,10 +196,6 @@ def validate(q, catalog):
"distance_change",
"pace_change",
"heart_rate_change",
"rolling_7d_distance",
"rolling_28d_distance",
"rolling_7d_count",
"rolling_28d_count",
"run_day_streak",
}
fields = {
@@ -226,13 +217,13 @@ def validate(q, catalog):
if q["bin"]:
fields.add(q["bin"]["field"])
for spec in q["derived"]:
if "window" not in spec:
if not any(key in spec for key in ("window", "since", "best_distance")):
fields.update(
node.id
for node in ast.walk(ast.parse(spec["expression"], mode="eval"))
if isinstance(node, ast.Name)
)
if fields & temporal or any("window" in spec for spec in q["derived"]):
if fields & temporal or any(any(key in spec for key in ("window", "since", "best_distance")) for spec in q["derived"]):
raise QueryError(
"Run-history metrics and rolling calculations require the runs source."
)