How I built a self-adapting training plan in Next.js (no AI, just logic)
When I started building RunAdapt, I had one goal: a running plan that doesn't fall apart when you miss sessions.
No machine learning. No LLMs. Just deterministic logic that runs every time you mark a session as MISSED or PARTIAL.
Here's exactly how it works.
The core idea
Most training apps are static. You get a plan, and if life gets in the way, you're on your own. RunAdapt runs 4 rules in sequence every time you miss a session.
Rule 1 — Reschedule
Finds the next available slot in your calendar and creates a new session there.
if (session.status === 'MISSED') {
const nextSlot = findNextAvailableSlot(plan.availableDays);
createSession({ ...session, date: nextSlot });
}
Rule 2 — Reduce intensity
If you have 2 or more consecutive missed sessions, the intensity factor drops by 0.15 (minimum 0.60). No point pushing hard if you're already struggling.
if (consecutiveMisses >= 2) {
plan.intensityFactor = Math.max(0.60, plan.intensityFactor - 0.15);
}
Rule 3 — Adjust target date
If your failure rate exceeds 20%, the race date moves forward up to 8 weeks. Better to adjust the goal than to pretend you're on track.
if (failureRate > 0.20) {
plan.adjustedTargetDate = addWeeks(plan.targetDate, weeksNeeded);
}
Rule 4 — Micro session
If you have less than 30 minutes available, instead of skipping entirely, the plan creates a 20 min / 3 km session. Something is always better than nothing.
if (availableMinutes < 30) {
createMicroSession({ duration: 20, distance: 3 });
}
Why deterministic logic instead of AI?
I considered using an LLM to make the adaptation smarter. But for this use case, deterministic rules have real advantages:
- Predictable — the user knows exactly what will happen
- Fast — no API calls, no latency
- Cheap — no token costs
- Trustworthy — no hallucinations
Sometimes simple is better.
Stack
- Next.js 14 (App Router)
- Supabase (auth + database)
- Vercel Hobby (free)
What's next
I'm currently looking for my first real users to validate whether these 4 rules are actually enough — or if I'm missing something obvious.
If you're a runner, I'd love your feedback: runadapt.vercel.app
Top comments (0)