HillsRun
Garmin Connect était trop bruyant pour mon usage trail. J'ai construit un dashboard épuré : D+, allure, FC et readiness — synchro automatique quotidienne.
Développeur full-stack3 moisEn production
PythonFastAPINext.jsPostgreSQLGarmin
15 janvier 2026
40+Endpoints API
QuotidienneSynchro
11Routers
Railway + VercelDéploiement
https://app.hillsrun.com
Problème
Garmin Connect est puissant mais bruyant. Trop de métriques, pas assez de focus. Pour le trail running, j'ai besoin de suivre l'essentiel : dénivelé positif, allure, fréquence cardiaque et readiness quotidienne.
Solution
HillsRun extrait l'essentiel de Garmin Connect dans une interface épurée. L'application synchronise automatiquement les données athlète chaque jour, puis les présente via un dashboard minimaliste.
Architecture
Le système repose sur deux composants indépendants :
- Backend Python/FastAPI : sync engine + REST API (40+ endpoints, 11 routers)
- Frontend Next.js : dashboard PWA avec proxy API sécurisé
Garmin Connect (OAuth)
│
FastAPI (Railway)
├── SyncManager (5 fetchers)
├── REST API (40+ endpoints)
└── asyncpg → PostgreSQL (Neon)
│
Next.js (Vercel)
├── Proxy API (clé cachée server-side)
├── Auth Better-Auth
└── Charts Plotly
Stack technique
| Composant | Technologie |
|---|---|
| Backend | Python 3.11+, FastAPI, asyncpg |
| Frontend | Next.js 16, React 19, TypeScript |
| Auth | Better-Auth (email/password) |
| Base de données | PostgreSQL 15+ (Neon) + réplica NAS |
| Visualisation | Plotly.js (client-side) |
| Déploiement | Railway (API) + Vercel (front) |
| CI/CD | GitHub Actions |
Résultats
- Sync automatique : cron quotidien, données Garmin récupérées via OAuth
- Dashboard : résumé hebdomadaire, readiness, tendances
- PWA : installable sur mobile, service worker Serwist
- Sécurité : tokens OAuth chiffrés Fernet, clé API jamais exposée côté client
- Réplica NAS : réplication logique PostgreSQL vers le homelab
Ce que j'ai appris
- Gérer l'authentification OAuth Garmin (rate limiting, retry, refresh tokens)
- Concevoir une API REST structurée avec FastAPI et asyncpg
- Mettre en place un proxy API côté Next.js pour protéger les clés
- Configurer la réplication logique PostgreSQL entre Neon et un NAS