Files
FitTrack_GarminSync/specs/004-home-sstent-projects/tasks.md

7.4 KiB

Tasks: Simplify Sync Job Management with Progress Tracking

Feature Branch: 004-home-sstent-projects | Date: Saturday, October 11, 2025 | Spec: /home/sstent/Projects/FitTrack_GarminSync/specs/004-home-sstent-projects/spec.md

Phase 1: Setup Tasks

(No specific setup tasks identified beyond the existing project structure. Foundational components will be created in Phase 2.)

Phase 2: Foundational Tasks

These tasks establish the core components required for the single sync job management and progress tracking.

  • T001: Create backend/src/models/sync_job.py to define the SyncJob Pydantic model with status, progress, start_time, end_time, error_message, and job_type attributes. [P]
  • T002: Create backend/src/services/sync_manager.py to implement the CurrentSyncJobManager (singleton) with methods start_sync, update_progress, complete_sync, fail_sync, get_current_sync_status, and is_sync_active. [P]
  • T003: Update backend/src/dependencies.py to remove references to the old job_store and SyncStatusService. [P]
  • T004: Delete backend/src/jobs.py. [P]
  • T005: Delete backend/src/services/sync_status_service.py. [P]

Phase 3: User Story 1 - Initiate a Sync and Monitor Progress (P1)

Story Goal: As a user, I want to initiate a data synchronization (activities, health, or workouts) and be able to monitor its progress in real-time, so I know the system is working and when it's complete or if it has failed.

Independent Test Criteria: This can be fully tested by initiating any type of sync (e.g., activity sync) and repeatedly querying the status API until the sync completes or fails. It delivers immediate value by informing the user about the state of their data synchronization.

  • T006 [US1]: Modify backend/src/api/garmin_sync.py to import CurrentSyncJobManager and SyncJob from the new modules. [P]
  • T007 [US1]: Modify backend/src/api/garmin_sync.py to remove the old SyncJob import and the /status/{job_id} endpoint. [P]
  • T008 [US1]: Modify backend/src/api/garmin_sync.py to update the POST /garmin/activities endpoint:
    • Implement the single-sync enforcement using CurrentSyncJobManager.is_sync_active().
    • Call CurrentSyncJobManager.start_sync(job_type="activities").
    • Pass the SyncJob instance (or a reference to the CurrentSyncJobManager) to garmin_activity_service.sync_activities_in_background.
    • Change the response_model to a simple success message. [P]
  • T009 [US1]: Modify backend/src/api/garmin_sync.py to update the POST /garmin/workouts endpoint:
    • Implement the single-sync enforcement using CurrentSyncJobManager.is_sync_active().
    • Call CurrentSyncJobManager.start_sync(job_type="workouts").
    • Pass the SyncJob instance (or a reference to the CurrentSyncJobManager) to garmin_workout_service.upload_workout_in_background.
    • Change the response_model to a simple success message. [P]
  • T010 [US1]: Modify backend/src/api/garmin_sync.py to update the POST /garmin/health endpoint:
    • Implement the single-sync enforcement using CurrentSyncJobManager.is_sync_active().
    • Call CurrentSyncJobManager.start_sync(job_type="health").
    • Pass the SyncJob instance (or a reference to the CurrentSyncJobManager) to garmin_health_service.sync_health_metrics_in_background.
    • Change the response_model to a simple success message. [P]
  • T011 [US1]: Add GET /garmin/sync/status API endpoint to backend/src/api/garmin_sync.py that returns the current SyncJob status from CurrentSyncJobManager.get_current_sync_status(). [P]
  • T012 [US1]: Modify backend/src/services/garmin_activity_service.py:
    • Remove job_id parameter from sync_activities_in_background.
    • Accept SyncJob instance (or CurrentSyncJobManager) as a parameter.
    • Replace job_store.update_job calls with CurrentSyncJobManager.update_progress, complete_sync, and fail_sync. [P]
  • T013 [US1]: Modify backend/src/services/garmin_workout_service.py:
    • Remove job_id parameter from upload_workout_in_background.
    • Accept SyncJob instance (or CurrentSyncJobManager) as a parameter.
    • Replace job_store.update_job calls with CurrentSyncJobManager.update_progress, complete_sync, and fail_sync. [P]
  • T014 [US1]: Modify backend/src/services/garmin_health_service.py:
    • Remove job_id parameter from sync_health_metrics_in_background.
    • Accept SyncJob instance (or CurrentSyncJobManager) as a parameter.
    • Replace job_store.update_job calls with CurrentSyncJobManager.update_progress, complete_sync, and fail_sync. [P]
  • T015 [US1]: Update backend/src/main.py to ensure CurrentSyncJobManager is properly initialized and accessible (e.g., as a global or via dependency injection if preferred). [P]

Phase 4: Polish & Cross-Cutting Concerns

  • T016: Add unit tests for backend/src/models/sync_job.py. [P]
  • T017: Add unit tests for backend/src/services/sync_manager.py. [P]
  • T018: Add API integration tests for GET /garmin/sync/status endpoint. [P]
  • T019: Add API integration tests for POST /garmin/activities (success and conflict scenarios). [P]
  • T020: Add API integration tests for POST /garmin/workouts (success and conflict scenarios). [P]
  • T021: Add API integration tests for POST /garmin/health (success and conflict scenarios). [P]
  • T022: Ensure all new and modified code adheres to Python 3.13 style guidelines (type hints, Black formatting, Flake8 linting). [P]

Dependencies

graph TD
    A[T001: Create SyncJob Model] --> B(T002: Create SyncManager Service)
    A --> C(T003: Update dependencies.py)
    A --> D(T004: Delete jobs.py)
    A --> E(T005: Delete sync_status_service.py)
    B --> F(T006: Modify garmin_sync.py imports)
    B --> G(T012: Modify garmin_activity_service.py)
    B --> H(T013: Modify garmin_workout_service.py)
    B --> I(T014: Modify garmin_health_service.py)
    F --> J(T007: Modify garmin_sync.py remove old endpoint)
    J --> K(T008: Modify POST /garmin/activities)
    J --> L(T009: Modify POST /garmin/workouts)
    J --> M(T010: Modify POST /garmin/health)
    J --> N(T011: Add GET /garmin/sync/status)
    K --> O(T015: Update main.py)
    L --> O
    M --> O
    N --> O
    O --> P(T016: Unit tests for SyncJob)
    O --> Q(T017: Unit tests for SyncManager)
    O --> R(T018: API tests for GET /garmin/sync/status)
    O --> S(T019: API tests for POST /garmin/activities)
    O --> T(T020: API tests for POST /garmin/workouts)
    O --> U(T021: API tests for POST /garmin/health)
    O --> V(T022: Code style adherence)

Parallel Execution Examples

  • After T005 (Foundational Tasks): T006, T007, T012, T013, T014 can be worked on in parallel.
  • After T015 (User Story 1 Implementation): T016, T017, T018, T019, T020, T021, T022 (all testing and polish tasks) can be worked on in parallel.

Implementation Strategy

This feature will be implemented using an MVP-first approach, focusing on delivering the core functionality of User Story 1. The tasks are ordered to build foundational components first, then implement the core user story functionality, and finally add comprehensive testing and polish. Each user story phase is designed to be an independently testable increment.