Mise à jour obligatoire
Jusqu’ici, quand une version de Kaiho corrigeait un bug, le correctif ne valait que pour les gens qui l’installaient. Rien ne pouvait empêcher l’ancienne version de continuer à tourner. On l’a payé plusieurs fois : le crash Android de la 1.9.0 en arrière-plan, la perte de progrès des leçons, les achats payés qui n’arrivaient pas jusqu’à RevenueCat. À chaque fois le correctif partait, puis on attendait.
La mise à jour obligatoire est l’interrupteur qui manquait. Quand il est armé, une version trop ancienne ne démarre plus : elle affiche un écran plein qui explique la situation, avec un seul bouton, vers le store.
Ce que voit l’utilisateur
Section intitulée « Ce que voit l’utilisateur »Un écran plein qui remplace tout — pas un bandeau, pas une fenêtre qu’on ferme :
Mise à jour nécessaire Cette version de Kaiho est trop ancienne pour continuer. Installe la dernière version, tes données et ton suivi sont conservés. [ Mettre à jour ]
La phrase sur les données est là exprès : devant un écran bloquant, la seule vraie inquiétude de quelqu’un qui arrête de fumer est de perdre son suivi. Le bouton ouvre la fiche Kaiho dans l’App Store ou le Play Store.
L’écran s’affiche avant la connexion. Une installation neuve, un lancement déconnecté, un compte en cours d’onboarding : tous passent par la barrière. C’est le but — la version qu’on retire est justement celle dont on sait qu’elle fait quelque chose de travers.
Comment on l’arme
Section intitulée « Comment on l’arme »Une table Supabase, app_version_gate, avec une ligne par plateforme. L’app lit la version minimale supportée à chaque lancement et à chaque retour au premier plan, et se bloque si sa propre version est en dessous.
| Colonne | Ce que c’est |
|---|---|
platform |
ios ou android — une ligne chacune, pour pouvoir bloquer une seule des deux apps |
min_version |
la version minimale autorisée, en 1.11.0. 0.0.0 veut dire « désarmé », et c’est la valeur normale |
latest_version |
réservée à une future incitation douce, pas encore lue par les apps |
Armer, c’est une requête :
update public.app_version_gate set min_version = '1.12.0', updated_at = now() where platform = 'ios';Désarmer, c’est la même avec '0.0.0'. Dans les deux cas, l’effet arrive au prochain lancement de l’app, ou dès le retour au premier plan pour quelqu’un qui l’a en arrière-plan.
Les deux règles à ne pas enfreindre
Section intitulée « Les deux règles à ne pas enfreindre »Ce qui se passe quand ça se passe mal
Section intitulée « Ce qui se passe quand ça se passe mal »La barrière laisse passer au moindre doute. Requête échouée, serveur injoignable, réponse illisible, numéro de version illisible : l’app démarre normalement. Une panne de notre côté ne doit jamais bloquer qui que ce soit.
Une seule exception, volontaire : l’app mémorise la dernière version minimale qu’elle a lue. Un lancement sans réseau utilise cette valeur. Sans ça, couper le réseau suffirait à passer outre la barrière.
Le mode démo (celui des captures d’écran des stores) ne se bloque jamais.
Ce qu’on ne fait pas, et pourquoi
Section intitulée « Ce qu’on ne fait pas, et pourquoi »- Aucun texte ne vient du serveur. La table ne transporte que des numéros de version ; les trois phrases de l’écran vivent dans les traductions de l’app, en six langues. Une chaîne venue du réseau ne serait pas traduisible, et un écran bloquant non traduit serait le pire endroit pour s’en apercevoir.
- Pas d’incitation douce pour l’instant. Une seule mécanique : bloqué, ou pas. La colonne
latest_versionexiste pour le jour où on voudra un simple « une mise à jour est dispo », mais les apps ne la lisent pas encore. - Pas de flux natif Play In-App Update. Il ne marche que pour les installations venues du Play Store, sa priorité se fixe au moment de la publication sans pouvoir être changée après, et il ne se teste qu’en partage interne. Le bouton ouvre la fiche du store, identiquement sur les deux apps.
- Aucun event de tracking. Une fois la barrière armée, « une session bloquée » c’est exactement « une session dont la version est sous le minimum » — et la version est déjà attachée à tous les events. Compter deux fois la même chose n’apprend rien.