This commit is contained in:
2025-08-07 18:52:21 -07:00
parent f41316c8cf
commit 3dc3ec5c5c
15 changed files with 826 additions and 295 deletions

View File

@@ -11,11 +11,11 @@
4. Download missing activities (`garminsync download --missing`)
## Tech Stack
**Frontend:** Python CLI (argparse)
**Backend:** Python 3.10+ with garminexport==1.2.0
**Frontend:** CLI (Go)
**Backend:** Go
**Database:** SQLite (garmin.db)
**Hosting:** Docker container
**Key Libraries:** garminexport, python-dotenv, sqlite3
**Key Libraries:** garminexport (Go), viper (env vars), cobra (CLI framework), go-sqlite3
## Data Structure
**Main data object:**
@@ -28,7 +28,7 @@ Activity:
```
## User Flow
1. User launches container with credentials: `docker run -it --env-file .env garminsync`
1. User launches container with credentials: `sudo docker run -it --env-file .env garminsync`
2. User is presented with CLI menu of options
3. User selects command (e.g., `garminsync download --missing`)
4. Application executes task with progress indicators
@@ -36,50 +36,81 @@ Activity:
## File Structure
```
GarminSync/
/garminsync
├── cmd/
│ └── root.go (CLI entrypoint)
│ └── list.go (activity listing commands)
│ └── download.go (download command)
├── internal/
│ ├── garmin/
│ │ ├── client.go (API integration)
│ │ └── activity.go (activity models)
│ └── db/
│ ├── database.go (embedded schema)
│ ├── sync.go (NEW: database synchronization)
│ └── migrations.go (versioned migrations)
├── Dockerfile
├── .env.example
── requirements.txt
└── main.py
├── .env
── README.md
```
## Technical Implementation Notes
- **Single-file architecture:** All logic in main.py (CLI, DB, Garmin integration)
- **Architecture:** Go-based implementation with Cobra CLI framework
- **Authentication:** Credentials via GARMIN_EMAIL/GARMIN_PASSWORD env vars (never stored)
- **File naming:** `activity_{id}_{timestamp}.fit` (e.g., activity_123456_20240807.fit)
- **Rate limiting:** 2-second delays between API requests
- **Database:** In-memory during auth testing, persistent garmin.db for production
- **Docker** All docker commands require the use of sudo
- **Database:** Embedded schema creation in Go code with versioned migrations
- **Docker:**
- All commands require sudo as specified
- Fully containerized build process (no host Go dependencies)
- **Session management:** Automatic cookie handling via garminexport with file-based persistence
- **Pagination:** Implemented for activity listing
- **Package stability:** Always use stable, released versions of packages to ensure reproducibility
## Development Phases
### Phase 1: Core Infrastructure
- [X] Dockerfile with Python 3.10 base
- [X] Environment variable handling
- [X] garminexport client initialization
### Phase 1: Core Infrastructure - COMPLETE
- [x] Dockerfile creation
- [x] Environment variable handling (viper)
- [x] Cobra CLI framework setup
- [x] garminexport client initialization (with session persistence)
### Phase 2: Activity Listing
- [ ] SQLite schema implementation
- [ ] Activity listing commands
- [ ] Database synchronization
### Phase 2: Activity Listing - COMPLETE
- [x] SQLite schema implementation
- [x] Activity listing commands
- [x] Database synchronization
- [x] List command UI implementation
### Phase 3: Download Pipeline
- [ ] FIT file download implementation
- [ ] Idempotent download logic
- [ ] Database update on success
### Phase 3: Download Pipeline - COMPLETE
- [x] FIT file download implementation
- [x] Idempotent download logic (with exponential backoff)
- [x] Database update on success
- [x] Database sync integration
### Phase 4: Polish
- [ ] Progress indicators
- [ ] Error handling
- [x] Progress indicators (download command)
- [ ] Error handling (robust error recovery)
- [ ] README documentation
- [x] Session timeout handling
## Critical Roadblocks
1. **Garmin API changes:** garminexport is abandoned, switch to garmin-connect-export instead
2. **Rate limiting:** Built-in 2-second request delays
3. **Session management:** Automatic cookie handling via garminexport
4. **File conflicts:** Atomic database updates during downloads
5. **Docker permissions:** Volume-mounted /data directory for downloads
1. **Rate limiting:** Built-in 2-second request delays (implemented)
2. **Session management:** Automatic cookie handling via garminexport (implemented)
3. **File conflicts:** Atomic database updates during downloads (implemented)
4. **Docker permissions:** Volume-mounted /data directory for downloads (implemented)
5. ~~**Database sync:** Efficient Garmin API ↔ local sync~~ (implemented)
## Current Status
**Working on:** Phase 1 - Core Infrastructure (Docker setup, env vars)
**Next steps:** Implement activity listing with SQLite schema
**Known issues:** Garmin API rate limits (mitigated by 2s delays), session timeout handling
**Working on:** Phase 4 - Final polish and error handling
**Next steps:**
1. Fix command flag parsing issue
2. Implement comprehensive error handling
3. Complete README documentation
4. Final testing and validation
**Known issues:**
- Command flag parsing issue: The `--all` flag is not being recognized by the CLI. This appears to be related to how Cobra handles flags for subcommands. The root cause is being investigated.
## Recent Fixes
- Fixed package declaration conflicts in cmd/ directory (changed from `package cmd` to `package main`)
- Removed unnecessary import in root.go that was causing build errors
- Verified Docker build process now completes successfully