Aller au contenu principal
AnthemionAnthemion
Retour aux projets

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
HillsRun

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

ComposantTechnologie
BackendPython 3.11+, FastAPI, asyncpg
FrontendNext.js 16, React 19, TypeScript
AuthBetter-Auth (email/password)
Base de donnéesPostgreSQL 15+ (Neon) + réplica NAS
VisualisationPlotly.js (client-side)
DéploiementRailway (API) + Vercel (front)
CI/CDGitHub 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