PD-248 — Retour d'Expérience (REX)¶
1. Résumé de la story¶
| Champ | Valeur |
|---|---|
| ID | PD-248 |
| Titre | [INV-242-10] Implémenter protection screenshot native iOS |
| Projet | ProbatioVault-app |
| Domaine | crypto |
| Durée totale | ~8 heures |
| Complexité | Medium |
2. Contexte et objectif¶
Cette story implémente la protection anti-screenshot native iOS pour les écrans sensibles de l'application ProbatioVault (phrase de récupération BIP-39, codes TOTP, clés API). L'objectif est d'empêcher la capture d'écran pour protéger les données cryptographiques sensibles conformément à l'invariant INV-242-10 de PD-242.
3. Résultats¶
Livrables produits¶
| Livrable | Fichier | Couverture tests |
|---|---|---|
| Hook useScreenshotProtection | src/hooks/useScreenshotProtection.ts | 100% |
| Service screenshotProtectionLogger | src/services/screenshotProtection.ts | 100% |
| Intégration écrans recovery | src/screens/recovery/*.tsx | >80% |
| Tests unitaires | src/__tests__/hooks/useScreenshotProtection.*.ts | 100% |
| Tests E2E | src/__tests__/e2e/screenshot-protection.e2e.ts | N/A (OCR) |
Métriques finales¶
| Métrique | Valeur | Seuil |
|---|---|---|
| new_coverage | >80% | ≥80% ✅ |
| new_violations | 0 | 0 ✅ |
| Tests passants | 1452 | - |
| Pipeline CI | SUCCESS | ✅ |
4. Itérations de gates¶
| Gate | Itération | Verdict | Score | Écarts majeurs |
|---|---|---|---|---|
| 3 | 1 | GO | 8.75/10 | Aucun |
| 5 | 1 | RESERVE | 7.875/10 | REC-248-01: Robustesse OCR |
| 8 | 1 | RESERVE | 7.75/10 | DIV-248-02: Intégration écrans non testée |
Analyse des écarts¶
Gate 5 (Plan): - REC-248-01: Robustesse OCR pour tests E2E insuffisamment documentée - Action: Ajout de retry et seuil de confiance dans les tests E2E
Gate 8 (Closure): - DIV-248-02: Tests d'intégration des écrans recovery incomplets - Action: Ajout de RecoveryRestoreScreen.integration.test.tsx avec couverture >90%
5. Écarts Sonar résolus¶
| Règle | Description | Fichiers impactés | Correction |
|---|---|---|---|
| S6479 | Do not use Array index in keys | MnemonicDisplay, MnemonicInput | Utilisation de clés statiques |
| S7723 | Use new Array() instead of Array() | MnemonicInput | Syntaxe corrigée |
| S1874 | SafeAreaView deprecated | RecoveryScreens | Import depuis react-native-safe-area-context |
6. Patterns techniques identifiés¶
Pattern 1: Protection screenshot avec useFocusEffect¶
// Pattern efficace pour activer/désactiver sur navigation
useFocusEffect(
useCallback(() => {
if (Platform.OS !== "ios") {
screenshotProtectionLogger.logIncompatibleEnvironment();
return;
}
preventScreenCaptureAsync().catch((e) =>
screenshotProtectionLogger.logActivationError("SCR-248-01", e)
);
return () => {
allowScreenCaptureAsync().catch((e) =>
screenshotProtectionLogger.logActivationError("SCR-248-01", e)
);
};
}, [])
);
Pattern 2: Tests d'intégration pour callbacks React¶
// Pour couvrir les callbacks non-mockés, utiliser des tests d'intégration
// qui triggent les vrais callbacks via les composants enfants
describe("handlePhraseComplete - success path", () => {
it("should call recovery service functions", async () => {
render(<RecoveryRestoreScreen />);
const inputs = screen.getAllByPlaceholderText("word");
for (let i = 0; i < 24; i++) {
fireEvent.changeText(inputs[i], validMnemonicWords[i]);
}
await act(async () => {
fireEvent.press(screen.getByText("Verify"));
});
await waitFor(() => {
expect(mockDeriveRecoveryKey).toHaveBeenCalled();
});
});
});
7. Points positifs¶
- Implémentation simple et efficace: Le hook
useScreenshotProtectionest une solution élégante et réutilisable - Logging technique silencieux: Respect de l'invariant INV-248-04 (pas d'alerte utilisateur)
- Compatibilité Expo SDK 54: Utilisation de
expo-screen-capturesans code natif custom - Couverture exhaustive: 100% sur le code core, tests multi-plateformes
8. Points d'amélioration¶
-
Tests d'intégration dès le départ: Les tests unitaires avec mocks ne couvrent pas les callbacks React. Prévoir des tests d'intégration dès la phase de plan.
-
Sonar new_coverage difficile à atteindre: La métrique
new_coveragecalcule uniquement sur les fichiers modifiés. Toucher un fichier existant avec faible couverture impacte la moyenne. -
E2E OCR: Les tests E2E avec OCR sont complexes à mettre en place et nécessitent un environnement spécifique (Tesseract, simulateur).
9. Leçons apprises¶
Learning 1: Tests d'intégration pour callbacks React¶
Tags: #testing #react #coverage Description: Les tests unitaires avec mocks des composants enfants ne couvrent pas les callbacks passés en props. Pour atteindre >80% de couverture sur les écrans React, il faut des tests d'intégration qui utilisent les vrais composants enfants.
Learning 2: Sonar S6479 et clés de liste¶
Tags: #sonar #react #lint Description: Sonar détecte key={index} et key={\prefix-${index}`}` comme violations de S6479. Solutions: utiliser des IDs uniques, ou un tableau constant de clés statiques.
Learning 3: SafeAreaView deprecated¶
Tags: #react-native #migration Description: SafeAreaView de react-native est deprecated. Utiliser SafeAreaView de react-native-safe-area-context à la place.
10. Propositions d'amélioration du process¶
10.1 Template de tests d'intégration¶
Fichier: templates/prompts/6b-agent-qa-integration.md Priorité: haute Description: Ajouter une section explicite demandant des tests d'intégration pour les écrans React, en plus des tests unitaires.
10.2 Checklist pré-merge couverture¶
Fichier: CLAUDE.md Priorité: moyenne Description: Ajouter une vérification locale de la couverture avant le merge vers dev pour éviter les échecs Sonar.
10.3 Exclusions Sonar pour screens UI¶
Fichier: sonar-project.properties Priorité: basse Description: Considérer l'exclusion partielle des screens UI purement déclaratifs de la couverture (discussion avec l'équipe).
11. Conclusion¶
PD-248 a été implémenté avec succès. La protection screenshot est opérationnelle sur iOS pour tous les écrans sensibles. Les gates ont permis d'identifier des points d'amélioration (robustesse OCR, tests d'intégration) qui ont été corrigés avant le merge.
Recommandation: Planifier un test manuel sur device physique avec build EAS production pour valider le comportement réel de la protection screenshot.
Document généré le 2026-02-20 Co-Authored-By: Claude Opus 4.5 noreply@anthropic.com