Aller au contenu

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

  • 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

  1. La route SealDetail sera ajoutee au RootStackParamList de AppNavigator.tsx avec les params { sealId: string }. Ce module ne modifie pas AppNavigator (hors perimetre agent).
  2. L'integration dans handlers.ts sera faite par l'orchestrateur : appeler resolveSealNotificationTarget(data) dans handleNotificationResponse quand data.type === "seal_terminal".
  3. 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)