Introduction
Il y a 52 jours, le 1er janvier 2026, j'ai pris une résolution. Pas une de ces grandes déclarations qu'on oublie mi-février — un truc simple, concret, mesurable : faire des pompes tous les jours.
Ce n'est pas la première fois que j'essaye. J'ai toujours fait du sport de manière intermittente. Mais avec le monde de la startup — les deadlines, les sprints, les soirées à debugger en prod — j'ai plusieurs fois perdu la motivation. Trois semaines d'affilée, puis plus rien pendant deux mois. Le schéma classique.
Cette fois, j'ai décidé de traiter le problème comme un développeur : avec du code, des données, et un système qui ne me laisse pas tricher.
Le problème : la motivation ne suffit pas
La motivation, c'est un pic. Ça monte fort le 1er janvier, et ça redescend doucement vers le 20. Les études en psychologie comportementale le montrent : la motivation intrinsèque seule ne suffit pas pour maintenir une habitude. Il faut un système.
Duolingo l'a compris depuis longtemps. Leur mécanique de streak — cette série de jours consécutifs qu'on ne veut surtout pas casser — est un levier psychologique redoutable. Quand tu as 30 jours de streak, rater un jour te coûte émotionnellement bien plus que le simple effort de faire tes pompes.
J'ai décidé de construire le même mécanisme, mais pour mes pompes.
Version 1 : le composant web
Le tracker est d'abord né dans mon portfolio. Un composant Vue intégré à mon site Nuxt, avec :
- Un stepper (+5/-5) pour ajuster le nombre de pompes
- Un calendrier visuel : les jours validés sont cochés en or, les jours manqués en rouge
- Un compteur de streak bien visible
- Des statistiques : total de pompes, nombre de jours, meilleur streak
Le backend est minimal : trois endpoints Nitro (stats, entries, validate) qui tapent dans une table PostgreSQL sur Neon. Pas d'authentification, pas de complexité inutile. Juste moi et mes pompes.
Ça a marché. Les 10 premiers jours, le simple fait de voir le calendrier se remplir m'a motivé. Au jour 20, je ne voulais plus casser la chaîne. Au jour 30, c'était devenu un réflexe.
Le problème du web sur mobile
Mais au quotidien, ouvrir un navigateur, taper l'URL, attendre le chargement... c'est trop de friction. La plupart du temps, je valide mes pompes le matin au réveil ou le soir avant de dormir. Sur mon téléphone. Et l'expérience web mobile n'est pas assez fluide pour un geste qu'on répète chaque jour.
J'ai donc construit une application Android native.
L'application Android
L'app est écrite en Kotlin avec une architecture classique MVVM :
- Room pour le cache local — même hors connexion, je vois mes données
- Retrofit 2 pour la synchronisation avec le backend Nuxt
- ViewModel + LiveData pour un UI réactif
- SwipeRefreshLayout pour le pull-to-refresh
Mais le vrai game-changer, c'est le widget.
Le widget qui change tout
J'ai ajouté un widget Android qui se place sur l'écran d'accueil. Il affiche le streak actuel et le statut du jour. Chaque fois que j'allume mon téléphone, je le vois. Impossible de l'ignorer. Impossible de se dire "je ferai ça plus tard".
Le widget se synchronise en arrière-plan via WorkManager toutes les 30 minutes. Pas besoin d'ouvrir l'app pour voir où j'en suis.
C'est cette combinaison — le streak psychologique + la visibilité permanente du widget — qui a fait tenir l'habitude pendant 52 jours sans interruption.
L'authentification Google OAuth
Au départ, l'app était un outil personnel. Pas d'auth, pas de notion d'utilisateur. Mais j'ai voulu la rendre partageable — que d'autres personnes puissent l'utiliser avec leurs propres données.
Le choix de l'authentification a été réfléchi. Le client principal est une app Android native. Les sessions/cookies sont pensées pour le web. J'ai opté pour une approche stateless :
- Android obtient un Google ID Token via Credential Manager
- Le token est envoyé dans le header
Authorization: Bearerà chaque requête - Le backend vérifie le token avec
google-auth-libraryet upsert l'utilisateur
Pas de sessions à gérer côté serveur. Pas de cookies. Compatible avec le serverless de Vercel. Et l'expérience utilisateur est transparente : un tap sur "Se connecter avec Google" et c'est réglé.
La migration des données existantes
Le moment délicat : j'avais déjà 52 jours de données sans notion d'utilisateur. La migration s'est faite en trois étapes :
- Ajout de la table
userset de la colonneuserId(nullable) danshealth_entries - Script de migration qui rattache toutes les entries existantes à mon compte
- Ajout de la contrainte unique composite
(userId, date)
Zéro donnée perdue. Mon streak de 52 jours est intact.
Le light mode
Détail qui compte : j'ai passé l'application en light mode. Fond beige #F5F2EC, le même que mon portfolio. Si vous avez lu mon article sur l'abandon du dark theme, vous savez pourquoi. Cohérence visuelle, lisibilité, et alignement avec ma conviction que le light mode est sous-estimé.
Les chiffres après 52 jours
- 52 jours de streak ininterrompu
- 1 080 pompes au total (20/jour en janvier, 25/jour depuis mi-février)
- 0 jour manqué depuis le 1er janvier
- Temps moyen : moins de 2 minutes par session
Ce n'est pas un exploit sportif. 20-25 pompes par jour, c'est accessible à presque tout le monde. Mais la régularité sur 52 jours, ça c'est le résultat du système.
Ce que j'ai appris
La gamification fonctionne, même sur soi-même. Je savais intellectuellement que les streaks sont un levier puissant. Le vivre au quotidien, c'est différent. Au jour 40, je me suis surpris à faire mes pompes à 23h55, malade, juste pour ne pas perdre le streak.
La friction est l'ennemi de l'habitude. L'app web marchait, mais c'est le widget Android qui a tout changé. Réduire le nombre de taps entre "j'y pense" et "c'est fait" est crucial.
Over-engineering est tentant, mais inutile. Trois endpoints, une table, un token. Pas de framework d'auth complexe, pas de Redis pour les sessions, pas de microservices. Le système le plus simple qui fonctionne.
Conclusion
Ce projet est petit. Pas de millions d'utilisateurs, pas d'architecture distribuée complexe. Mais c'est peut-être le projet dont je suis le plus satisfait. Parce qu'il résout un vrai problème — le mien — et qu'il le résout bien.
52 jours et counting. L'objectif passera à 30 pompes en mars. Le streak continue.
Commentaires
Aucun commentaire pour le moment.