mirror of
https://github.com/sstent/FitTrack_GarminSync.git
synced 2026-01-26 00:51:44 +00:00
feat: Initial commit of FitTrack_GarminSync project
This commit is contained in:
82
contracts/garmin_auth_link.json
Normal file
82
contracts/garmin_auth_link.json
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"endpoint": "/api/garmin/auth/link",
|
||||
"method": "POST",
|
||||
"description": "Initiates the linking process for a Garmin Connect account using username/password.",
|
||||
"request": {
|
||||
"headers": {
|
||||
"Authorization": "Bearer <token>"
|
||||
},
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"email": {
|
||||
"type": "string",
|
||||
"format": "email",
|
||||
"description": "Garmin Connect account email."
|
||||
},
|
||||
"password": {
|
||||
"type": "string",
|
||||
"description": "Garmin Connect account password."
|
||||
}
|
||||
},
|
||||
"required": ["email", "password"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"200": {
|
||||
"description": "Garmin Connect account linked successfully.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Garmin Connect account linked successfully."
|
||||
},
|
||||
"garmin_connect_account_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID of the newly linked Garmin Connect account."
|
||||
}
|
||||
},
|
||||
"required": ["message", "garmin_connect_account_id"]
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request: Invalid credentials or account already linked.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Invalid Garmin Connect credentials or account already linked."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized: User not authenticated with the application.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Not authenticated with the application."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error: Unexpected error during linking process.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "An unexpected error occurred during Garmin account linking."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
contracts/sync_garmin_activities.json
Normal file
82
contracts/sync_garmin_activities.json
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"endpoint": "/api/sync/garmin/activities",
|
||||
"method": "POST",
|
||||
"description": "Triggers synchronization of Garmin Connect activities to CentralDB.",
|
||||
"request": {
|
||||
"headers": {
|
||||
"Authorization": "Bearer <token>"
|
||||
},
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"start_date": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"description": "Optional start date to sync activities from (YYYY-MM-DD). Defaults to last sync date."
|
||||
},
|
||||
"end_date": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"description": "Optional end date to sync activities until (YYYY-MM-DD). Defaults to today."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"202": {
|
||||
"description": "Synchronization process initiated successfully.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Garmin activity synchronization initiated."
|
||||
},
|
||||
"sync_job_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID of the created synchronization job."
|
||||
}
|
||||
},
|
||||
"required": ["message", "sync_job_id"]
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized: User not authenticated or Garmin Connect account not linked.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Not authenticated or Garmin Connect account not linked."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"429": {
|
||||
"description": "Too Many Requests: Rate limit exceeded for Garmin Connect API.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Rate limit exceeded. Please try again later."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error: Unexpected error during synchronization initiation.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "An unexpected error occurred."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
contracts/sync_garmin_health_metrics.json
Normal file
82
contracts/sync_garmin_health_metrics.json
Normal file
@@ -0,0 +1,82 @@
|
||||
{
|
||||
"endpoint": "/api/sync/garmin/health-metrics",
|
||||
"method": "POST",
|
||||
"description": "Triggers synchronization of Garmin Connect health metrics to CentralDB.",
|
||||
"request": {
|
||||
"headers": {
|
||||
"Authorization": "Bearer <token>"
|
||||
},
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"start_date": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"description": "Optional start date to sync health metrics from (YYYY-MM-DD). Defaults to last sync date."
|
||||
},
|
||||
"end_date": {
|
||||
"type": "string",
|
||||
"format": "date",
|
||||
"description": "Optional end date to sync health metrics until (YYYY-MM-DD). Defaults to today."
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"202": {
|
||||
"description": "Synchronization process initiated successfully.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Garmin health metrics synchronization initiated."
|
||||
},
|
||||
"sync_job_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID of the created synchronization job."
|
||||
}
|
||||
},
|
||||
"required": ["message", "sync_job_id"]
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized: User not authenticated or Garmin Connect account not linked.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Not authenticated or Garmin Connect account not linked."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"429": {
|
||||
"description": "Too Many Requests: Rate limit exceeded for Garmin Connect API.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Rate limit exceeded. Please try again later."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error: Unexpected error during synchronization initiation.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "An unexpected error occurred."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
90
contracts/sync_garmin_workouts.json
Normal file
90
contracts/sync_garmin_workouts.json
Normal file
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"endpoint": "/api/sync/garmin/workouts",
|
||||
"method": "POST",
|
||||
"description": "Uploads a workout from the application to Garmin Connect.",
|
||||
"request": {
|
||||
"headers": {
|
||||
"Authorization": "Bearer <token>"
|
||||
},
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"workout_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "The ID of the workout to upload from CentralDB."
|
||||
}
|
||||
},
|
||||
"required": ["workout_id"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"202": {
|
||||
"description": "Workout upload process initiated successfully.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"message": {
|
||||
"type": "string",
|
||||
"example": "Garmin workout upload initiated."
|
||||
},
|
||||
"sync_job_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "ID of the created synchronization job for the workout upload."
|
||||
}
|
||||
},
|
||||
"required": ["message", "sync_job_id"]
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized: User not authenticated or Garmin Connect account not linked.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Not authenticated or Garmin Connect account not linked."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"404": {
|
||||
"description": "Not Found: Workout with the specified ID not found.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Workout not found."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"429": {
|
||||
"description": "Too Many Requests: Rate limit exceeded for Garmin Connect API.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Rate limit exceeded. Please try again later."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error: Unexpected error during workout upload initiation.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "An unexpected error occurred during workout upload."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
113
contracts/sync_status.json
Normal file
113
contracts/sync_status.json
Normal file
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"endpoint": "/api/sync/status",
|
||||
"method": "GET",
|
||||
"description": "Retrieves the current status of ongoing or completed synchronization processes.",
|
||||
"request": {
|
||||
"headers": {
|
||||
"Authorization": "Bearer <token>"
|
||||
},
|
||||
"query_parameters": {
|
||||
"job_id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Optional: Filter status by a specific synchronization job ID."
|
||||
},
|
||||
"job_type": {
|
||||
"type": "string",
|
||||
"enum": ["activity_sync", "health_metrics_sync", "workout_upload"],
|
||||
"description": "Optional: Filter status by job type."
|
||||
},
|
||||
"limit": {
|
||||
"type": "integer",
|
||||
"minimum": 1,
|
||||
"maximum": 100,
|
||||
"default": 10,
|
||||
"description": "Optional: Maximum number of sync jobs to return."
|
||||
},
|
||||
"offset": {
|
||||
"type": "integer",
|
||||
"minimum": 0,
|
||||
"default": 0,
|
||||
"description": "Optional: Number of sync jobs to skip for pagination."
|
||||
}
|
||||
}
|
||||
},
|
||||
"response": {
|
||||
"200": {
|
||||
"description": "Returns a list of synchronization job statuses.",
|
||||
"body": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": {
|
||||
"type": "string",
|
||||
"format": "uuid",
|
||||
"description": "Unique identifier of the sync job."
|
||||
},
|
||||
"job_type": {
|
||||
"type": "string",
|
||||
"enum": ["activity_sync", "health_metrics_sync", "workout_upload"],
|
||||
"description": "Type of synchronization."
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": ["pending", "in_progress", "completed", "failed"],
|
||||
"description": "Current status of the job."
|
||||
},
|
||||
"started_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true,
|
||||
"description": "Timestamp when the job started."
|
||||
},
|
||||
"completed_at": {
|
||||
"type": "string",
|
||||
"format": "date-time",
|
||||
"nullable": true,
|
||||
"description": "Timestamp when the job completed."
|
||||
},
|
||||
"progress": {
|
||||
"type": "number",
|
||||
"format": "float",
|
||||
"minimum": 0.0,
|
||||
"maximum": 1.0,
|
||||
"nullable": true,
|
||||
"description": "Current progress (0.0-1.0)."
|
||||
},
|
||||
"error_message": {
|
||||
"type": "string",
|
||||
"nullable": true,
|
||||
"description": "Details of any error encountered."
|
||||
}
|
||||
},
|
||||
"required": ["id", "job_type", "status"]
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized: User not authenticated.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "Not authenticated."
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"500": {
|
||||
"description": "Internal Server Error: Unexpected error retrieving status.",
|
||||
"body": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"detail": {
|
||||
"type": "string",
|
||||
"example": "An unexpected error occurred."
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user