Backend / API

StreakFit API

Kotlin/Ktor backend for workout schedules and streaks, versioned plans, JWT + Google auth.

  • Kotlin
  • Ktor
  • Exposed ORM
  • PostgreSQL
  • Flyway
  • Redis
  • JWT
  • Google OAuth
  • Docker
StreakFit API A Kotlin and Ktor API whose schedule domain versions plan changes forward instead of mutating the active plan, so past days stay answerable. DOMAIN JWT EXPOSED ORM CACHE Client mobile or web API Ktor API password + Google Schedules active + pending Schedule clock effective-from dates Exercise catalog referenced, not copied DB PostgreSQL Flyway migrations DB Redis cache Versioned domain Persistence Client
A plan change writes a pending schedule with a future effective date rather than mutating the active one, which is what keeps “what was I supposed to do last Tuesday” answerable.

Overview

StreakFit is the backend for a fitness app built around consistency: users define a weekly workout schedule, follow it day by day, and keep a streak going. It is deliberately a different stack from the rest of this site, Kotlin on the JVM with Ktor, chosen to show that the engineering approach (clean domain modeling, tests first, disciplined migrations) is language-independent, not tied to one ecosystem.

Problem

A training schedule is not static: people change routines, and a change should take effect on a future date without corrupting the history of what they were supposed to do before it. Most simple CRUD backends overwrite the plan in place, which loses that history and makes "what was my schedule last Tuesday" unanswerable. Auth also has to support both classic email/password and Google sign-in from day one.

Solution

A Ktor REST API with a versioned schedule model: each user can have an active schedule and a pending one with an effective-from date, so edits roll forward cleanly instead of mutating the past. A schedule is a set of per-day entries (workout or rest), each holding ordered exercise slots with sets, reps, or duration. Auth issues JWTs and accepts both password and Google OAuth. Exercises live in their own catalog referenced by the schedule.

Architecture

Kotlin + Ktor (Netty) with kotlinx.serialization for JSON. Domain code is split by feature, auth, users, schedules, exercises, with the schedule logic isolated behind a service, a validator, and a clock abstraction so effective-from date math is testable without wall-clock flakiness. Persistence is PostgreSQL through the Exposed ORM, with Flyway managing migrations, and Redis for caching. It ships as a Docker image behind Traefik on the homelab at streakfit-api.theevolvedalligator.com.

Key decisions

A versioned active/pending schedule instead of in-place edits, so plan changes are auditable and future-dated. A dedicated ScheduleClock so date-sensitive rules are unit-testable and deterministic. Exposed over a heavier framework to keep SQL close and explicit. Flyway so schema changes are ordered and reproducible across environments. JWT with both password and Google OAuth so the client is not locked to one identity provider. Kover coverage and a unit-test suite that runs without an embedded database during fast agent iteration.

Challenges

Modeling schedule versioning so that switching the active plan never rewrites past days; keeping the effective-from transition logic deterministic under test; validating that every day entry and exercise slot is internally consistent before it reaches the database; and keeping the JVM image small and fast to boot for homelab deploys.

Outcome

A live, health-checked Kotlin API on the homelab with a clean, versioned domain and a real test suite: evidence that the same ownership and quality bar carries across languages, not just the TypeScript and Python stacks that dominate the rest of this portfolio.

Wondering if Daniel is a fit? Ask his assistant, hiring, contracts, or collaboration.