RepJot is a lightweight REST API written in Go for tracking workouts and exercise routines. It provides user authentication, workout history logs, and exercise entry tracking (sets, reps, weights, durations).
- Go 1.26
- Routing: go-chi/chi v5 (for lightweight, radix-tree based routing)
- Database: PostgreSQL (driver: jackc/pgx v5 with
database/sqlcompatibility) - Migrations: goose (SQL-based migrations)
- Dev Setup: Docker Compose (multi-db layout for separate development and testing environments)
- Quality Assurance: Husky and commitlint for conventional commit standards
main.go: Application entrypoint, CLI flag parsing, and HTTP server configurations.internal/app/: Core application container holding database pools, logging utilities, and route handler mappings.internal/api/: HTTP handlers and request decoding/validation logic.internal/store/: Data Access Object (DAO) layer interface and Postgres-backed CRUD implementations.internal/middleware/: CORS, authentication token verification, and handler protection filters.internal/tokens/: Cryptographic utilities for session and authentication token generation.migrations/: Schema definition files managed by Goose.
Ensure you have Go, Docker, and Goose installed on your machine.
Spin up both the local development database (port 5432) and the test database (port 5433):
docker compose up -dConfigure your environment variables in a .env file at the root:
DATABASE_URL="postgres://postgres:postgres@localhost:5432/postgres?sslmode=disable"
TEST_DATABASE_URL="postgres://postgres:postgres@localhost:5433/postgres?sslmode=disable"
GOOSE_DRIVER=postgres
GOOSE_DBSTRING=postgres://postgres:postgres@localhost:5432/postgres
GOOSE_MIGRATION_DIR=./migrationsApply the migrations to your local development database:
goose upBy default, the server listens on port 8080. Run the binary or source directly:
go run main.go --port=8080All protected endpoints require a Bearer token supplied in the Authorization header.
curl -X POST http://localhost:8080/users \
-H "Content-Type: application/json" \
-d '{
"username": "john_doe",
"email": "john.doe@example.com",
"password": "securepassword123",
"bio": "Developer and runner"
}'curl -X POST http://localhost:8080/tokens/authentication \
-H "Content-Type: application/json" \
-d '{
"username": "john_doe",
"password": "securepassword123"
}'Response returns a raw token string to pass in the Authorization: Bearer <token> header.
curl -X POST http://localhost:8080/workouts \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"title": "Leg Day",
"description": "Lower body strength training",
"duration_minutes": 60,
"calories_burned": 400,
"entries": [
{
"exercise_name": "Squats",
"sets": 3,
"reps": 12,
"weight": 100.5,
"notes": "Focused on depth",
"order_index": 1
}
]
}'curl -H "Authorization: Bearer YOUR_TOKEN_HERE" \
http://localhost:8080/workouts/1curl -X PUT http://localhost:8080/workouts/1 \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"title": "Updated Leg Day",
"description": "Lower body strength training session",
"duration_minutes": 70,
"calories_burned": 450,
"entries": [
{
"exercise_name": "Squats",
"sets": 4,
"reps": 10,
"weight": 110.0,
"notes": "Added an extra set",
"order_index": 1
}
]
}'curl -X DELETE http://localhost:8080/workouts/1 \
-H "Authorization: Bearer YOUR_TOKEN_HERE"curl http://localhost:8080/healthTo execute the unit and database integration tests:
go test ./...This project uses Husky to run pre-commit git hooks. Commits must follow the conventional commit structure (e.g., feat: ..., fix: ..., docs: ...) enforced by @commitlint.
To install the git hooks locally:
bun install