Skip to content

About

A RESTful Workout Tracker API built with Java 21 and Spring Boot 3.2.5, featuring JWT authentication, workout scheduling, exercise management, progress tracking, personal records, and role-based admin controls using MySQL.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

40 Commits

Folders and files

Repository files navigation

🏋️ Workout Tracker API

Plan workouts. Record performance. Measure progress.

A RESTful backend for a workout-tracking application, built with Java 21 and Spring Boot. It provides JWT-based authentication, workout scheduling and completion, exercise management, progress reports, and administrator endpoints.


Java Spring Boot MySQL JWT Maven


Backend API · Stateless authentication · Role-based access · OpenAPI / Swagger


Contents

Start here Explore the API Development
Overview · Features Endpoints · Authentication Setup · Docker
Architecture · Data model Examples · Errors Tests · Security

What this project does

Workout Tracker API is the server-side application for managing personal training sessions. A user can register and sign in, browse the exercise catalogue, schedule workouts with sets, update or delete their workouts, mark sessions as completed, and retrieve workout history and performance summaries. Administrators have separate endpoints for managing users, exercises, workouts, and dashboard data.

Scope: This repository contains the Spring Boot backend/API. It does not contain the frontend application.

Features

User accounts 🗓️ Workout planning 📈 Reports
Registration and login Schedule workouts by date/time Workout history
BCrypt password hashing Add exercises and sets Exercise progress
JWT access tokens Update, view, and delete workouts Monthly summary
User / admin roles Complete sessions and check PRs Last exercise performance
🛠️ Exercise catalogue 🛡️ Admin tools 🧰 Developer tools
Browse exercises Dashboard data Swagger UI / OpenAPI
Strength, cardio, flexibility Search and page through users/workouts Spring Boot Actuator dependency
Seed initial exercises Block/unblock and remove users Maven Wrapper and Dockerfile

Workout lifecycle

flowchart LR
    A[Register / Login] --> B[Receive JWT]
    B --> C[Browse Exercises]
    C --> D[Schedule Workout]
    D --> E[Update or View]
    E --> F[Complete Workout]
    F --> G[History and Progress Reports]
Loading

Architecture

The application follows a conventional layered Spring Boot structure:

flowchart TB
    Client[Frontend / API Client] --> Controllers[REST Controllers]
    Controllers --> Services[Service Layer]
    Services --> Repositories[Spring Data JPA Repositories]
    Repositories --> DB[(MySQL Database)]
    Client -->|Bearer JWT| Filter[JWT Request Filter]
    Filter --> Security[Spring Security]
    Security --> Controllers
    Controllers --> DTO[Request / Response DTOs]
    Services --> DTO
Loading
  • Controllers expose HTTP routes and map request/response data.
  • Services implement application rules for authentication, workouts, reports, and administration.
  • Repositories access persisted entities through Spring Data JPA.
  • Entities / models represent users, exercises, workouts, workout exercises, sets, and history.
  • DTOs define the data exchanged by API clients.
  • Security components validate JWTs and apply role-based access rules.
  • Exception handlers translate application and security errors into HTTP responses.

Repository layout

workout-tracker-api/
├── src/
│   ├── main/
│   │   ├── java/com/workouttrackerapi/
│   │   │   ├── admin/          # Admin controllers, DTOs and services
│   │   │   ├── auth/           # Registration, login, user model, JWT service
│   │   │   ├── common/         # API response and exception handlers
│   │   │   ├── config/         # Security, JWT filter, seeders, Swagger
│   │   │   ├── exercise/       # Exercise controller, model and repository
│   │   │   ├── workout/        # Workout controllers, models, DTOs, services
│   │   │   └── WorkouttrackerapiApplication.java
│   │   └── resources/
│   │       └── application.properties
│   └── test/java/              # Application, auth, JWT and workout tests
├── .mvn/wrapper/               # Maven Wrapper configuration
├── Dockerfile
├── mvnw
├── mvnw.cmd
└── pom.xml

Technology stack

Technology Purpose in this codebase
Java 21 Application language and runtime target
Spring Boot 3.2.5 Application framework
Spring Web REST controllers and HTTP responses
Spring Data JPA / Hibernate ORM and database persistence
MySQL Connector/J MySQL connectivity
Spring Security Authentication and endpoint authorization
JJWT 0.11.5 JWT creation and parsing
BCrypt Password hashing
Jakarta Validation Request DTO validation
Springdoc OpenAPI UI 2.3.0 Interactive API documentation
Lombok Reduces DTO/model boilerplate
JUnit / Spring Boot Test Automated tests
JaCoCo Test coverage report generation
Docker Containerized build and runtime

Run locally

Prerequisites

  • JDK 21
  • MySQL server and a database/schema you can use
  • Git (optional, for cloning)
  • Docker (optional)

1. Get the source

git clone <your-repository-url>
cd workout-tracker-api

If you already downloaded this project as a ZIP, extract it and open a terminal in the workout-tracker-api directory.

2. Create a MySQL database

For example, create a database named workoutapi in MySQL:

CREATE DATABASE workoutapi;

The application reads its database connection from environment variables. Configure them before starting the API.

