PD-284 — Agent Developer : Module seal-navigation
1. Module
| Attribut | Valeur |
| Module | seal-navigation |
| Fichier principal | src/navigation/seal-deep-link.ts |
| Projet cible | ProbatioVault-app |
| Agent | agent-developer (Claude) |
2. Responsabilite
Gestion des deep-links de scellement : resolution des liens probatiovault://seal/{uuid} depuis les notifications terminales vers l'ecran SealDetail, avec validation de securite (whitelist scheme interne) et resilience aux liens malformes.
3. Implementation
3.1. Exports publics
| Export | Type | Description |
SEAL_LINKING_CONFIG | const (objet) | Configuration React Navigation pour NavigationContainer. Enregistre le prefix probatiovault:// et le mapping seal/:sealId vers la route SealDetail. |
resolveSealDeepLink(deepLink) | function | Resout un deep-link brut (string) en NavigationTarget | null. Valide le scheme (SEC-01), extrait le sealId via validateSealDeepLink, journalise les rejets. |
resolveSealNotificationTarget(data) | function | Point d'integration avec handlers.ts. Filtre data.type === "seal_terminal", extrait data.deep_link, delegue a resolveSealDeepLink. |
3.2. Dependances internes
| Dependance | Import | Usage |
seal/notifications.ts | validateSealDeepLink | Validation format + extraction SealId |
seal/telemetry.ts | logControlledError | Journalisation erreurs controlees |
types/seal.ts | SEAL_DEEP_LINK_SCHEME, SEAL_DEEP_LINK_PATTERN, SealId | Constantes et types |
types/navigation.ts | NavigationTarget | Type de retour pour routage |
3.3. Flux de resolution
Notification tap
-> handleNotificationResponse (handlers.ts)
-> resolveSealNotificationTarget(data)
-> data.type === "seal_terminal" ?
-> resolveSealDeepLink(data.deep_link)
-> scheme whitelist check (SEC-01)
-> validateSealDeepLink (format + UUID)
-> NavigationTarget { screen: "SealDetail", params: { sealId } }
4. Couverture des invariants et tests contractuels
| Invariant / Test | Couverture | Mecanisme |
| INV-284-08 | Oui | resolveSealDeepLink produit un NavigationTarget avec sealId valide vers SealDetail |
| TC-NOM-09 | Oui | Deep-link succes (SEALED) resolu vers ecran detail |
| TC-NOM-10 | Oui | Deep-link echec (FAILED_TIMEOUT) resolu vers ecran detail |
| TC-ERR-07 | Oui | Deep-link malforme retourne null sans crash, erreur journalisee |
| TC-NEG-07 | Oui | Scheme externe rejete (logControlledError + retour null) |
| SEC-01 | Oui | Whitelist probatiovault:// verifie en premier ; tout autre scheme rejete |
5. Decisions architecturales
D1 — Resolution en deux couches (notification + deep-link)
- Decision : Separer
resolveSealNotificationTarget (filtre payload notification) de resolveSealDeepLink (validation deep-link pure). - Rationale : Permet de reutiliser
resolveSealDeepLink pour d'autres sources de deep-links (universal links, QR codes) sans couplage aux notifications. - Alternatives : Fonction monolithique dans
handlers.ts. - Trade-offs : Un fichier supplementaire, mais decouplage propre et testabilite unitaire.
D2 — SEAL_LINKING_CONFIG comme objet statique
- Decision : Exporter la config de linking comme constante (
as const) plutot que comme fonction. - Rationale : React Navigation attend un objet stable ; une constante evite les re-renders inutiles du
NavigationContainer. - Alternatives : Factory function avec parametres dynamiques.
- Trade-offs : Pas de configuration dynamique du scheme, mais le scheme est fixe par contrat (SEC-01).
6. Hypotheses
- La route
SealDetail sera ajoutee au RootStackParamList de AppNavigator.tsx avec les params { sealId: string }. Ce module ne modifie pas AppNavigator (hors perimetre agent). - L'integration dans
handlers.ts sera faite par l'orchestrateur : appeler resolveSealNotificationTarget(data) dans handleNotificationResponse quand data.type === "seal_terminal". - Le
NavigationContainer dans App.tsx recevra linking={SEAL_LINKING_CONFIG} pour activer le routage automatique des deep-links a l'ouverture de l'app.
7. Fichiers modifies / crees
| Action | Fichier |
| Cree | src/navigation/seal-deep-link.ts |
8. Matrice de couverture tests
| Test-ID | Fichier source | Fonction testee |
| TC-NOM-09 | src/navigation/seal-deep-link.ts | resolveSealDeepLink (success path) |
| TC-NOM-10 | src/navigation/seal-deep-link.ts | resolveSealDeepLink (success path, same logic) |
| TC-ERR-07 | src/navigation/seal-deep-link.ts | resolveSealDeepLink (malformed -> null) |
| TC-NEG-07 | src/navigation/seal-deep-link.ts | resolveSealDeepLink (external scheme -> null) |