A REST API for the Trainify app to manage workouts, exercises, sessions, metrics and user progress.
π AboutΒ Β β’Β Β π οΈ Tech StackΒ Β β’Β Β β¨ FeaturesΒ Β β’Β Β π Getting StartedΒ Β β’Β Β π³ DockerΒ Β β’Β Β π API DocumentationΒ Β β’Β Β π§ͺ Tests
Trainify API is the backend of the Trainify app, responsible for providing a REST layer to register and track workouts. The application allows managing exercises, creating and finishing workout sessions, logging weight, tracking metrics, and consuming progress data through a well-organized modular structure.
The project was built with Fastify, TypeScript, Prisma ORM and PostgreSQL, with a focus on performance, strong typing, hardened security and interactive documentation via Scalar.
- π’ Node.js β Server-side JavaScript runtime.
- β‘ Fastify β Fast and efficient web framework.
- π· TypeScript β Static typing and safer development.
- ποΈ Prisma ORM β Modern, type-safe ORM for relational databases.
- π PostgreSQL β Robust relational database.
- π³ Docker β Containerization of the API and the local database.
- π @fastify/jwt β JWT authentication.
- πͺ @fastify/cookie β Cookie parsing and management.
- π @fastify/cors β CORS handling.
- π‘οΈ @fastify/helmet β Security headers for HTTP responses.
- π¦ @fastify/rate-limit β Request rate limiting.
- π @fastify/swagger + @scalar/fastify-api-reference β Interactive API documentation.
- π bcrypt β Password hashing.
- π dayjs β Lightweight date manipulation.
- π§© Zod β Runtime schema validation with full type inference.
- π¦ tsup β Bundler for building the production output.
- π§ͺ Vitest β Automated testing.
- π Biome β Fast, opinionated linter and formatter.
- ποΈ Exercise management (catalog and custom exercises)
- ποΈ Workout creation, plans and weekly scheduling
- β±οΈ Starting, pausing and finishing workout sessions
- π Exercise log tracking and session history
- π Performance comparisons (weekly, monthly and per exercise)
- βοΈ Weight logging, weight goals and analytics
- π Overall user metrics and progress
- π Gamification module: streaks, badges and achievements
- π JWT authentication and Google sign-in
- π‘οΈ Security hardening with Helmet and rate limiting
- π§© Data validation with Zod
- π³ Docker support with multi-stage build
- π Interactive API documentation with Scalar
- π§ͺ Automated testing with Vitest
- π© Node.js 22+
- π¦ npm
- π³ Docker (optional, for containerized setup)
-
Clone the repository:
git clone https://github.com/joschonarth/trainify-api.git
-
Navigate into the project:
cd trainify-api -
Install dependencies:
npm install
Copy the example env file and fill in your values:
cp .env.example .envExample content:
NODE_ENV=dev
PORT=3333
JWT_SECRET=your_jwt_secret
GOOGLE_CLIENT_ID=your-google-oauth-client-id.apps.googleusercontent.com
DATABASE_URL="postgresql://docker:docker@localhost:5432/trainify?schema=public"Start the PostgreSQL container:
docker compose up -d trainify-pgRun the Prisma migrations:
npm run migrateOptionally, seed the database with sample data:
npm run seedStart the server in development mode:
npm run devAPI running at http://localhost:3333
The project includes a multi-stage Dockerfile that builds the application and produces a lightweight runtime image containing only the compiled output and production dependencies. The .dockerignore keeps secrets, local artifacts and tests out of the image.
docker build -t trainify-api .The container does not read .env from the image. Pass the environment variables at runtime:
docker run --env-file .env \
-e DATABASE_URL="postgresql://docker:docker@host.docker.internal:5432/trainify?schema=public" \
-p 3333:3333 \
trainify-apiOn Linux,
host.docker.internalmay not resolve by default. Add--add-host=host.docker.internal:host-gatewayto the command, or use the compose setup below.
To start the API and the database together:
docker compose up -d --buildInside the compose network the database host is trainify-pg, which is already set in the trainify-api service, so there is no need to change DATABASE_URL for this setup.
Migrations are not executed on container start, to avoid race conditions when running multiple replicas. Run them manually:
docker compose exec trainify-api npx prisma migrate deployOr, with a standalone container:
docker exec -it <container_id> npx prisma migrate deployThe image includes a health check that calls GET /health every 30 seconds. You can inspect the status with:
docker psWith the server running, access the interactive documentation at:
There is also a health check endpoint available at:
- β€οΈ http://localhost:3333/health
Tests are run with Vitest and cover the main application flows.
# Run all tests
npm run test
# Run tests in watch mode
npm run test:watch
# Generate coverage report
npm run test:coveragesrc/
modules/
exercise/
gamification/
metric/
session/
user/
weight/
workout/
lib/
env/Contributions are welcome. If you'd like to help, open an issue or submit a pull request with your proposed improvements.
If you liked this project, consider leaving a β on GitHub β it really helps!
Made with β₯ by JoΓ£o OtΓ‘vio Schonarth