Windows PowerShell

$env:DB_URL="jdbc:mysql://localhost:3306/workoutapi"
$env:DB_USERNAME="your_mysql_username"
$env:DB_PASSWORD="your_mysql_password"

macOS / Linux

export DB_URL="jdbc:mysql://localhost:3306/workoutapi"
export DB_USERNAME="your_mysql_username"
export DB_PASSWORD="your_mysql_password"

Use your own local credentials. Do not commit passwords or production connection strings to source control.

3. Start the application

Windows

.\mvnw.cmd spring-boot:run

macOS / Linux

chmod +x mvnw
./mvnw spring-boot:run

Alternatively, if Maven is installed:

mvn spring-boot:run

The server uses port 8080 by default. The configured PORT environment variable can override it.

http://localhost:8080

The application expects DB_URL, DB_USERNAME, and DB_PASSWORD to be set. Startup will fail if the required database configuration is missing or cannot connect.

4. Open API documentation

After the application starts, try:

  • Swagger UI: http://localhost:8080/swagger-ui/index.html
  • OpenAPI JSON: http://localhost:8080/v3/api-docs

Use Swagger UI to inspect request schemas and try endpoints. Protected routes require a valid bearer token.

Authentication and authorization

Authentication is stateless and uses JWT bearer tokens.

  1. Register through POST /api/auth/register.
  2. Log in through POST /api/auth/login.
  3. Copy the returned token.
  4. For protected routes, send it in the HTTP header:
Authorization: Bearer <your-jwt-token>

The login response includes a token, role, and user ID. Tokens generated by the current implementation expire after 24 hours.

Access rules

