mirror of
https://github.com/sstent/FitTrack_GarminSync.git
synced 2026-02-07 06:52:22 +00:00
86 lines
7.0 KiB
Markdown
86 lines
7.0 KiB
Markdown
# Feature Specification: Garmin Login Improvements
|
|
|
|
**Feature Branch**: `003-loginimprovements-use-the`
|
|
**Created**: Friday, October 10, 2025
|
|
**Status**: Draft
|
|
**Input**: User description: "Rework the garmin authentication for this app. I want the app to: allow providing a user/pass via the /login endpoint; the app should store the resulting auth tokens and user/pass in the centralDB; the api caller should not need a cookie - all state should be global for the Garmin Sync service"
|
|
|
|
## User Scenarios & Testing *(mandatory)*
|
|
|
|
### User Story 1 - Initial Garmin Account Setup (Priority: P1)
|
|
|
|
A user wants to link their Garmin account to the FitTrack Garmin Sync service for the first time. They provide their Garmin credentials via the `/login` endpoint. The system successfully authenticates with Garmin, stores the credentials and tokens, and confirms the link.
|
|
|
|
**Why this priority**: This is the core functionality enabling users to connect their Garmin accounts, which is fundamental to the service.
|
|
|
|
**Independent Test**: Can be fully tested by calling the `/login` endpoint with valid Garmin credentials and verifying that the credentials and tokens are stored in the `centralDB` and subsequent Garmin Sync operations can proceed.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** the FitTrack Garmin Sync service is running, **When** a user sends a POST request to `/login` with valid Garmin username and password, **Then** the system successfully authenticates with Garmin, stores the Garmin username, plaintext password, and authentication tokens in the `centralDB`, and returns a success response.
|
|
2. **Given** the FitTrack Garmin Sync service is running, **When** a user sends a POST request to `/login` with invalid Garmin username or password, **Then** the system returns an error response indicating authentication failure and does not store any credentials or tokens.
|
|
|
|
---
|
|
|
|
### User Story 2 - Automatic Garmin Token Refresh (Priority: P1)
|
|
|
|
After initial setup, the system automatically manages the Garmin authentication tokens, refreshing them as needed without user intervention, to ensure continuous synchronization with Garmin.
|
|
|
|
**Why this priority**: Ensures the service remains operational and data synchronization is uninterrupted, providing a seamless user experience.
|
|
|
|
**Independent Test**: Can be tested by simulating an expired token scenario and verifying that the system successfully refreshes the token during a subsequent Garmin API call.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** valid Garmin credentials and tokens are stored in the `centralDB`, and the current Garmin authentication token is nearing expiration or has expired, **When** the Garmin Sync service attempts to perform an operation requiring Garmin authentication, **Then** the system automatically refreshes the Garmin authentication token using the stored credentials, updates the `centralDB` with the new tokens, and successfully completes the Garmin operation.
|
|
2. **Given** valid Garmin credentials and tokens are stored in the `centralDB`, and the current Garmin authentication token is valid, **When** the Garmin Sync service attempts to perform an operation requiring Garmin authentication, **Then** the system uses the existing valid token without attempting a refresh.
|
|
|
|
---
|
|
|
|
### User Story 3 - Stateless Garmin Sync Operations (Priority: P1)
|
|
|
|
The Garmin Sync service operates without relying on session cookies. For every operation requiring Garmin access, it retrieves the necessary authentication tokens from the `centralDB` based on the single-user context.
|
|
|
|
**Why this priority**: This is a core architectural requirement for the service to be stateless and not rely on client-side cookies.
|
|
|
|
**Independent Test**: Can be tested by performing multiple Garmin Sync operations (e.g., activity download, health metric sync) and verifying that each operation successfully retrieves credentials from the `centralDB` and completes without requiring a prior session.
|
|
|
|
**Acceptance Scenarios**:
|
|
|
|
1. **Given** valid Garmin credentials and tokens are stored in the `centralDB`, **When** any Garmin Sync operation is initiated, **Then** the service retrieves the necessary Garmin authentication tokens from the `centralDB` for the single user and uses them to authenticate with Garmin.
|
|
2. **Given** no valid Garmin credentials or tokens are stored in the `centralDB`, **When** any Garmin Sync operation is initiated, **Then** the service returns an error indicating that Garmin authentication is required.
|
|
|
|
## Requirements *(mandatory)*
|
|
|
|
### Functional Requirements
|
|
|
|
- **FR-001**: The system MUST expose a `/login` endpoint that accepts a Garmin username and password.
|
|
- **FR-002**: The system MUST authenticate with Garmin using the provided username and password.
|
|
- **FR-003**: Upon successful Garmin authentication, the system MUST store the Garmin username, plaintext password, and authentication tokens in the `centralDB`.
|
|
- **FR-004**: The system MUST automatically refresh Garmin authentication tokens when they are expired or nearing expiration.
|
|
- **FR-005**: The system MUST update the `centralDB` with newly refreshed Garmin authentication tokens.
|
|
- **FR-006**: The system MUST retrieve Garmin authentication tokens from the `centralDB` for all Garmin Sync operations. **The client is not required to send any authentication header for these operations.**
|
|
- **FR-007**: The system MUST return an error response to the API caller if Garmin authentication fails (initial login or token refresh).
|
|
- **FR-008**: The system MUST operate as a single-user system, using the single set of stored Garmin credentials for all operations.
|
|
- **FR-009**: The `/login` endpoint MUST be publicly accessible without prior authentication.
|
|
|
|
## Clarifications
|
|
|
|
### Session 2025-10-10
|
|
|
|
- Q: How should the client authenticate for subsequent sync operations (e.g., `/api/sync/garmin/activities`) given that the spec states "the api caller should not need a cookie" and "all state should be global for the Garmin Sync service", but the contract for `sync_garmin_activities` shows an `Authorization: Bearer <token>` header? → A: No authentication header is required; the backend implicitly uses the single stored Garmin credentials.
|
|
|
|
### Key Entities *(include if feature involves data)*
|
|
|
|
- **GarminCredentials**: Represents the stored Garmin authentication information.
|
|
* Attributes: `garmin_username` (string), `garmin_password_plaintext` (string), `access_token` (string), `access_token_secret` (string), `token_expiration_date` (datetime).
|
|
* Relationship: Stored in `centralDB`.
|
|
|
|
## Success Criteria *(mandatory)*
|
|
|
|
### Measurable Outcomes
|
|
|
|
- **SC-001**: Users can successfully link their Garmin account via the `/login` endpoint within 10 seconds.
|
|
- **SC-002**: Garmin data synchronization operations (e.g., activity download) complete without interruption due to expired tokens for 99.9% of attempts.
|
|
- **SC-003**: The `/login` endpoint correctly handles invalid Garmin credentials, returning an error response within 2 seconds.
|
|
- **SC-004**: The system maintains continuous Garmin connectivity for 99% of the time without requiring manual re-authentication. |