feat: Update spec, fix bugs, improve UI/UX, and clean up code
This commit is contained in:
@@ -1,11 +1,20 @@
|
||||
from fastapi import APIRouter, Depends
|
||||
from fastapi import APIRouter, Depends, HTTPException
|
||||
from pydantic import BaseModel
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
from ..models.api_token import APIToken
|
||||
from ..services.sync_app import SyncApp
|
||||
from ..services.garmin.client import GarminClient
|
||||
from ..services.postgresql_manager import PostgreSQLManager
|
||||
from sqlalchemy.orm import Session
|
||||
from ..utils.config import config
|
||||
import logging
|
||||
import json
|
||||
import garth
|
||||
from garth.auth_tokens import OAuth1Token, OAuth2Token
|
||||
|
||||
router = APIRouter()
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class SyncActivityRequest(BaseModel):
|
||||
days_back: int = 30
|
||||
@@ -20,32 +29,50 @@ def get_db():
|
||||
with db_manager.get_db_session() as session:
|
||||
yield session
|
||||
|
||||
@router.post("/sync/weight", response_model=SyncResponse)
|
||||
async def sync_weight(db: Session = Depends(get_db)):
|
||||
# This would trigger the weight sync process
|
||||
# Implementation will connect with the services layer
|
||||
return {
|
||||
"status": "started",
|
||||
"message": "Weight sync process started",
|
||||
"job_id": "weight-sync-12345"
|
||||
}
|
||||
def _load_and_verify_garth_session(db: Session):
|
||||
"""Helper to load token from DB and verify session with Garmin."""
|
||||
logger.info("Loading and verifying Garmin session...")
|
||||
token_record = db.query(APIToken).filter_by(token_type='garmin').first()
|
||||
if not (token_record and token_record.garth_oauth1_token and token_record.garth_oauth2_token):
|
||||
raise HTTPException(status_code=401, detail="Garmin token not found.")
|
||||
|
||||
try:
|
||||
oauth1_dict = json.loads(token_record.garth_oauth1_token)
|
||||
oauth2_dict = json.loads(token_record.garth_oauth2_token)
|
||||
|
||||
domain = oauth1_dict.get('domain')
|
||||
if domain:
|
||||
garth.configure(domain=domain)
|
||||
|
||||
garth.client.oauth1_token = OAuth1Token(**oauth1_dict)
|
||||
garth.client.oauth2_token = OAuth2Token(**oauth2_dict)
|
||||
|
||||
garth.UserProfile.get()
|
||||
logger.info("Garth session verified.")
|
||||
except Exception as e:
|
||||
logger.error(f"Garth session verification failed: {e}", exc_info=True)
|
||||
raise HTTPException(status_code=401, detail=f"Failed to authenticate with Garmin: {e}")
|
||||
|
||||
@router.post("/sync/activities", response_model=SyncResponse)
|
||||
async def sync_activities(request: SyncActivityRequest, db: Session = Depends(get_db)):
|
||||
# This would trigger the activity sync process
|
||||
# Implementation will connect with the services layer
|
||||
return {
|
||||
"status": "started",
|
||||
"message": "Activity sync process started",
|
||||
"job_id": f"activity-sync-{request.days_back}"
|
||||
}
|
||||
def sync_activities(request: SyncActivityRequest, db: Session = Depends(get_db)):
|
||||
_load_and_verify_garth_session(db)
|
||||
garmin_client = GarminClient() # The client is now just a thin wrapper
|
||||
sync_app = SyncApp(db_session=db, garmin_client=garmin_client)
|
||||
result = sync_app.sync_activities(days_back=request.days_back)
|
||||
return SyncResponse(
|
||||
status=result.get("status", "completed_with_errors" if result.get("failed", 0) > 0 else "completed"),
|
||||
message=f"Activity sync completed: {result.get('processed', 0)} processed, {result.get('failed', 0)} failed",
|
||||
job_id=f"activity-sync-{datetime.now().strftime('%Y%m%d%H%M%S')}"
|
||||
)
|
||||
|
||||
@router.post("/sync/metrics", response_model=SyncResponse)
|
||||
async def sync_metrics(db: Session = Depends(get_db)):
|
||||
# This would trigger the health metrics sync process
|
||||
# Implementation will connect with the services layer
|
||||
return {
|
||||
"status": "started",
|
||||
"message": "Health metrics sync process started",
|
||||
"job_id": "metrics-sync-12345"
|
||||
}
|
||||
def sync_metrics(db: Session = Depends(get_db)):
|
||||
_load_and_verify_garth_session(db)
|
||||
garmin_client = GarminClient()
|
||||
sync_app = SyncApp(db_session=db, garmin_client=garmin_client)
|
||||
result = sync_app.sync_health_metrics()
|
||||
return SyncResponse(
|
||||
status=result.get("status", "completed_with_errors" if result.get("failed", 0) > 0 else "completed"),
|
||||
message=f"Health metrics sync completed: {result.get('processed', 0)} processed, {result.get('failed', 0)} failed",
|
||||
job_id=f"metrics-sync-{datetime.now().strftime('%Y%m%d%H%M%S')}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user