229 lines
5.1 KiB
Markdown
229 lines
5.1 KiB
Markdown
# 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
|