Add Garmin Connect auto-sync via python-garminconnect
Build and push images / validate (push) Successful in 2s
Build and push images / build-backend (push) Successful in 7s
Build and push images / build-worker (push) Successful in 6s
Build and push images / build-frontend (push) Successful in 8s

- GarminConnectConfig model stores encrypted credentials and OAuth token
- garmin_connect_sync service: token-based auth with password fallback,
  activity FIT download + queue, daily wellness from JSON API
- Celery beat schedule: sync_all_garmin_connect fires every hour
- New API router /api/garmin-sync: config CRUD, manual trigger
- Beat container added to docker-compose.yml and docker-compose.deploy.yml
- ProfilePage: Garmin Connect section with connect/update/disconnect and Sync now

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 00:08:12 +01:00
parent 0cdc653664
commit 6d224d51c5
9 changed files with 691 additions and 3 deletions
+2 -1
View File
@@ -6,7 +6,7 @@ import asyncio
from app.core.database import engine, AsyncSessionLocal, Base
from app.core.config import settings
from app.api import auth, activities, routes, health, records, upload, profile
from app.api import auth, activities, routes, health, records, upload, profile, garmin_sync
async def init_db():
@@ -98,6 +98,7 @@ app.include_router(health.router, prefix="/api/health-metrics", tags=["health"])
app.include_router(records.router, prefix="/api/records", tags=["records"])
app.include_router(upload.router, prefix="/api/upload", tags=["upload"])
app.include_router(profile.router, prefix="/api/profile", tags=["profile"])
app.include_router(garmin_sync.router, prefix="/api/garmin-sync", tags=["garmin-sync"])
@app.get("/health")