Aller au contenu

PD-174 — Retour d'expérience


📚 Navigation User Story | Document | | | ---------- | -- | | 📋 [Spécification](PD-174-specification.md) | | | 🛠️ [Plan d'implémentation](PD-174-plan.md) | | | ✅ [Critères d'acceptation](PD-174-acceptability.md) | | | 📝 **Retour d'expérience** | *(ce document)* | [← Retour à mobile-ios](../PD-195-epic.md) · [↑ Index User Story](index.md)

1. Résumé exécutif

La User Story PD-174 visait à implémenter un mécanisme de verrouillage automatique configurable avec effacement du cache sensible lors du passage en arrière-plan ou après inactivité. L'implémentation fournit le timer d'inactivité, la détection background et l'effacement partiel du cache, mais présente 2 écarts MAJEURS : pas de LockScreen/blocage navigation, et effacement cache incomplet (les données déchiffrées du vault ne sont pas effacées). Verdict : ACCEPTÉ AVEC RÉSERVES.


2. Points fluides

  • useAutoLock hook : architecture propre avec timer, refs, callbacks et cleanup
  • AppState handling : détection foreground/background fonctionnelle via React Native AppState
  • useSecurityStore : store Zustand bien structuré avec état isLocked, autoLockEnabled, autoLockTimeout
  • useUserActivity : hook dédié pour détecter touches, scrolls, keypresses
  • Callbacks extensibles : onBeforeLock et onAfterLock permettent d'injecter logique métier
  • Tests exhaustifs : 400+ lignes de tests couvrant tous les scénarios (timer, background, disabled)
  • Protection double-lock : ref isLockingRef évite les verrouillages concurrents
  • Timer cleanup : clearTimers() dans useEffect cleanup évite memory leaks
  • Options disabled : permet de désactiver l'auto-lock sur écrans onboarding/login

3. Points difficiles

Difficulté Contexte
Bug perte données vault Vider le vault store via setState({}) déclenchait le persist middleware qui écrasait les données persistées avec des tableaux vides
Intégration navigation Le plan prévoyait un LockScreen modal + blocage navigation, non implémenté dans cette US
Délimitation périmètre La spec mentionne "redirection vers écran de déverrouillage existant" mais cet écran n'existe pas encore
Effacement sélectif Distinguer données sensibles (password) des données fonctionnelles (vault) requiert analyse fine

4. Hypothèses révélées tardivement

Hypothèse initiale Réalité découverte
L'écran de déverrouillage existe déjà FAUX — Pas de LockScreen.tsx dans le codebase, dépendance non satisfaite
Vider le vault store est safe FAUX — Le middleware persist écrase les données persistées, causant perte de dossiers
Les données vault sont sensibles PARTIELLEMENT FAUX — Déjà chiffrées en persistence, le password est la vraie donnée sensible
Le blocage navigation est simple FAUX — Nécessite modal overlay ou navigation guard, complexité sous-estimée

5. Invariants complexes à implémenter

Invariant Complexité
Timer reset sur activité Coordination entre useUserActivity et useAutoLock via callback
Pas de double-lock Ref isLockingRef nécessaire pour éviter race conditions
Lock immédiat sur background Doit être synchrone, pas d'await possible dans AppState callback
Préserver données vault Ne PAS vider le store pour éviter écrasement persistence
Effacement password mémoire Manipulation directe du state via useAuthStore.setState()

6. Dette technique

Dette Impact Priorité
Pas de LockScreen Verrouillage non effectif, juste état isLocked HAUTE
Pas de blocage navigation Écrans protégés restent accessibles HAUTE
Vault non vidé au lock Données déchiffrées restent en mémoire MOYENNE
rehydrateVaultAfterUnlock vide Fonction placeholder, ne fait rien d'utile BASSE
Délais différents plan vs spec Plan: ⅕/15/30min, Spec: 30s/½/5/10min BASSE

7. Risques résiduels

Risque Probabilité Impact Mitigation suggérée
Accès écrans sans déverrouillage Élevée ÉLEVÉ Implémenter LockScreen + navigation guard
Données déchiffrées en mémoire Élevée MOYEN Accepté comme compromis vs bug perte données
Timer non précis en background Moyenne FAIBLE iOS limite les timers, comportement attendu
Race condition lock/unlock Faible MOYEN Protection par ref déjà en place
Password reste en mémoire si erreur Faible MOYEN try/finally autour du setState

8. Améliorations processus

Amélioration Bénéfice attendu
Vérifier existence dépendances LockScreen "existant" n'existait pas, créer ou lier à une US
Tester persist middleware Le bug perte données aurait été détecté plus tôt
Séparer US verrouillage/navigation Clarifier périmètre : état vs blocage effectif
Documenter compromis sécurité Décision vault non vidé mérite documentation explicite
Aligner délais plan/spec Éviter confusion sur les valeurs attendues

9. Enseignements clés

  1. Le persist middleware est piégeux — Appeler setState({}) sur un store Zustand persisté écrase les données en AsyncStorage. Toujours tester le comportement avec les middlewares actifs.

  2. Une dépendance "existante" doit être vérifiée — La spec suppose un "écran de déverrouillage existant" qui n'existe pas. Vérifier les hypothèses de dépendance avant de commencer l'implémentation.

  3. L'effacement cache est un compromis — Vider les données déchiffrées causerait leur perte permanente (bug persist). Le compromis documenté est d'effacer seulement le password (vraie donnée sensible).

  4. L'état isLocked ne suffit pas — Un boolean dans le store ne bloque pas l'accès aux écrans. Une vraie protection nécessite un modal overlay ou un navigation guard.

  5. Les délais de la spec et du plan divergent — Spec: 30s, 1min, 2min, 5min, 10min. Plan: 1min, 5min, 15min, 30min, jamais. Cette incohérence devrait être résolue avant implémentation.