Try training_status and stats_and_body for VO2 max (debug logging)
Build and push images / validate (push) Successful in 2s
Build and push images / build-backend (push) Successful in 47s
Build and push images / build-worker (push) Successful in 45s
Build and push images / build-frontend (push) Successful in 23s

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 21:59:05 +01:00
parent 367ae4e8f7
commit 41a39ec3c7
+17 -18
View File
@@ -325,33 +325,32 @@ def sync_wellness(garmin, user_id: int, since: Optional[datetime], db,
logger.warning("Failed to upsert health_metrics for %s: %s", day_str, exc) logger.warning("Failed to upsert health_metrics for %s: %s", day_str, exc)
db.rollback() db.rollback()
# Fetch current VO2 max once via maxmet endpoint (slow-changing — only update today's row) # Fetch current VO2 max once (slow-changing — only update today's row)
today_str = date.today().isoformat() today_str = date.today().isoformat()
mm_data = _safe(garmin.get_max_metrics, today_str) ts_data = _safe(garmin.get_training_status, today_str)
logger.info("maxmet raw response: %s", mm_data) logger.info("training_status raw response: %s", ts_data)
sb_data = _safe(garmin.get_stats_and_body, today_str)
logger.info("stats_and_body raw response: %s", sb_data)
fa_data = _safe(garmin.get_fitnessage_data, today_str) fa_data = _safe(garmin.get_fitnessage_data, today_str)
logger.info("fitnessage raw response: %s", fa_data)
vo2 = None vo2 = None
if mm_data: # Try training status first
# maxmet returns a list of metric dicts or a wrapper if ts_data and not vo2:
items = mm_data if isinstance(mm_data, list) else mm_data.get("allMetrics", {}).get("metricsMap", {}) for key in ("vo2MaxPreciseValue", "vo2Max", "latestVO2Max"):
if isinstance(items, list): v = ts_data.get(key)
for item in items:
for key in ("vo2MaxPreciseValue", "vo2Max", "generic"):
v = item.get(key)
if v and isinstance(v, (int, float)) and float(v) > 0: if v and isinstance(v, (int, float)) and float(v) > 0:
vo2 = float(v) vo2 = float(v)
break break
if vo2: if not vo2 and isinstance(ts_data.get("mostRecentVO2Max"), dict):
break v = ts_data["mostRecentVO2Max"].get("generic") or ts_data["mostRecentVO2Max"].get("value")
elif isinstance(items, dict):
for key in ("VO2_MAX", "vo2Max", "vo2MaxPreciseValue"):
entry = items.get(key)
if entry:
v = entry[0].get("value") if isinstance(entry, list) else entry.get("value")
if v and float(v) > 0: if v and float(v) > 0:
vo2 = float(v) vo2 = float(v)
# Try stats_and_body
if sb_data and not vo2:
for key in ("vo2MaxPreciseValue", "vo2Max"):
v = sb_data.get(key)
if v and isinstance(v, (int, float)) and float(v) > 0:
vo2 = float(v)
break break
fa_age = None fa_age = None