Endpoint group Access
/api/auth/** Public
/swagger-ui/**, /v3/api-docs/** Public
/api/admin/** Admin role
/api/workout/** Authenticated user or admin
/api/exercises Requires authentication under the current fallback security rule

The configured CORS origins currently include the deployed frontend origin in SecurityConfig and http://localhost:5173. Update this allowlist deliberately if your frontend runs elsewhere.

API reference

All paths below are relative to http://localhost:8080. Request and response schemas are defined in the DTO classes and can be inspected in Swagger UI.

Authentication

Method Endpoint Purpose Access
POST /api/auth/register Create a user account Public
POST /api/auth/login Authenticate and receive a JWT Public

Exercises

Method Endpoint Purpose Access
GET /api/exercises List the exercise catalogue Authenticated

Workouts

Method Endpoint Purpose Access
POST /api/workout Create a scheduled workout User / Admin
PUT /api/workout/update/{id} Update scheduling, comments, or exercise sets User / Admin
DELETE /api/workout/delete/{workoutid} Delete a workout User / Admin
GET /api/workout/get/{workoutid} Get workout details User / Admin
GET /api/workout/scheduled?status=PLANNED List workouts by status User / Admin
POST /api/workout/{id}/complete Complete a workout and check personal records User / Admin
GET /api/workout/history Retrieve workout history User / Admin
GET /api/workout/progress?exerciseId={id} Retrieve progress for an exercise User / Admin
GET /api/workout/monthly?month={month}&year={year} Retrieve a monthly summary User / Admin
GET /api/workout/last-performance/{exerciseId} Retrieve the last recorded sets for an exercise User / Admin

Workout status values defined in the source are PLANNED, COMPLETED, and CANCELLED.

Admin dashboard

Method Endpoint Purpose Access
GET /api/admin/dashboard Dashboard summary data Admin
GET /api/admin/exercises List exercises for administration Admin
POST /api/admin/exercises Create an exercise Admin
PUT /api/admin/exercises/{id} Update an exercise Admin
DELETE /api/admin/exercises/{id} Delete an exercise Admin
GET /api/admin/users?page=0&size=10&search= Search/list users with pagination Admin
GET /api/admin/users/{id} Get a user Admin
PATCH /api/admin/users/{id}/block Change a user's active state Admin
DELETE /api/admin/users/{id} Delete a user Admin
GET /api/admin/workouts?page=0&size=10&status=PLANNED List workouts with pagination and optional status Admin
GET /api/admin/workouts/{id} Get a workout Admin
DELETE /api/admin/workouts/{id} Delete a workout Admin

For paginated admin endpoints, page is zero-based and size controls the page size. The status filter is optional for admin workout listing.

Request examples

Register

POST /api/auth/register

{
  "name": "Alex Morgan",
  "email": "alex@example.com",
  "password": "choose-a-strong-password"
}

Log in

POST /api/auth/login

{
  "email": "alex@example.com",
  "password": "choose-a-strong-password"
}

The current login implementation returns a JSON object containing token, role, and userId.

Create a workout

POST /api/workout

{
  "title": "Upper Body Day",
  "description": "Chest and back session",
  "scheduled_date": "2026-10-20",
  "scheduled_time": "18:30:00",
  "workout_Exercises_Request": [
    {
      "id": 1,
      "sets": [
        {
          "setNumber": 1,
          "setType": "WORKING",
          "reps": 10,
          "weight": 20.0
        },
        {
          "setNumber": 2,
          "setType": "WORKING",
          "reps": 8,
          "weight": 25.0
        }
      ]
    }
  ]
}

Use an exercise id that exists in the database. Each requested exercise must include at least one set, and each set requires positive reps and a non-negative weight. The service prevents a user from booking another workout at the same scheduled date and time.

Complete a workout

POST /api/workout/{id}/complete

{
  "notes": "Felt strong today",
  "duration": 50
}

The response reports successful completion and a newPersonalRecords list. The exact business rules for completion and personal records are implemented in WorkoutService.

Retrieve reports

GET /api/workout/progress?exerciseId=1
GET /api/workout/monthly?month=10&year=2026
GET /api/workout/last-performance/1
GET /api/workout/scheduled?status=PLANNED

Include the bearer token with each protected request.

Domain model

The source defines the following core persistence concepts:

Model Role
Users Account details, password hash, role, active state
Exercises Exercise name, description, category, and muscle group
Workouts User-owned scheduled workout and status
WorkoutExercises Exercises attached to a workout
WorkoutSets Set number/type, reps, and weight
WorkoutHistory Workout history used by reporting features
Workout_Logs Additional workout log model present in the source

Exercise categories are strength, cardio, and flexibility. On startup, the exercise seeder attempts to add a small starter catalogue (including push-ups, squats, bench press, deadlift, running, pull-ups, and diamond push-ups) when those names do not already exist.

Hibernate is configured with spring.jpa.hibernate.ddl-auto=update, so it updates the schema based on mapped entities. This is convenient for development, but a migration tool and a deliberate schema-management policy are recommended for production.

Error handling

The project contains dedicated exceptions for cases such as invalid login credentials, duplicate users/exercises, missing users/exercises/workouts, unauthorized access, already-completed workouts, and occupied workout slots. Global and security exception handlers centralize error responses.

Use the HTTP status and response body returned by the running application as the source of truth for a specific failure; response formats can differ between validation, application, and Spring Security errors.

Tests and coverage

Tests are located under src/test/java and include coverage for:

  • Application context startup
  • Authentication service behavior
  • JWT service behavior
  • Workout service behavior

Run the test suite:

./mvnw test

On Windows:

.\mvnw.cmd test

JaCoCo is configured to generate a coverage report during the Maven test phase. When generated, inspect:

target/site/jacoco/index.html

The Dockerfile currently builds the application with Maven and skips tests inside the image build (-Dmaven.test.skip=true); run tests separately before building/releasing an image.

🐳 Docker

Build the image from the project root:

docker build -t workout-tracker-api .

Run it with database settings supplied through environment variables:

docker run --rm -p 8080:8080 \
  -e DB_URL="jdbc:mysql://host.docker.internal:3306/workoutapi" \
  -e DB_USERNAME="your_mysql_username" \
  -e DB_PASSWORD="your_mysql_password" \
  workout-tracker-api

host.docker.internal is commonly useful on Docker Desktop when MySQL runs on the host machine. Adjust the JDBC hostname for your environment. The container exposes port 8080.

Security notes before deployment

  • Move secrets out of source code. The current JWT signing secret is hard-coded in JwtsService; replace it with a strong environment-provided secret and rotate it before deployment.
  • Review the admin seeder. AdminSeeder contains a hard-coded admin email and password. Remove this development convenience or provision an administrator securely through deployment configuration; never publish or reuse the embedded credentials.
  • Use HTTPS in deployed environments and keep database credentials in a secret manager or deployment environment.
  • Restrict CORS origins to the exact frontend origins you control.
  • Review ownership checks. Before production use, verify that every workout read, update, delete, completion, and report query enforces that the authenticated user owns the requested data. Authentication alone is not the same as resource-level authorization.
  • Review schema migration and SQL logging. spring.jpa.show-sql=true and automatic schema updates are currently enabled; consider safer production settings.
  • Review actuator exposure. Actuator is included as a dependency; configure and expose only the management endpoints you intend to make available.

This README documents the behavior visible in the source tree; it does not imply that the application has been penetration-tested or deployed securely.

Suggested next steps

  • Externalize JWT signing configuration and secure administrator provisioning.
  • Add database migration scripts (for example, Flyway).
  • Add integration tests for endpoint authorization and user-level workout ownership.
  • Add a Postman collection or API contract tests for common workflows.
  • Define production profiles and health/observability endpoint exposure.
  • Add CI to run tests and package the application before deployment.

Contributing

  1. Create a branch for your change.
  2. Keep controllers, services, repositories, DTOs, and entities in their existing responsibility layers.
  3. Add or update tests for behavior changes.
  4. Run ./mvnw test (or .\mvnw.cmd test on Windows).
  5. Open a pull request with a concise description of the change.

License

No license file or license declaration was identified in the supplied source tree. Add a LICENSE file before distributing this project if you want to specify reuse terms.


Built to help make workout planning and progress tracking accessible through a clean REST API.

Documentation written from the project source structure and implementation, not from the previous README.

About

A RESTful Workout Tracker API built with Java 21 and Spring Boot 3.2.5, featuring JWT authentication, workout scheduling, exercise management, progress tracking, personal records, and role-based admin controls using MySQL.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages