mirror of
https://github.com/sstent/AICyclingCoach.git
synced 2026-01-26 17:12:30 +00:00
change to TUI
This commit is contained in:
471
README.md
471
README.md
@@ -1,325 +1,272 @@
|
||||
# AI Cycling Coach
|
||||
# AI Cycling Coach - Terminal Edition
|
||||
|
||||
A single-user, self-hosted web application that provides AI-powered cycling training plan generation, workout analysis, and plan evolution based on actual ride data from Garmin Connect.
|
||||
🚴♂️ An intelligent cycling training coach with a sleek Terminal User Interface (TUI) that creates personalized training plans and analyzes your workouts using AI, with seamless Garmin Connect integration.
|
||||
|
||||
## 🚀 Quick Start
|
||||
## ✨ Features
|
||||
|
||||
### Prerequisites
|
||||
- Docker and Docker Compose
|
||||
- 2GB+ available RAM
|
||||
- 10GB+ available disk space
|
||||
- **🧠 AI-Powered Plan Generation**: Create personalized 4-week training plans based on your goals and constraints
|
||||
- **📊 Automatic Workout Analysis**: Get detailed AI feedback on your completed rides with terminal-based visualizations
|
||||
- **⌚ Garmin Connect Integration**: Sync activities automatically from your Garmin device
|
||||
- **🔄 Plan Evolution**: Training plans adapt based on your actual performance
|
||||
- **🗺️ GPX Route Management**: Upload and visualize your favorite cycling routes with ASCII maps
|
||||
- **📈 Progress Tracking**: Monitor your training progress with terminal charts and metrics
|
||||
- **💻 Pure Terminal Interface**: Beautiful, responsive TUI that works entirely in your terminal
|
||||
- **🗃️ SQLite Database**: Lightweight, portable database that travels with your data
|
||||
- **🚀 No Docker Required**: Simple installation and native performance
|
||||
|
||||
### Setup
|
||||
1. Clone the repository
|
||||
2. Copy environment file: `cp .env.example .env`
|
||||
3. Edit `.env` with your credentials
|
||||
4. Start services: `docker-compose up -d`
|
||||
|
||||
## 🐳 Container-First Development
|
||||
|
||||
This project follows strict containerization practices. All development occurs within Docker containers - never install packages directly on the host system.
|
||||
|
||||
### Key Rules
|
||||
|
||||
#### Containerization Rules
|
||||
- ✅ All Python packages must be in `backend/requirements.txt`
|
||||
- ✅ All system packages must be in `backend/Dockerfile`
|
||||
- ✅ Never run `pip install` or `apt-get install` outside containers
|
||||
- ✅ Use `docker-compose` for local development
|
||||
|
||||
#### Database Management
|
||||
- ✅ Schema changes handled through Alembic migrations
|
||||
- ✅ Migrations run automatically on container startup
|
||||
- ✅ No raw SQL in application code - use SQLAlchemy ORM
|
||||
- ✅ Migration rollback scripts available for emergencies
|
||||
|
||||
### Development Workflow
|
||||
## 🏁 Quick Start
|
||||
|
||||
### Option 1: Automated Installation (Recommended)
|
||||
```bash
|
||||
# Start development environment
|
||||
docker-compose up -d
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f backend
|
||||
|
||||
# Run database migrations manually (if needed)
|
||||
docker-compose exec backend alembic upgrade head
|
||||
|
||||
# Access backend container
|
||||
docker-compose exec backend bash
|
||||
|
||||
# Stop services
|
||||
docker-compose down
|
||||
git clone https://github.com/ai-cycling-coach/ai-cycling-coach.git
|
||||
cd ai-cycling-coach
|
||||
./install.sh
|
||||
```
|
||||
|
||||
### Migration Management
|
||||
|
||||
#### Automatic Migrations
|
||||
Migrations run automatically when containers start. The entrypoint script:
|
||||
1. Runs `alembic upgrade head`
|
||||
2. Verifies migration success
|
||||
3. Starts the application
|
||||
|
||||
#### Manual Migration Operations
|
||||
### Option 2: Manual Installation
|
||||
```bash
|
||||
# Check migration status
|
||||
docker-compose exec backend python scripts/migration_checker.py check-db
|
||||
# Clone and setup
|
||||
git clone https://github.com/ai-cycling-coach/ai-cycling-coach.git
|
||||
cd ai-cycling-coach
|
||||
|
||||
# Generate new migration
|
||||
docker-compose exec backend alembic revision --autogenerate -m "description"
|
||||
# Create virtual environment
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# Rollback migration
|
||||
docker-compose exec backend python scripts/migration_rollback.py rollback
|
||||
# Install
|
||||
pip install -e .
|
||||
|
||||
# Initialize database
|
||||
make init-db
|
||||
|
||||
# Run the application
|
||||
cycling-coach
|
||||
```
|
||||
|
||||
#### Migration Validation
|
||||
## ⚙️ Configuration
|
||||
|
||||
Edit the `.env` file with your settings:
|
||||
|
||||
```bash
|
||||
# Validate deployment readiness
|
||||
docker-compose exec backend python scripts/migration_checker.py validate-deploy
|
||||
# Database Configuration (SQLite)
|
||||
DATABASE_URL=sqlite+aiosqlite:///data/cycling_coach.db
|
||||
|
||||
# Generate migration report
|
||||
docker-compose exec backend python scripts/migration_checker.py report
|
||||
```
|
||||
# File Storage
|
||||
GPX_STORAGE_PATH=data/gpx
|
||||
|
||||
### Database Backup & Restore
|
||||
# AI Service Configuration
|
||||
OPENROUTER_API_KEY=your_openrouter_api_key_here
|
||||
AI_MODEL=deepseek/deepseek-r1
|
||||
|
||||
#### Creating Backups
|
||||
```bash
|
||||
# Create backup
|
||||
docker-compose exec backend python scripts/backup_restore.py backup
|
||||
|
||||
# Create named backup
|
||||
docker-compose exec backend python scripts/backup_restore.py backup my_backup
|
||||
```
|
||||
|
||||
#### Restoring from Backup
|
||||
```bash
|
||||
# List available backups
|
||||
docker-compose exec backend python scripts/backup_restore.py list
|
||||
|
||||
# Restore (with confirmation prompt)
|
||||
docker-compose exec backend python scripts/backup_restore.py restore backup_file.sql
|
||||
|
||||
# Restore without confirmation
|
||||
docker-compose exec backend python scripts/backup_restore.py restore backup_file.sql --yes
|
||||
```
|
||||
|
||||
#### Cleanup
|
||||
```bash
|
||||
# Remove backups older than 30 days
|
||||
docker-compose exec backend python scripts/backup_restore.py cleanup
|
||||
|
||||
# Remove backups older than N days
|
||||
docker-compose exec backend python scripts/backup_restore.py cleanup 7
|
||||
```
|
||||
|
||||
## 🔧 Configuration
|
||||
|
||||
### Environment Variables
|
||||
```env
|
||||
# Database
|
||||
DATABASE_URL=postgresql://postgres:password@db:5432/cycling
|
||||
|
||||
# Garmin Connect
|
||||
# Garmin Connect Credentials
|
||||
GARMIN_USERNAME=your_garmin_email@example.com
|
||||
GARMIN_PASSWORD=your_secure_password
|
||||
|
||||
# AI Service
|
||||
OPENROUTER_API_KEY=your_openrouter_api_key
|
||||
AI_MODEL=anthropic/claude-3-sonnet-20240229
|
||||
|
||||
# Application
|
||||
API_KEY=your_secure_random_api_key_here
|
||||
# Optional: Logging Configuration
|
||||
LOG_LEVEL=INFO
|
||||
```
|
||||
|
||||
### Health Checks
|
||||
## 🎮 Usage
|
||||
|
||||
The application includes comprehensive health monitoring:
|
||||
### Terminal Interface
|
||||
|
||||
Start the application with:
|
||||
```bash
|
||||
# Check overall health
|
||||
curl http://localhost:8000/health
|
||||
|
||||
# Response includes:
|
||||
# - Database connectivity
|
||||
# - Migration status
|
||||
# - Current vs head revision
|
||||
# - Service availability
|
||||
cycling-coach
|
||||
# or
|
||||
ai-cycling-coach
|
||||
# or
|
||||
python main.py
|
||||
```
|
||||
|
||||
Navigate through the interface using:
|
||||
|
||||
1. **🏠 Dashboard**: View recent workouts, weekly stats, and sync status
|
||||
2. **📋 Plans**: Generate new training plans or manage existing ones
|
||||
3. **💪 Workouts**: Sync from Garmin, view detailed analysis, and approve AI suggestions
|
||||
4. **📏 Rules**: Define custom training constraints and preferences
|
||||
5. **🗺️ Routes**: Upload GPX files and view ASCII route visualizations
|
||||
|
||||
### Key Features
|
||||
|
||||
#### 🧠 AI-Powered Analysis
|
||||
- Detailed workout feedback with actionable insights
|
||||
- Performance trend analysis
|
||||
- Training load recommendations
|
||||
- Recovery suggestions
|
||||
|
||||
#### 🗺️ ASCII Route Visualization
|
||||
```
|
||||
Route Map:
|
||||
S●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●E
|
||||
● ●
|
||||
● Morning Loop - 15.2km ●
|
||||
● ●
|
||||
●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●●
|
||||
|
||||
Elevation Profile (50m - 180m):
|
||||
████████████████████████████████████████████████████████████
|
||||
██████████████████████████████ ████████████████████████████
|
||||
███████████████████████████ ████████████████████████
|
||||
███████████████████████ ██████████████████████
|
||||
```
|
||||
|
||||
#### 📊 Terminal-Based Charts
|
||||
- Heart rate zones
|
||||
- Power distribution
|
||||
- Training load trends
|
||||
- Weekly volume tracking
|
||||
|
||||
## 🏗️ Architecture
|
||||
|
||||
### Service Architecture
|
||||
### 🔧 Technology Stack
|
||||
- **Backend**: Python with SQLAlchemy + SQLite
|
||||
- **TUI Framework**: Textual (Rich terminal interface)
|
||||
- **AI Integration**: OpenRouter API (Deepseek R1, Claude, GPT)
|
||||
- **Garmin Integration**: garth library
|
||||
- **Database**: SQLite with async support
|
||||
|
||||
### 📁 Project Structure
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ Frontend │ │ Backend │
|
||||
│ (React) │◄──►│ (FastAPI) │
|
||||
│ │ │ │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
│ │
|
||||
▼ ▼
|
||||
┌─────────────────┐ ┌─────────────────┐
|
||||
│ Garmin │ │ PostgreSQL │
|
||||
│ Connect │ │ Database │
|
||||
└─────────────────┘ └─────────────────┘
|
||||
ai-cycling-coach/
|
||||
├── main.py # Application entrypoint
|
||||
├── backend/ # Core business logic
|
||||
│ ├── app/
|
||||
│ │ ├── models/ # Database models
|
||||
│ │ ├── services/ # Business services
|
||||
│ │ └── config.py # Configuration
|
||||
│ └── alembic/ # Database migrations
|
||||
├── tui/ # Terminal interface
|
||||
│ ├── views/ # TUI screens
|
||||
│ ├── services/ # TUI service layer
|
||||
│ └── widgets/ # Custom UI components
|
||||
└── data/ # SQLite database and files
|
||||
├── cycling_coach.db
|
||||
└── gpx/ # GPX route files
|
||||
```
|
||||
|
||||
### Data Flow
|
||||
1. Garmin activities synced via background tasks
|
||||
2. AI analysis performed on workout data
|
||||
3. Training plans evolved based on performance
|
||||
4. User feedback incorporated for plan adjustments
|
||||
## 🛠️ Development
|
||||
|
||||
## 🧪 Testing & Validation
|
||||
|
||||
### CI/CD Pipeline
|
||||
GitHub Actions automatically validates:
|
||||
- ✅ No uncommitted migration files
|
||||
- ✅ No raw SQL in application code
|
||||
- ✅ Proper dependency management
|
||||
- ✅ Container build success
|
||||
- ✅ Migration compatibility
|
||||
|
||||
### Local Validation
|
||||
### Setup Development Environment
|
||||
```bash
|
||||
# Run all validation checks
|
||||
docker-compose exec backend python scripts/migration_checker.py validate-deploy
|
||||
# Clone repository
|
||||
git clone https://github.com/ai-cycling-coach/ai-cycling-coach.git
|
||||
cd ai-cycling-coach
|
||||
|
||||
# Check for raw SQL usage
|
||||
grep -r "SELECT.*FROM\|INSERT.*INTO\|UPDATE.*SET\|DELETE.*FROM" backend/app/
|
||||
# Install in development mode
|
||||
make dev-install
|
||||
|
||||
# Initialize database
|
||||
make init-db
|
||||
|
||||
# Run tests
|
||||
make test
|
||||
|
||||
# Format code
|
||||
make format
|
||||
|
||||
# Run application
|
||||
make run
|
||||
```
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── backend/
|
||||
│ ├── Dockerfile # Multi-stage container build
|
||||
│ ├── requirements.txt # Python dependencies
|
||||
│ ├── scripts/
|
||||
│ │ ├── migration_rollback.py # Rollback utilities
|
||||
│ │ ├── backup_restore.py # Backup/restore tools
|
||||
│ │ └── migration_checker.py # Validation tools
|
||||
│ └── app/
|
||||
│ ├── main.py # FastAPI application
|
||||
│ ├── database.py # Database configuration
|
||||
│ ├── models/ # SQLAlchemy models
|
||||
│ ├── routes/ # API endpoints
|
||||
│ ├── services/ # Business logic
|
||||
│ └── schemas/ # Pydantic schemas
|
||||
├── frontend/
|
||||
│ ├── Dockerfile
|
||||
│ └── src/
|
||||
├── docker-compose.yml # Development services
|
||||
├── .github/
|
||||
│ └── workflows/
|
||||
│ └── container-validation.yml # CI/CD checks
|
||||
└── .kilocode/
|
||||
└── rules/
|
||||
└── container-database-rules.md # Development guidelines
|
||||
```
|
||||
|
||||
## 🚨 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Migration Failures
|
||||
### Available Make Commands
|
||||
```bash
|
||||
# Check migration status
|
||||
docker-compose exec backend alembic current
|
||||
|
||||
# View migration history
|
||||
docker-compose exec backend alembic history
|
||||
|
||||
# Reset migrations (CAUTION: destroys data)
|
||||
docker-compose exec backend alembic downgrade base
|
||||
make help # Show all available commands
|
||||
make install # Install the application
|
||||
make dev-install # Install in development mode
|
||||
make run # Run the application
|
||||
make init-db # Initialize the database
|
||||
make test # Run tests
|
||||
make clean # Clean build artifacts
|
||||
make build # Build distribution packages
|
||||
make package # Create standalone executable
|
||||
make setup # Complete setup for new users
|
||||
```
|
||||
|
||||
#### Database Connection Issues
|
||||
### Creating a Standalone Executable
|
||||
```bash
|
||||
# Check database health
|
||||
docker-compose exec db pg_isready -U postgres
|
||||
|
||||
# View database logs
|
||||
docker-compose logs db
|
||||
|
||||
# Restart database
|
||||
docker-compose restart db
|
||||
make package
|
||||
# Creates: dist/cycling-coach
|
||||
```
|
||||
|
||||
#### Container Build Issues
|
||||
## 🚀 Deployment Options
|
||||
|
||||
### 1. Portable Installation
|
||||
```bash
|
||||
# Rebuild without cache
|
||||
docker-compose build --no-cache backend
|
||||
|
||||
# View build logs
|
||||
docker-compose build backend
|
||||
# Create portable package
|
||||
make build
|
||||
pip install dist/ai-cycling-coach-*.whl
|
||||
```
|
||||
|
||||
### Health Monitoring
|
||||
|
||||
#### Service Health
|
||||
### 2. Standalone Executable
|
||||
```bash
|
||||
# Check all services
|
||||
docker-compose ps
|
||||
|
||||
# View service logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Check backend health
|
||||
curl http://localhost:8000/health
|
||||
# Create single-file executable
|
||||
make package
|
||||
# Copy dist/cycling-coach to target system
|
||||
```
|
||||
|
||||
#### Database Health
|
||||
### 3. Development Installation
|
||||
```bash
|
||||
# Check database connectivity
|
||||
docker-compose exec backend python -c "
|
||||
from app.database import get_db
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
import asyncio
|
||||
|
||||
async def test():
|
||||
async with AsyncSession(get_db()) as session:
|
||||
result = await session.execute('SELECT 1')
|
||||
print('Database OK')
|
||||
|
||||
asyncio.run(test())
|
||||
"
|
||||
# For development and testing
|
||||
make dev-install
|
||||
```
|
||||
|
||||
## 🔒 Security
|
||||
## 📋 Requirements
|
||||
|
||||
- API key authentication for all endpoints
|
||||
- Secure storage of Garmin credentials
|
||||
- No sensitive data in application logs
|
||||
- Container isolation prevents host system access
|
||||
- Regular security updates via container rebuilds
|
||||
|
||||
## 📚 API Documentation
|
||||
|
||||
Once running, visit:
|
||||
- **API Docs**: http://localhost:8000/docs
|
||||
- **Alternative Docs**: http://localhost:8000/redoc
|
||||
- **Python**: 3.8 or higher
|
||||
- **Operating System**: Linux, macOS, Windows
|
||||
- **Terminal**: Any terminal with Unicode support
|
||||
- **Memory**: ~100MB RAM
|
||||
- **Storage**: ~50MB + data files
|
||||
|
||||
## 🤝 Contributing
|
||||
|
||||
1. Follow container-first development rules
|
||||
2. Ensure all changes pass CI/CD validation
|
||||
3. Update documentation for significant changes
|
||||
4. Test migration compatibility before merging
|
||||
1. Fork the repository
|
||||
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
||||
3. Make your changes
|
||||
4. Run tests (`make test`)
|
||||
5. Format code (`make format`)
|
||||
6. Commit changes (`git commit -m 'Add amazing feature'`)
|
||||
7. Push to branch (`git push origin feature/amazing-feature`)
|
||||
8. Open a Pull Request
|
||||
|
||||
### Development Guidelines
|
||||
## 🐛 Troubleshooting
|
||||
|
||||
- Use SQLAlchemy ORM for all database operations
|
||||
- Keep dependencies in `requirements.txt`
|
||||
- Test schema changes in development environment
|
||||
- Document migration changes in commit messages
|
||||
- Run validation checks before pushing
|
||||
### Common Issues
|
||||
|
||||
**Database errors:**
|
||||
```bash
|
||||
make init-db # Reinitialize database
|
||||
```
|
||||
|
||||
**Import errors:**
|
||||
```bash
|
||||
pip install -e . # Reinstall in development mode
|
||||
```
|
||||
|
||||
**Garmin sync fails:**
|
||||
- Check credentials in `.env`
|
||||
- Verify Garmin Connect account access
|
||||
- Check internet connection
|
||||
|
||||
**TUI rendering issues:**
|
||||
- Ensure terminal supports Unicode
|
||||
- Try different terminal emulators
|
||||
- Check terminal size (minimum 80x24)
|
||||
|
||||
### Getting Help
|
||||
|
||||
- 📖 Check the documentation
|
||||
- 🐛 Open an issue on GitHub
|
||||
- 💬 Join our community discussions
|
||||
|
||||
## 📄 License
|
||||
|
||||
This project is licensed under the MIT License - see the LICENSE file for details.
|
||||
MIT License - see [LICENSE](LICENSE) file for details.
|
||||
|
||||
---
|
||||
## 🙏 Acknowledgments
|
||||
|
||||
**Note**: This application is designed for single-user, self-hosted deployment. All data remains on your local infrastructure with no external data sharing.
|
||||
- [Textual](https://github.com/Textualize/textual) - Amazing TUI framework
|
||||
- [garth](https://github.com/matin/garth) - Garmin Connect integration
|
||||
- [OpenRouter](https://openrouter.ai/) - AI model access
|
||||
- [SQLAlchemy](https://www.sqlalchemy.org/) - Database toolkit
|
||||
Reference in New Issue
Block a user