fix(cron): resolve Garmin sync payload mismatch, harden cronjobs, and update wiki submodule
This commit is contained in:
@@ -35,13 +35,7 @@ Führe den nächtlichen Garmin Connect Sync durch.
|
||||
Vorgehen:
|
||||
1. Führe den Garmin-Sync-Befehl aus:
|
||||
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/garmin_sync.py --days 2 --data-dir /home/node/.openclaw/wiki/main/data
|
||||
2. Aktualisiere die gerenderten Markdown-Ansichten:
|
||||
PYTHONPATH=/home/node/mop-skills/mop-skills/skills/datastore/scripts uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/render_views.py --data-dir /home/node/.openclaw/wiki/main/data --wiki-dir /home/node/.openclaw/wiki/main
|
||||
3. Aktualisiere das persönliche Health & Nutrition Dashboard (moritz.html):
|
||||
uv run /home/node/mop-skills/mop-skills/skills/datastore/scripts/update_moritz_website.py --data-dir /home/node/.openclaw/wiki/main/data
|
||||
4. Git Commit & Push im Knowledge Wiki:
|
||||
cd /home/node/.openclaw/wiki/main && git add data/garmin/ entities/nutrition-log/ public/ && git diff --staged --quiet || (git commit -m "chore(garmin): automated nightly mirror [skip ci]" && git push origin main)
|
||||
5. Finale Antwort:
|
||||
2. Finale Antwort:
|
||||
- Bei Erfolg: Gib exakt 'NO_REPLY' aus (intentional silence, kein Telegram-Spam in der Nacht).
|
||||
- Nur bei Authentifizierungsfehlern: Informiere kurz via Telegram (Thema #Sport), dass ein Garmin-Re-Auth nötig ist, oder starte den Re-Auth-Flow.
|
||||
EOF
|
||||
|
||||
+1
-1
Submodule knowledge-wiki updated: 720c5cf74b...71ee240511
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Any, Dict, List, Optional
|
||||
from pydantic import BaseModel, Field
|
||||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
class QueryRequest(BaseModel):
|
||||
query: str = Field(..., description="Read-only SQL query to execute in DuckDB")
|
||||
@@ -44,6 +44,20 @@ class GarminSyncRequest(BaseModel):
|
||||
daily: List[Dict[str, Any]] = Field(default_factory=list, description="Garmin daily summary records")
|
||||
sleep: List[Dict[str, Any]] = Field(default_factory=list, description="Garmin sleep records")
|
||||
activities: List[Dict[str, Any]] = Field(default_factory=list, description="Garmin activity records")
|
||||
daily_summary: Optional[Dict[str, Any]] = None
|
||||
sleep_data: Optional[Dict[str, Any]] = None
|
||||
|
||||
@model_validator(mode="before")
|
||||
@classmethod
|
||||
def normalize_aliases(cls, data: Any) -> Any:
|
||||
if isinstance(data, dict):
|
||||
# Normalize daily_summary dict to daily list if daily is missing/empty
|
||||
if "daily_summary" in data and data["daily_summary"] and not data.get("daily"):
|
||||
data["daily"] = [data["daily_summary"]]
|
||||
# Normalize sleep_data dict to sleep list if sleep is missing/empty
|
||||
if "sleep_data" in data and data["sleep_data"] and not data.get("sleep"):
|
||||
data["sleep"] = [data["sleep_data"]]
|
||||
return data
|
||||
|
||||
class StatusResponse(BaseModel):
|
||||
status: str
|
||||
|
||||
@@ -177,3 +177,29 @@ def test_garmin_sync_and_duplicate_guard(client: TestClient):
|
||||
assert r_sync.status_code == 200
|
||||
assert r_sync.json()["status"] == "success"
|
||||
assert r_sync.json()["synced_daily"] == 1
|
||||
|
||||
# Test alias support (daily_summary and sleep_data dicts)
|
||||
garmin_alias_payload = {
|
||||
"date": "2026-10-16",
|
||||
"daily_summary": {
|
||||
"calendarDate": "2026-10-16",
|
||||
"totalKilocalories": 2550,
|
||||
"activeKilocalories": 650,
|
||||
"bmrKilocalories": 1900,
|
||||
"totalSteps": 12000,
|
||||
"restingHeartRate": 50,
|
||||
},
|
||||
"sleep_data": {
|
||||
"dailySleepDTO": {
|
||||
"calendarDate": "2026-10-16",
|
||||
"sleepTimeSeconds": 28800,
|
||||
}
|
||||
},
|
||||
"activities": [],
|
||||
}
|
||||
r_alias = client.post("/duckdb-api/v1/garmin/sync", json=garmin_alias_payload)
|
||||
assert r_alias.status_code == 200
|
||||
assert r_alias.json()["status"] == "success"
|
||||
assert r_alias.json()["synced_daily"] == 1
|
||||
assert r_alias.json()["synced_sleep"] == 1
|
||||
|
||||
|
||||
Reference in New Issue
Block a user