Add matched training signals, daily recovery and performance analysis

This commit is contained in:
Peter Stockings
2026-10-03 13:22:32 +10:00
parent e6e2f22479
commit 418e03583a
37 changed files with 1380 additions and 47 deletions
+45
View File
@@ -101,6 +101,19 @@ def run_connection(connection_id):
count = import_cache(user, current_app.config["DATA_ROOT"])
if result["failed"]:
raise SyncError("Some activities failed; sync will retry.")
db.session.commit()
if connection.health_enabled:
from .recovery import sync_health
try:
health = sync_health(api, user)
connection.health_message = health["message"]
except Exception: # noqa: BLE001 -- optional provider data cannot block activities
db.session.rollback()
connection.health_message = "Daily recovery unavailable; will retry. Activity sync completed."
finally:
connection.tokens = cipher().encrypt(api.client.dumps().encode()).decode()
db.session.commit()
connection.last_success = now
connection.failures = 0
connection.message = f"Sync complete. {count} new activities imported."
@@ -150,6 +163,38 @@ def run_due():
def register_cli(app):
@app.cli.command("backfill-health")
@click.option("--email", required=True)
@click.option("--days", default=90, type=click.IntRange(1, 365))
def health_backfill(email, days):
from .recovery import sync_health
logging.getLogger("garminconnect").disabled = True
user = db.session.scalar(db.select(User).filter_by(email=email.strip().lower()))
connection = db.session.scalar(db.select(GarminConnection).filter_by(
user_id=user.id)) if user else None
if not connection:
raise click.ClickException("No connected account found.")
try:
with session_lock(user.id):
api = Garmin()
authenticated = False
try:
api.login(cipher().decrypt(connection.tokens.encode()).decode())
authenticated = True
result = sync_health(api, user, days, days)
connection.health_enabled = True
connection.health_message = result["message"]
click.echo(result["message"])
finally:
if authenticated:
connection.tokens = cipher().encrypt(api.client.dumps().encode()).decode()
db.session.commit()
except Timeout:
raise click.ClickException("A sync is running; retry after it finishes.") from None
except Exception: # noqa: BLE001 -- suppress provider credentials at the operator boundary
raise click.ClickException("Daily recovery import failed; retry or reconnect.") from None
@app.cli.command("sync-worker")
@click.option("--once", is_flag=True, help="Process currently due syncs and exit.")
def worker(once):