# Training Tracker A mobile-friendly web application for tracking training activities with a Go backend and PostgreSQL database. ## Project Structure ``` training-tracker/ ├── backend/ │ ├── cmd/server/ # Application entry point │ ├── internal/ │ │ ├── api/ # HTTP handlers │ │ ├── models/ # Data structures │ │ └── storage/ # Database layer │ ├── Dockerfile.dev # Development container │ ├── Dockerfile.prod # Production container │ ├── go.mod │ └── go.sum ├── frontend/ │ ├── index.html │ ├── css/styles.css │ └── js/ │ ├── api.js # API client │ └── app.js # Application logic ├── .gitea/workflows/ # CI/CD pipelines ├── docker-compose.yml └── README.md ``` ## Prerequisites - Docker and Docker Compose - Go 1.25.6+ (for local development without Docker) - A web server or `python3 -m http.server` (for frontend) ## Running with Docker Compose (Recommended) Start PostgreSQL and the backend: ```bash docker-compose up -d ``` This starts: - PostgreSQL on port 5432 - Backend API on port 8080 To view logs: ```bash docker-compose logs -f backend ``` To stop: ```bash docker-compose down ``` ## Running Manually ### 1. Start PostgreSQL ```bash docker-compose up -d postgres ``` Or use an existing PostgreSQL instance and set environment variables. ### 2. Run the Backend ```bash cd backend export DB_HOST=localhost export DB_PORT=5432 export DB_USER=postgres export DB_PASSWORD=postgres export DB_NAME=training_tracker go run ./cmd/server ``` ### 3. Serve the Frontend ```bash cd frontend python3 -m http.server 3000 ``` Open http://localhost:3000 in your browser. ## Testing The backend includes comprehensive unit and integration tests. ### Run Unit Tests ```bash cd backend go test ./... ``` ### Run Tests with Coverage ```bash cd backend go test -cover ./... ``` ### Run Integration Tests Integration tests use testcontainers to spin up a PostgreSQL instance. Docker must be running. ```bash cd backend go test -v -tags=integration ./internal/storage/... ``` ### Run All Tests ```bash cd backend go test ./... && go test -tags=integration ./internal/storage/... ``` ## Environment Variables | Variable | Default | Description | |----------|---------|-------------| | `DB_HOST` | localhost | PostgreSQL host | | `DB_PORT` | 5432 | PostgreSQL port | | `DB_USER` | postgres | Database user | | `DB_PASSWORD` | postgres | Database password | | `DB_NAME` | training_tracker | Database name | | `PORT` | 8080 | Backend server port | ## API Endpoints ### Exercises | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/exercises` | List all exercises | | POST | `/api/exercises` | Create exercise | | GET | `/api/exercises/:id` | Get exercise by ID | | PUT | `/api/exercises/:id` | Update exercise | | DELETE | `/api/exercises/:id` | Delete exercise | ### Training Plans | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/plans` | List all plans | | POST | `/api/plans` | Create plan | | GET | `/api/plans/:id` | Get plan with exercises | | PUT | `/api/plans/:id` | Update plan | | DELETE | `/api/plans/:id` | Delete plan | ### Sessions | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/sessions` | List all sessions | | POST | `/api/sessions` | Create session | | GET | `/api/sessions/:id` | Get session with entries | | PUT | `/api/sessions/:id` | Update session | | DELETE | `/api/sessions/:id` | Delete session | | POST | `/api/sessions/:id/entries` | Add exercise entry | ### Health Check | Method | Endpoint | Description | |--------|----------|-------------| | GET | `/api/health` | Returns `{"status": "ok"}` | ## API Examples ### Create an Exercise ```bash curl -X POST http://localhost:8080/api/exercises \ -H "Content-Type: application/json" \ -d '{"name": "Bench Press", "type": "strength", "muscle_group": "Chest"}' ``` ### Create a Session ```bash curl -X POST http://localhost:8080/api/sessions \ -H "Content-Type: application/json" \ -d '{"date": "2026-01-19T10:00:00Z", "notes": "Morning workout"}' ``` ### Add Entry to Session ```bash curl -X POST http://localhost:8080/api/sessions/1/entries \ -H "Content-Type: application/json" \ -d '{"exercise_id": 1, "weight": 80, "sets_completed": 3, "reps": 10}' ``` ## Features - Mobile-first responsive design - Exercise library (strength and cardio types) - Training plan templates - Session logging with: - Strength: weight, sets, reps - Cardio: duration, distance, heart rate - Session history and dashboard ## Production Deployment Build the production image: ```bash docker build -f backend/Dockerfile.prod -t training-tracker-backend ./backend ``` The production image uses: - Distroless base image - Non-root user - Pinned image digests for reproducibility ## CI/CD The project includes a Gitea Actions workflow (`.gitea/workflows/ci.yaml`) that: 1. Runs tests on pull requests 2. Builds and pushes Docker images on merge to main