Sprint qualite : corriger les bugs silencieux qui font desinstaller
Un rappel qui disparait sans prevenir, un email qui n'arrive jamais, une erreur fantome au demarrage : ces bugs ne font pas la une d'un changelog, mais ils detruisent la confiance de tes utilisateurs. En une journee de sprint qualite, j'ai corrige quatre problemes silencieux dans TAMSIV — mon gestionnaire de taches vocal pour Android — et l'experience au quotidien a radicalement change.
Points cles a retenir :
- Les bugs silencieux (rappels supprimes, emails muets, erreurs flash) causent plus de desinstallations que les crashes visibles.
- Activer push ET email par defaut pour les rappels elimine 90% des tickets "je n'ai pas ete notifie".
- Un sprint qualite sans nouvelle feature est l'investissement le plus rentable pour la retention utilisateur.
- La traduction complete de chaque fonctionnalite (ici les badges en 6 langues) est un signal de respect envers les utilisateurs internationaux.
Pourquoi un sprint qualite est plus important qu'une nouvelle feature ?
Quand tu developpes une app en solo, la tentation est permanente : ajouter des fonctionnalites. Un nouveau filtre ici, une integration la. C'est gratifiant, ca se montre facilement en screenshot, ca fait un beau commit.
Mais la realite, c'est que les utilisateurs ne desinstallent pas une app parce qu'il manque une feature. Ils desinstallent parce qu'un rappel n'a pas fonctionne. Parce qu'un email n'est jamais arrive. Parce qu'une erreur incomprehensible est apparue au demarrage.
Selon une etude de UserTesting, 88% des utilisateurs ne reviennent jamais apres une mauvaise experience. Et les bugs silencieux — ceux qui ne font pas crasher l'app mais qui erosent la confiance — sont les plus dangereux. Tu ne recois pas de rapport de crash. L'utilisateur ne signale rien. Il part, c'est tout.
C'est pour ca que j'ai decide de consacrer une journee entiere a un sprint 100% qualite. Pas de nouvelle fonctionnalite. Pas de refactoring ambitieux. Juste quatre corrections chirurgicales qui, mises bout a bout, changent vraiment l'experience de TAMSIV au quotidien.
Comment des rappels valides peuvent-ils disparaitre en silence ?
Le scenario : tu crees une tache avec trois rappels — un dans 10 minutes, un demain matin, un vendredi. Sauf que le premier rappel est deja dans le passe (tu as mis trop de temps a valider). TAMSIV affichait un avertissement : "Ce rappel est dans le passe". Jusque-la, logique.
Le probleme ? En fermant cet avertissement, tous les rappels etaient supprimes. Les deux rappels futurs, parfaitement valides, partaient avec. Un nettoyage un peu trop zele dans le code de validation.
Ce genre de bug est particulierement vicieux. L'utilisateur ne sait meme pas que ses rappels ont disparu. Il attend la notification de demain matin... qui ne viendra jamais. Et il blamera l'app — a juste titre.
La correction technique
La solution a consiste a separer clairement les rappels passes des rappels futurs dans la logique de validation. Concretement :
- Filtre temporel : seuls les rappels dont la date est anterieure a
Date.now()sont marques comme expires. - Avertissement cible : le message d'alerte ne concerne que les rappels effectivement dans le passe, avec leur nombre exact.
- Conservation garantie : les rappels futurs restent intacts, quoi que l'utilisateur fasse avec l'avertissement.
- Fuseaux horaires : j'en ai profite pour renforcer la gestion des timezones dans la validation — un cas limite que j'avais sous-estime.
Le systeme de rappels et recurrences est un pilier de TAMSIV. Un bug ici, meme minime, a un impact disproportionne sur la confiance utilisateur.
Pourquoi les emails de rappel n'arrivaient-ils jamais ?
TAMSIV supporte deux canaux de notification pour les rappels : le push (notification sur le telephone) et l'email. En theorie. En pratique, quand un utilisateur creait un rappel, seul le canal push etait active par defaut. L'email ? Desactive. Silencieusement.
Si tu n'allais pas manuellement cocher "email" dans les parametres du rappel, tu ne recevais jamais rien dans ta boite mail. Pas d'erreur, pas de message — juste le silence. Et pour un utilisateur qui ne consulte pas systematiquement son telephone, c'est un rappel completement rate.
Quel est le bon defaut pour les canaux de notification ?
La question semble triviale, mais elle ne l'est pas. Comme le recommande le Nielsen Norman Group dans ses recherches sur les valeurs par defaut, le defaut doit correspondre a ce que la majorite des utilisateurs attend. Et la majorite attend d'etre notifiee — par tous les canaux disponibles.
Maintenant, les deux canaux sont actives par defaut. Tu recois un push et un email. Si tu veux desactiver l'un des deux, c'est toujours possible, mais le comportement par defaut est celui que tout le monde attend. C'est le principe du sane default — un concept central dans la conception d'applications de productivite.
D'ou vient cette erreur "Invalid Refresh Token" au demarrage ?
Celle-la, c'est le genre de bug qui ne casse rien mais qui mine la confiance. Tu ouvres l'app apres quelques heures d'inactivite, et pendant une fraction de seconde, une erreur "Invalid Refresh Token" flashe a l'ecran. Puis tout fonctionne normalement.
Imagine : tu ouvres TAMSIV le matin pour voir tes taches du jour, et la premiere chose que tu vois, c'est une erreur. Tu ne sais pas ce qu'elle signifie. Tu ne sais pas si tes donnees sont en securite. Tu ne sais pas si l'app fonctionne correctement. Meme si tout est parfaitement OK en realite, l'impression est desastreuse.
L'analyse technique du probleme
Au demarrage a froid, Supabase Auth tentait de rafraichir le token d'authentification. Si le token avait expire (apres quelques heures d'inactivite), le SDK levait une erreur avant que le mecanisme de reconnexion automatique n'ait le temps de faire son travail.
L'erreur remontait jusqu'a l'UI alors qu'elle n'avait aucune raison d'y etre — la reconnexion finissait toujours par reussir. C'est un pattern classique dans les apps utilisant des tokens JWT avec refresh automatique : le premier appel echoue, le refresh se declenche, le deuxieme appel reussit.
La correction intercepte cette erreur specifique (AuthApiError avec le code invalid_refresh_token) au bon niveau et la supprime de l'affichage. Le rafraichissement de session continue de fonctionner exactement comme avant, mais l'utilisateur ne voit plus un message anxiogene qui ne le concerne pas.
Ce type de gestion d'erreur est critique pour toute app utilisant l'authentification Supabase. Le SDK fait bien son travail — il faut juste eviter d'exposer ses erreurs intermediaires a l'utilisateur.
Comment traduire un systeme de gamification dans 6 langues ?
TAMSIV est disponible en francais, anglais, allemand, espagnol, italien et portugais. Le systeme de gamification — niveaux, badges, streaks — fait partie des fonctionnalites que les utilisateurs decouvrent progressivement. Sauf que le guide explicatif des badges n'existait qu'en francais et en anglais.
C'est un probleme plus subtil qu'il n'y parait. Un utilisateur germanophone qui decouvre le systeme de badges et qui tombe sur un texte en francais ou en anglais va immediatement sentir que cette partie de l'app n'est pas finie. C'est un signal negatif tres fort, surtout quand le reste de l'interface est correctement traduit.
Le processus d'internationalisation des badges
Les 10 badges de TAMSIV ont chacun un nom, une description et des conditions de deblocage. Ca fait 30 chaines de texte a traduire dans 4 langues supplementaires (allemand, espagnol, italien, portugais). Le systeme d'internationalisation en 6 langues que j'ai mis en place gere ca avec un pipeline de traduction automatique via OpenRouter, suivi d'une relecture manuelle pour les termes de gamification.
Ce n'est pas un fix spectaculaire, mais c'est le genre de detail qui fait qu'un utilisateur lusophone ou germanophone se sent chez lui dans l'app. Et comme l'explique CSA Research, 76% des consommateurs preferent acheter des produits dans leur propre langue.
Quel est l'impact reel de ces corrections sur la retention ?
Ces quatre corrections representent une journee de travail. Aucune n'aurait fait un titre de changelog excitant. Mais ensemble, elles eliminent des frictions reelles :
- Rappels perdus : plus aucun rappel valide ne disparait suite a un avertissement sur un rappel expire.
- Emails manques : les deux canaux de notification sont actifs par defaut, plus de surprise.
- Erreur au demarrage : le message "Invalid Refresh Token" ne s'affiche plus jamais.
- Gamification traduite : les 10 badges sont disponibles dans les 6 langues supportees.
En termes de retention, chacun de ces bugs etait un point de friction invisible. L'utilisateur ne signale pas "ton email de rappel n'est pas arrive" — il se dit simplement que l'app ne fonctionne pas et il la desinstalle. Selon Adjust, le taux de retention moyen d'une app a J30 est de 6%. Chaque friction eliminee pousse ce chiffre vers le haut.
Comment organiser un sprint qualite quand on est dev solo ?
Etre developpeur solo sur un projet comme TAMSIV signifie que personne ne va planifier un sprint qualite a ta place. Voici la methode que j'utilise :
- Utiliser sa propre app quotidiennement — le dogfooding est la meilleure source de bugs. Chaque irritation notee dans un memo vocal (avec TAMSIV, evidemment).
- Prioriser par impact utilisateur — un bug qui affecte 100% des utilisateurs a chaque demarrage passe avant un bug qui touche 2% des cas.
- Limiter le scope — une journee, 4 corrections maximum. Pas de refactoring tentant en cours de route.
- Tester sur de vrais appareils — les 12 beta-testeurs sont la pour ca. Un bug reproduit sur 3 appareils differents est un vrai bug.
Le sprint zero-feature que j'ai fait la semaine suivante a confirme cette approche : les retours des beta-testeurs etaient bien meilleurs apres ces corrections silencieuses qu'apres l'ajout de nouvelles fonctionnalites.
Questions frequentes
Combien de temps faut-il pour un sprint qualite efficace ?
Une journee concentree suffit pour 3 a 5 corrections ciblees. L'important est de ne pas melanger avec du developpement de features — le contexte mental est different. Je recommande un sprint qualite toutes les 2 semaines pour un projet en phase de lancement.
Comment detecter les bugs silencieux quand il n'y a pas de crash report ?
Le dogfooding quotidien est la methode numero un. Utilise ta propre app comme un utilisateur normal, pas comme un developpeur. Les outils comme Firebase Analytics aident aussi a detecter des patterns anormaux (sessions tres courtes, fonctionnalites jamais utilisees).
Pourquoi activer push ET email par defaut plutot que laisser l'utilisateur choisir ?
Parce que la majorite des utilisateurs ne changent jamais les parametres par defaut (recherches du Nielsen Norman Group). Le opt-out est plus respectueux que le opt-in pour les notifications de rappel — l'utilisateur a explicitement demande a etre rappele, il s'attend a recevoir la notification sur tous les canaux disponibles.
L'erreur "Invalid Refresh Token" est-elle dangereuse pour les donnees ?
Non, absolument pas. C'est une erreur intermediaire normale dans le flux de rafraichissement de token JWT. Supabase Auth gere ca automatiquement — le token expire est remplace par un nouveau en arriere-plan. Le probleme etait uniquement l'affichage de cette erreur technique a l'utilisateur.
Comment gerer la traduction de termes de gamification (badges, niveaux) ?
J'utilise un pipeline de traduction automatique via OpenRouter, suivi d'une relecture pour les termes specifiques au gaming. Certains termes comme "streak" ou "badge" sont souvent gardes en anglais meme dans les versions localisees, car ils sont universellement compris par les utilisateurs d'apps mobiles.