mirror of
https://github.com/sstent/FitTrack_GarminSync.git
synced 2026-01-25 16:41:41 +00:00
Complete implementation planning for CLI app with MFA
- Created implementation plan with technical context - Developed data models for User Session, Sync Job, and Authentication Token - Defined API contracts for authentication, sync triggering, and status checking - Created quickstart guide for CLI usage - Updated agent context with new technology stack - Verified constitution compliance for all design decisions
This commit is contained in:
112
specs/006-cli-auth-sync-mfa/contracts/auth_cli_login.yaml
Normal file
112
specs/006-cli-auth-sync-mfa/contracts/auth_cli_login.yaml
Normal file
@@ -0,0 +1,112 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: GarminSync CLI Authentication API
|
||||
version: 1.0.0
|
||||
description: API for CLI-based authentication with MFA support
|
||||
paths:
|
||||
/api/auth/cli/login:
|
||||
post:
|
||||
summary: Authenticate user via CLI with optional MFA
|
||||
description: Authenticates a user with username/password and optional MFA code
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
required:
|
||||
- username
|
||||
- password
|
||||
properties:
|
||||
username:
|
||||
type: string
|
||||
description: User's email or username
|
||||
password:
|
||||
type: string
|
||||
description: User's password
|
||||
mfa_code:
|
||||
type: string
|
||||
description: MFA code if required
|
||||
remember_me:
|
||||
type: boolean
|
||||
description: Whether to store tokens for future use
|
||||
responses:
|
||||
'200':
|
||||
description: Authentication successful
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
session_id:
|
||||
type: string
|
||||
description: Unique session identifier
|
||||
access_token:
|
||||
type: string
|
||||
description: Access token for API calls
|
||||
token_type:
|
||||
type: string
|
||||
description: Type of token (e.g., Bearer)
|
||||
expires_in:
|
||||
type: integer
|
||||
description: Time until token expiration in seconds
|
||||
mfa_required:
|
||||
type: boolean
|
||||
description: Whether MFA is required for this account
|
||||
user:
|
||||
type: object
|
||||
properties:
|
||||
id:
|
||||
type: string
|
||||
description: User identifier
|
||||
email:
|
||||
type: string
|
||||
description: User's email
|
||||
username:
|
||||
type: string
|
||||
description: User's username
|
||||
'400':
|
||||
description: Invalid credentials or missing required fields
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
mfa_required:
|
||||
type: boolean
|
||||
description: Whether MFA is required for this account
|
||||
'401':
|
||||
description: Authentication failed
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
'429':
|
||||
description: Too many failed attempts
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
185
specs/006-cli-auth-sync-mfa/contracts/sync_cli_status.yaml
Normal file
185
specs/006-cli-auth-sync-mfa/contracts/sync_cli_status.yaml
Normal file
@@ -0,0 +1,185 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: GarminSync CLI Sync Status API
|
||||
version: 1.0.0
|
||||
description: API for checking sync job status via CLI
|
||||
paths:
|
||||
/api/sync/cli/status:
|
||||
get:
|
||||
summary: Check status of sync operations
|
||||
description: Retrieves the status of current and recent sync jobs
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: job_id
|
||||
in: query
|
||||
required: false
|
||||
description: Specific job ID to check (returns all recent if not provided)
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Sync status information retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
jobs:
|
||||
type: array
|
||||
items:
|
||||
type: object
|
||||
properties:
|
||||
job_id:
|
||||
type: string
|
||||
description: Unique identifier for the sync job
|
||||
status:
|
||||
type: string
|
||||
description: Current status of the sync job
|
||||
enum: [pending, running, completed, failed, cancelled]
|
||||
progress:
|
||||
type: number
|
||||
format: float
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description: Percentage of completion (0-100)
|
||||
sync_type:
|
||||
type: string
|
||||
enum: [activities, health, workouts]
|
||||
description: Type of data being synced
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the job was created
|
||||
started_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the job started executing
|
||||
completed_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the job completed (if completed)
|
||||
total_items:
|
||||
type: integer
|
||||
description: Total number of items to sync
|
||||
processed_items:
|
||||
type: integer
|
||||
description: Number of items processed so far
|
||||
error_message:
|
||||
type: string
|
||||
description: Error details if job failed
|
||||
'401':
|
||||
description: Authentication required or invalid token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
|
||||
/api/sync/cli/status/{job_id}:
|
||||
get:
|
||||
summary: Check status of a specific sync job
|
||||
description: Retrieves the status of a specific sync job by ID
|
||||
security:
|
||||
- bearerAuth: []
|
||||
parameters:
|
||||
- name: job_id
|
||||
in: path
|
||||
required: true
|
||||
description: Unique identifier of the sync job
|
||||
schema:
|
||||
type: string
|
||||
responses:
|
||||
'200':
|
||||
description: Specific sync job status retrieved successfully
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
job:
|
||||
type: object
|
||||
properties:
|
||||
job_id:
|
||||
type: string
|
||||
description: Unique identifier for the sync job
|
||||
status:
|
||||
type: string
|
||||
description: Current status of the sync job
|
||||
enum: [pending, running, completed, failed, cancelled]
|
||||
progress:
|
||||
type: number
|
||||
format: float
|
||||
minimum: 0
|
||||
maximum: 100
|
||||
description: Percentage of completion (0-100)
|
||||
sync_type:
|
||||
type: string
|
||||
enum: [activities, health, workouts]
|
||||
description: Type of data being synced
|
||||
created_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the job was created
|
||||
started_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the job started executing
|
||||
completed_at:
|
||||
type: string
|
||||
format: date-time
|
||||
description: When the job completed (if completed)
|
||||
total_items:
|
||||
type: integer
|
||||
description: Total number of items to sync
|
||||
processed_items:
|
||||
type: integer
|
||||
description: Number of items processed so far
|
||||
error_message:
|
||||
type: string
|
||||
description: Error details if job failed
|
||||
'401':
|
||||
description: Authentication required or invalid token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
'404':
|
||||
description: Sync job not found
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
107
specs/006-cli-auth-sync-mfa/contracts/sync_cli_trigger.yaml
Normal file
107
specs/006-cli-auth-sync-mfa/contracts/sync_cli_trigger.yaml
Normal file
@@ -0,0 +1,107 @@
|
||||
openapi: 3.0.0
|
||||
info:
|
||||
title: GarminSync CLI Sync Trigger API
|
||||
version: 1.0.0
|
||||
description: API for triggering sync operations via CLI
|
||||
paths:
|
||||
/api/sync/cli/trigger:
|
||||
post:
|
||||
summary: Trigger a sync operation via CLI
|
||||
description: Initiates a data sync operation for the authenticated user
|
||||
security:
|
||||
- bearerAuth: []
|
||||
requestBody:
|
||||
required: true
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
sync_type:
|
||||
type: string
|
||||
enum: [activities, health, workouts]
|
||||
description: Type of data to sync
|
||||
date_range:
|
||||
type: object
|
||||
properties:
|
||||
start_date:
|
||||
type: string
|
||||
format: date
|
||||
description: Start date for sync (YYYY-MM-DD)
|
||||
end_date:
|
||||
type: string
|
||||
format: date
|
||||
description: End date for sync (YYYY-MM-DD)
|
||||
force_full_sync:
|
||||
type: boolean
|
||||
description: Whether to perform a full sync instead of incremental
|
||||
responses:
|
||||
'200':
|
||||
description: Sync operation successfully initiated
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: true
|
||||
job_id:
|
||||
type: string
|
||||
description: Unique identifier for the sync job
|
||||
status:
|
||||
type: string
|
||||
description: Current status of the sync job
|
||||
enum: [pending, running]
|
||||
message:
|
||||
type: string
|
||||
description: Status message
|
||||
'400':
|
||||
description: Invalid request parameters
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
'401':
|
||||
description: Authentication required or invalid token
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
'409':
|
||||
description: Sync already in progress for this user
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
success:
|
||||
type: boolean
|
||||
example: false
|
||||
error:
|
||||
type: string
|
||||
description: Error message
|
||||
active_job_id:
|
||||
type: string
|
||||
description: ID of the currently active job
|
||||
|
||||
components:
|
||||
securitySchemes:
|
||||
bearerAuth:
|
||||
type: http
|
||||
scheme: bearer
|
||||
bearerFormat: JWT
|
||||
71
specs/006-cli-auth-sync-mfa/data-model.md
Normal file
71
specs/006-cli-auth-sync-mfa/data-model.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# Data Model: CLI App for API Interaction with MFA
|
||||
|
||||
## Key Entities
|
||||
|
||||
### User Session
|
||||
Represents an authenticated user session with associated tokens and permissions
|
||||
|
||||
**Attributes:**
|
||||
- `session_id`: Unique identifier for the session
|
||||
- `user_id`: Identifier for the authenticated user
|
||||
- `access_token`: JWT or API token for authenticated requests
|
||||
- `refresh_token`: Token used to refresh the access token
|
||||
- `expires_at`: Timestamp when the access token expires
|
||||
- `mfa_enabled`: Boolean indicating if MFA is required for this session
|
||||
- `created_at`: Timestamp when the session was created
|
||||
- `last_used_at`: Timestamp of last activity with this session
|
||||
|
||||
### Sync Job
|
||||
Represents an initiated sync operation with status, progress, and metadata
|
||||
|
||||
**Attributes:**
|
||||
- `job_id`: Unique identifier for the sync job
|
||||
- `user_id`: Identifier of the user who initiated the job
|
||||
- `status`: Current status (pending, running, completed, failed, cancelled)
|
||||
- `progress`: Percentage of completion (0-100)
|
||||
- `start_time`: Timestamp when the sync started
|
||||
- `end_time`: Timestamp when the sync completed (if completed)
|
||||
- `sync_type`: Type of sync (activities, health, workouts, etc.)
|
||||
- `error_message`: Error details if the job failed
|
||||
- `total_items`: Total number of items to sync
|
||||
- `processed_items`: Number of items processed so far
|
||||
|
||||
### Authentication Token
|
||||
Secure credential used to access the API on behalf of the user
|
||||
|
||||
**Attributes:**
|
||||
- `token_id`: Unique identifier for the token
|
||||
- `user_id`: Identifier of the user this token represents
|
||||
- `access_token`: The actual access token value
|
||||
- `token_type`: Type of token (Bearer, etc.)
|
||||
- `expires_in`: Time until expiration in seconds
|
||||
- `scope`: Permissions associated with this token
|
||||
- `created_at`: Timestamp when token was created
|
||||
- `last_used_at`: Timestamp of last usage
|
||||
- `mfa_verified`: Boolean indicating if MFA was completed for this token
|
||||
|
||||
## Relationships
|
||||
|
||||
1. **User Session** 1 → * **Sync Job**: A user session can have multiple sync jobs
|
||||
2. **Authentication Token** 1 → 1 **User Session**: Each session is associated with one primary auth token
|
||||
|
||||
## Validation Rules
|
||||
|
||||
From Functional Requirements:
|
||||
- **FR-005**: Authentication tokens must be stored securely with appropriate file permissions
|
||||
- **FR-008**: Expired tokens must be refreshed automatically when possible
|
||||
- **FR-007**: All operations must provide clear feedback on success or failure
|
||||
|
||||
## State Transitions
|
||||
|
||||
### Sync Job Status Transitions
|
||||
- `pending` → `running` (when sync starts)
|
||||
- `running` → `completed` (when sync finishes successfully)
|
||||
- `running` → `failed` (when sync encounters an error)
|
||||
- `pending` → `cancelled` (when user cancels before start)
|
||||
- `running` → `cancelled` (when user cancels during execution)
|
||||
|
||||
### Session Expiration
|
||||
- Active session remains valid until `expires_at` timestamp
|
||||
- Session marked as invalid after expiration
|
||||
- Automatic refresh attempted if refresh token exists
|
||||
105
specs/006-cli-auth-sync-mfa/plan.md
Normal file
105
specs/006-cli-auth-sync-mfa/plan.md
Normal file
@@ -0,0 +1,105 @@
|
||||
# Implementation Plan: CLI App for API Interaction with MFA
|
||||
|
||||
**Branch**: `006-cli-auth-sync-mfa` | **Date**: Thursday, December 18, 2025 | **Spec**: /home/sstent/Projects/FitTrack/GarminSync/specs/006-cli-auth-sync-mfa/spec.md
|
||||
**Input**: User description: "create a simple python CLI app for interacting with our API to authenticate the user, trigger a sync, and see the sync status. Allow for the use of MFA on the acct."
|
||||
|
||||
## Summary
|
||||
|
||||
This feature implements a text-based command-line interface that allows users to authenticate with the API (with MFA support), trigger sync operations, and check sync status. The implementation follows the project's constitution standards, using Python 3.13 with appropriate libraries for CLI interface, authentication, and API communication.
|
||||
|
||||
## Technical Context
|
||||
|
||||
**Language/Version**: Python 3.13 (Constitution requirement: Python Modernization principle)
|
||||
**Primary Dependencies**: Click/Typer for CLI (Constitution requirement: cli_interface standard), httpx for API calls, pydantic for data validation, garth/garminconnect for Garmin authentication
|
||||
**Storage**: Local file storage for authentication tokens and configuration (JSON/YAML format)
|
||||
**Testing**: pytest (Constitution requirement: TDD principle) for unit and integration tests
|
||||
**Target Platform**: Linux, macOS, Windows command-line environments
|
||||
**Project Type**: Single project CLI application
|
||||
**Performance Goals**: Authentication in under 30 seconds (per spec SC-001), status checks in under 5 seconds (per spec SC-003)
|
||||
**Constraints**: Secure handling of credentials and tokens, support for MFA flows, offline token storage
|
||||
**Scale/Scope**: Individual user tool, single-user operation, designed for personal use scenarios
|
||||
|
||||
## Constitution Check
|
||||
|
||||
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
|
||||
|
||||
- **Python Modernization**: Compliant (Python 3.13, type hints, dataclasses for models)
|
||||
- **Virtual Environment Isolation**: Compliant (uses .venv, dependencies will be pinned)
|
||||
- **Test-Driven Development**: Compliant (pytest for testing, will follow TDD approach)
|
||||
- **Containerization Standards**: Not applicable (CLI tool, not a containerized service)
|
||||
- **Project Structure Standards**: Compliant (follows src/ structure with models, services, etc.)
|
||||
- **Service-Specific Standards**:
|
||||
- **cli_interface**: Compliant (using Click as required by constitution, YAML config, multiple output formats)
|
||||
- **API Standards**: Compliant (will interact with existing API endpoints following REST patterns)
|
||||
- **Code Quality Standards**: Compliant (will use Black, Flake8, Mypy, Isort as required)
|
||||
- **Dependency Management**: Compliant (will use requirements.txt with pinned dependencies)
|
||||
|
||||
All constitution gates pass. No violations detected post-design.
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
```
|
||||
specs/006-cli-auth-sync-mfa/
|
||||
├── plan.md # This file (/speckit.plan command output)
|
||||
├── research.md # Phase 0 output (/speckit.plan command)
|
||||
├── data-model.md # Phase 1 output (/speckit.plan command)
|
||||
├── quickstart.md # Phase 1 output (/speckit.plan command)
|
||||
├── contracts/ # Phase 1 output (/speckit.plan command)
|
||||
└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)
|
||||
```
|
||||
|
||||
### Source Code (repository root)
|
||||
|
||||
```
|
||||
cli/
|
||||
├── src/
|
||||
│ ├── __init__.py
|
||||
│ ├── main.py # CLI entry point with commands for auth, sync, status
|
||||
│ ├── auth/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── auth_manager.py # Handles authentication flows with MFA support
|
||||
│ │ └── token_manager.py # Manages local token storage and refresh
|
||||
│ ├── api/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── client.py # API client for communicating with backend
|
||||
│ │ └── endpoints.py # API endpoint definitions
|
||||
│ ├── models/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── session.py # User session data model
|
||||
│ │ ├── sync_job.py # Sync job data model
|
||||
│ │ └── token.py # Authentication token model
|
||||
│ ├── commands/
|
||||
│ │ ├── __init__.py
|
||||
│ │ ├── auth_cmd.py # Authentication command implementation
|
||||
│ │ ├── sync_cmd.py # Sync triggering command implementation
|
||||
│ │ └── status_cmd.py # Status checking command implementation
|
||||
│ └── utils/
|
||||
│ ├── __init__.py
|
||||
│ ├── config.py # Configuration handling
|
||||
│ ├── output.py # Output formatting (JSON, table, CSV)
|
||||
│ └── validators.py # Input validation utilities
|
||||
├── tests/
|
||||
│ ├── unit/
|
||||
│ │ ├── test_auth_manager.py
|
||||
│ │ ├── test_token_manager.py
|
||||
│ │ ├── test_api_client.py
|
||||
│ │ └── test_commands.py
|
||||
│ ├── integration/
|
||||
│ │ ├── test_auth_flow.py
|
||||
│ │ └── test_sync_operations.py
|
||||
│ └── contract/
|
||||
│ └── test_api_contracts.py
|
||||
└── requirements.txt
|
||||
```
|
||||
|
||||
**Structure Decision**: Created a dedicated CLI directory with a modular structure following the constitution's source structure requirements. The CLI module will follow the cli_interface standards from the constitution, using Click/Typer for the interface and supporting configuration and output formats as required.
|
||||
|
||||
## Complexity Tracking
|
||||
|
||||
*Fill ONLY if Constitution Check has violations that must be justified*
|
||||
|
||||
| Violation | Why Needed | Simpler Alternative Rejected Because |
|
||||
|-----------|------------|-------------------------------------|
|
||||
| (None) | (None) | (None) |
|
||||
171
specs/006-cli-auth-sync-mfa/quickstart.md
Normal file
171
specs/006-cli-auth-sync-mfa/quickstart.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# Quickstart Guide: CLI App for API Interaction with MFA
|
||||
|
||||
## Overview
|
||||
|
||||
This guide provides essential steps for setting up and using the GarminSync CLI application to authenticate with MFA support, trigger sync operations, and check sync status.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before you begin, ensure you have the following installed:
|
||||
|
||||
* **Python 3.13+**: The CLI application is built with Python 3.13 as required by project standards.
|
||||
* [Install Python](https://www.python.org/downloads/)
|
||||
* **Git**: For cloning the repository (if installing from source).
|
||||
|
||||
## Installation
|
||||
|
||||
### Option 1: Install from Package (Recommended)
|
||||
|
||||
```bash
|
||||
pip install garmin-sync-cli
|
||||
```
|
||||
|
||||
### Option 2: Install from Source
|
||||
|
||||
1. Clone the repository:
|
||||
```bash
|
||||
git clone <repository-url>
|
||||
cd <repository-name>
|
||||
```
|
||||
|
||||
2. Navigate to the CLI directory:
|
||||
```bash
|
||||
cd cli
|
||||
```
|
||||
|
||||
3. Install the CLI application in a virtual environment:
|
||||
```bash
|
||||
python -m venv .venv
|
||||
source .venv/bin/activate # On Windows: .venv\Scripts\activate
|
||||
pip install -r requirements.txt
|
||||
pip install -e .
|
||||
```
|
||||
|
||||
## Basic Usage
|
||||
|
||||
### 1. Authentication
|
||||
|
||||
To authenticate with your account (without MFA):
|
||||
|
||||
```bash
|
||||
garmin-sync auth --username your_email@example.com --password your_password
|
||||
```
|
||||
|
||||
To authenticate with your account (with MFA):
|
||||
|
||||
```bash
|
||||
garmin-sync auth --username your_email@example.com --password your_password --mfa-code 123456
|
||||
```
|
||||
|
||||
For interactive authentication (recommended for MFA):
|
||||
|
||||
```bash
|
||||
garmin-sync auth --interactive
|
||||
```
|
||||
|
||||
This will prompt you for your credentials and MFA code if required.
|
||||
|
||||
### 2. Trigger a Sync
|
||||
|
||||
After authenticating, trigger a sync operation:
|
||||
|
||||
```bash
|
||||
garmin-sync sync trigger --type activities --start-date 2024-01-01 --end-date 2024-01-31
|
||||
```
|
||||
|
||||
Available sync types: `activities`, `health`, `workouts`
|
||||
|
||||
For a full sync (not incremental):
|
||||
|
||||
```bash
|
||||
garmin-sync sync trigger --type activities --force-full
|
||||
```
|
||||
|
||||
### 3. Check Sync Status
|
||||
|
||||
Check the status of all recent sync jobs:
|
||||
|
||||
```bash
|
||||
garmin-sync sync status
|
||||
```
|
||||
|
||||
Check the status of a specific sync job:
|
||||
|
||||
```bash
|
||||
garmin-sync sync status --job-id abc123def456
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
The CLI application stores authentication tokens and configuration in your home directory:
|
||||
|
||||
* `~/.garmin-sync/config.yaml`: Configuration settings
|
||||
* `~/.garmin-sync/tokens.json`: Encrypted authentication tokens
|
||||
|
||||
### Custom Configuration
|
||||
|
||||
You can create a custom configuration file at `~/.garmin-sync/config.yaml`:
|
||||
|
||||
```yaml
|
||||
api_base_url: https://api.yourdomain.com
|
||||
default_timeout: 30
|
||||
output_format: table # Options: table, json, csv
|
||||
remember_login: true
|
||||
```
|
||||
|
||||
## Output Formats
|
||||
|
||||
The CLI supports multiple output formats:
|
||||
|
||||
* **Table** (default): Human-readable tabular format
|
||||
* **JSON**: Structured JSON output for scripting
|
||||
* **CSV**: Comma-separated values for data analysis
|
||||
|
||||
Specify output format with the `--format` option:
|
||||
|
||||
```bash
|
||||
garmin-sync sync status --format json
|
||||
```
|
||||
|
||||
## Help
|
||||
|
||||
Get help with any command:
|
||||
|
||||
```bash
|
||||
garmin-sync --help
|
||||
garmin-sync auth --help
|
||||
garmin-sync sync --help
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
### Authenticate and Sync Activities
|
||||
|
||||
```bash
|
||||
# Authenticate interactively
|
||||
garmin-sync auth --interactive
|
||||
|
||||
# Trigger a sync for recent activities
|
||||
garmin-sync sync trigger --type activities --start-date $(date -d "7 days ago" +%Y-%m-%d)
|
||||
|
||||
# Check the status of the sync
|
||||
garmin-sync sync status
|
||||
```
|
||||
|
||||
### Check All Sync Jobs in JSON Format
|
||||
|
||||
```bash
|
||||
garmin-sync sync status --format json
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Authentication Issues
|
||||
* Ensure your credentials are correct
|
||||
* If using MFA, make sure your code is current
|
||||
* Clear stored tokens if needed: `garmin-sync auth logout`
|
||||
|
||||
### Sync Issues
|
||||
* Check your internet connection
|
||||
* Verify API endpoint accessibility
|
||||
* Check if your account has proper permissions
|
||||
33
specs/006-cli-auth-sync-mfa/research.md
Normal file
33
specs/006-cli-auth-sync-mfa/research.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Research Findings for CLI App with MFA Support
|
||||
|
||||
## Phase 0: Outline & Research
|
||||
|
||||
### Decision
|
||||
Selected Click as the CLI framework for the Python application based on the project constitution's requirement for CLI interfaces (must be Click or Typer). Decided to create a new CLI module that interfaces with the existing API structure.
|
||||
|
||||
### Rationale
|
||||
- The constitution specifically requires either Click or Typer for CLI interfaces
|
||||
- Click provides excellent support for multi-level commands which is needed for auth/sync/status operations
|
||||
- Click has good support for handling MFA flows through prompts
|
||||
- Consistent with the existing backend architecture of the project
|
||||
|
||||
### Technology Choices Made
|
||||
- **CLI Framework**: Click (as required by constitution)
|
||||
- **API Client**: httpx (modern, async-capable, excellent for API interactions)
|
||||
- **Configuration**: YAML (as required by constitution)
|
||||
- **Output Formats**: JSON, table, CSV (as required by constitution)
|
||||
- **Token Storage**: Local JSON file with appropriate security measures
|
||||
- **Authentication Flow**: OAuth2/MFA integration with existing backend API
|
||||
|
||||
### Alternatives Considered
|
||||
- **Typer vs Click**: Typer offers better type hints integration, but Click was selected to match constitution requirements
|
||||
- **argparse**: Simpler but lacks the advanced features needed for this CLI application
|
||||
- **Direct HTTP requests**: httpx was chosen over basic requests library for better async support and API interactions
|
||||
|
||||
### Integration Approach
|
||||
The CLI app will integrate with the existing backend API, reusing authentication mechanisms and sync endpoints. This approach leverages existing functionality while providing a new interface for users who prefer command-line operations.
|
||||
|
||||
### Security Considerations
|
||||
- Local token storage will use appropriate file permissions (600)
|
||||
- MFA handling will follow platform-appropriate secure input methods
|
||||
- Token refresh mechanisms will be implemented to handle expiration
|
||||
Reference in New Issue
Block a user