Fix Garmin full export import: UDSFile health data and nested zip FIT files
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 44s
Build and push images / build-frontend (push) Successful in 25s

Garmin Connect exports use UDSFile_*.json (not DailyMetrics) for daily
wellness summaries, and pack activity FIT files inside nested sub-zips
under DI-Connect-Uploaded-Files/ rather than at the top level.

- process_garmin_health_zip: match UDSFile_*.json instead of DailyMetrics,
  handle list-of-records format, extract stress from allDayStress.aggregatorList,
  convert floorsAscendedInMeters to floor count
- upload_garmin_export: recurse into nested .zip files to find and queue
  individual activity FIT files

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-08 10:17:51 +01:00
parent 2ea691085f
commit f5d91cf8ae
2 changed files with 78 additions and 35 deletions
+16
View File
@@ -75,6 +75,22 @@ async def upload_garmin_export(
fit_path = extract_dir / name
task = process_activity_file.delay(str(fit_path), current_user.id, "fit")
task_ids.append(task.id)
elif lower.endswith(".zip"):
# Garmin exports nest activity FIT files inside sub-zips
# (e.g. DI-Connect-Uploaded-Files/UploadedFiles_*_Part*.zip)
nested_zip_path = extract_dir / name
nested_extract = nested_zip_path.parent / nested_zip_path.stem
nested_extract.mkdir(exist_ok=True)
try:
with zipfile.ZipFile(nested_zip_path) as nzf:
nzf.extractall(nested_extract)
for nested_name in nzf.namelist():
if nested_name.lower().endswith(".fit"):
fit_path = nested_extract / nested_name
task = process_activity_file.delay(str(fit_path), current_user.id, "fit")
task_ids.append(task.id)
except zipfile.BadZipFile:
pass
# Queue health/wellness data extraction
health_task = process_garmin_health_zip.delay(str(dest), current_user.id)