العودة إلى المشاريع


Sunrise Runner
تطبيق تدريب على الجري والمشي يأخذ المبتدئ من الصفر إلى جري 10 كم دون توقف، بخطة تتبع ما أنجزه جسمه فعلًا لا ما يمليه التقويم.
- السنة
- 2026
- النوع
- تطبيق ويب
- الحالة
- متاح
دراسة الحالة الكاملة متوفرة بالإنجليزية.
The problem. Couch-to-10K plans assume every week goes as written. Real beginners miss sessions, find a week too hard or feel a twinge, and a fixed calendar either pushes them into injury or makes them start over. Sunrise Runner is a bilingual Arabic and English coach that takes an absolute beginner to a continuous 10 km, with a plan that moves according to what the body actually did. Sign-in is required, through an email magic link.
The hard part. The coach is a deterministic engine, not an AI, so every decision can be explained and tested. It climbs a 24-rung ladder from eight rounds of 60 seconds running and 90 seconds walking up to 90 minutes continuous, earning effort credits along the way. Safety rails override the credits: at most one rung up a week, weekly time on feet capped at 10% over the four-week average, a deload every fourth week, and a pain flag that removes credits and books rest, and a second flag within 14 days freezes progression.
The approach. The engine lives in a framework-free package with no React, Next.js, Prisma or fetch, and the current time is always passed in as a parameter. Golden-scenario tests replay six named scenarios, each defending one rule against it. The session player is a shared reducer built to work offline, resumes from IndexedDB and queues its sync. Strava and Whoop adapters import outside activity, and Whoop recovery is shown as a hint only, and every chart has a data-table equivalent.
The outcome. The app is live as a PWA on Next.js 16 with Prisma on Neon Postgres and a Serwist service worker. Stylelint enforces logical CSS properties so the Arabic layout cannot regress, the end-to-end suite runs axe, RTL and mobile-layout specs, and the core package is held above 90% branch coverage by rule, within more than 1,500 tests over 171 commits. It is a training tool, not medical advice; onboarding requires a medical-disclaimer acknowledgement.
The hard part. The coach is a deterministic engine, not an AI, so every decision can be explained and tested. It climbs a 24-rung ladder from eight rounds of 60 seconds running and 90 seconds walking up to 90 minutes continuous, earning effort credits along the way. Safety rails override the credits: at most one rung up a week, weekly time on feet capped at 10% over the four-week average, a deload every fourth week, and a pain flag that removes credits and books rest, and a second flag within 14 days freezes progression.
The approach. The engine lives in a framework-free package with no React, Next.js, Prisma or fetch, and the current time is always passed in as a parameter. Golden-scenario tests replay six named scenarios, each defending one rule against it. The session player is a shared reducer built to work offline, resumes from IndexedDB and queues its sync. Strava and Whoop adapters import outside activity, and Whoop recovery is shown as a hint only, and every chart has a data-table equivalent.
The outcome. The app is live as a PWA on Next.js 16 with Prisma on Neon Postgres and a Serwist service worker. Stylelint enforces logical CSS properties so the Arabic layout cannot regress, the end-to-end suite runs axe, RTL and mobile-layout specs, and the core package is held above 90% branch coverage by rule, within more than 1,500 tests over 171 commits. It is a training tool, not medical advice; onboarding requires a medical-disclaimer acknowledgement.
دوري
Sole Full-Stack Developer — designed the training model and its safety rails, built the deterministic engine, the offline session player, the Next.js app and the Strava and Whoop integrations, and set the coverage, accessibility and RTL rules the code has to meet.
- Next.js 16
- React 19
- TypeScript
- Auth.js
- next-intl
- Prisma 7
- PostgreSQL (Neon)
- Tailwind CSS 4
- Zod 4
- TanStack Query
- Recharts
- Serwist
- Turborepo
- Vitest
- Playwright


