Documentation-RisqueCV

Logo RisqueCV RisqueCV.fr - Intégration logiciels tiers

Cette page décrit le protocole de communication bidirectionnel entre RisqueCV et ses partenaires.

RisqueCV.fr est un outil d’aide à la décision pour la prévention cardiovasculaire. Il permet d’évaluer le risque cardiovasculaire d’un patient et de générer un rapport PDF.

100% des calculs sont effectués côté client (Typescript), aucun envoi de données ni aucun calcul vers le serveur de RisqueCV.fr.

L’absence de serveur de calcul est un choix délibéré pour garantir la confidentialité des données des patients. Cette architecture rend impossible la mise à disposition d’une API REST ou SMART on FHIR.

L’intégration de RisqueCV.fr à un logicier métier repose donc sur l’API Standard window.postMessage, permettant un échange sécurisé des données cliniques. Ce protocole permet l’ouverture de RisqueCV.fr, le transfert de données cliniques du logiciel métier vers la fenêtre de RisqueCV.fr (sans transfert des données sur internet), la génération du PDF des résultats en local (librairie JS) et l’envoi du rapport PDF de RisqueCV.fr vers le logiciel métier sans transfert des données sur internet.

La méthode window.postMessage permet au médecin en consultation de préremplir les données cliniques et d’utiliser l’interface de RisqueCV.fr (courbes, graphiques, conseils, etc.) comme un outil d’aide à la décision.


🏗 Architecture du protocole

L’intégration repose sur un protocole d’échange de messages asynchrones via window.postMessage :

1. Ouverture

RisqueCV est conçu pour être ouvert depuis votre application via :

2. Établissement de la connexion (“handshake”)

Le protocole suit une machine à états stricte pour garantir la sécurité des données :

  1. Phase d’écoute : Dès l’ouverture, votre application doit se mettre à l’écoute de l’événement message global.
  2. Signal “ready” (RisqueCV ➡️ Partenaire) : Une fois chargé, RisqueCV émet un message risquecv:ready pour vous informer que le tunnel de communication est ouvert et vous transmettre un sessionId unique.
    • Obligation : Vous devez renvoyer le sessionId reçu lors de l’étape de prefill.
  3. Signal “ping” (Partenaire ➡️ RisqueCV) : Si votre application a manqué le signal initial (chargement asynchrone), vous pouvez envoyer un message { "type": "risquecv:ping" }. RisqueCV renverra immédiatement le signal ready.
  4. Injection “prefill” (Partenaire ➡️ RisqueCV) : En réponse au ready, vous envoyez vos données patient via un message risquecv:prefill.
  5. Verrouillage de session (Channel Locking) : À la réception de votre premier message de données (prefill), RisqueCV verrouille le canal. Pour le reste de la session, RisqueCV n’acceptera plus aucun message provenant d’une autre origine ou d’une autre fenêtre que la vôtre.

3. Traitement des données

L’algorithme de RisqueCV ne se contente pas de recevoir vos données, il assure leur intégrité :

4. UI adaptée au partenaire

5. Récupération du rapport (PDF)

Lorsque le médecin a terminé son évaluation sur RisqueCV :

  1. En cliquant sur le bouton “Envoyer vers Logiciel”, RisqueCV génère le rapport PDF localement dans le navigateur via la librairie pdfmake (aucune donnée n’est envoyée à nos serveurs).
  2. Il vous transmet le PDF via un message risquecv:pdf.
  3. Le payload contient le fichier encodé en Base64.
  4. En cas d’échec (ex: erreur mémoire), RisqueCV émet un message risquecv:error avec le code PDF_GENERATION_FAILED.

6. Fermeture de session

Lors du clic sur le bouton de retour, RisqueCV émet un signal risquecv:close. Voir la section “Résilience” ci-dessous pour la gestion des Iframes.


🔒 Sécurité et confidentialité

Ce protocole a été conçu pour répondre aux exigences les plus strictes de confidentialité (RGPD / HDS) :


🛡️ Résilience et Protocoles de repli

Pour garantir une expérience sans friction, RisqueCV implémente plusieurs mécanismes de sécurité :

Délai de repli (Handshake Timeout)

Si RisqueCV est ouvert en mode intégration mais ne reçoit aucun trafic valide (ni ping, ni prefill) dans les 5 secondes suivant son chargement, il bascule automatiquement en Mode Standard (autonome). Cela évite de bloquer le médecin si votre logiciel métier subit un bug technique.

Prévention de l’Inception (Iframes)

Rediriger une Iframe vers une URL externe peut provoquer le chargement de votre propre portail à l’intérieur de l’Iframe (Effet Inception).


🌐 Configuration Serveur (CSP)

Pour que votre logiciel puisse intégrer RisqueCV dans une Iframe, le serveur de RisqueCV doit vous y autoriser (Content-Security-Policy: frame-ancestors). Si vous constatez une erreur “Clickjacking” ou “Refused to frame”, demandez à ce que votre domaine soit bien whitelisté dans nos entêtes.


📖 Dictionnaire des caractéristiques

Le payload peut contenir n’importe quelle combinaison des clés ci-dessous. Toutes les valeurs sont optionnelles (null ou omission pour ignorer). Toute clé inconnue sera ignorée.

⚠️ ATTENTION, ERREURS FREQUENTES :

- Respecter la casse des clés (ex: PAS et non pas, HbA1c et non hba1c, age et non Age, etc.).
- Respecter les unités mentionnées (notamment mmol/L pour le cholestérol, % pour l'HbA1c).
- Respecter le typage des données, il faut envoyer des nombres pour les nombres, des booléens pour les booléens, etc.
- Ne pas envoyer de données nominatives (même si elles seront ignorées et non traitées).

1. Les 4 premières questions systématiques de RisqueCV.fr

Ces booléens pilotent les 4 premières questions du formulaire. Les mettre à false permet de sauter les questions de tri initiales.

Clé Type Description True si…
atcd boolean Antécédents de maladie cardiovasculaire avérée. Maladie coronaire (angor, IDM, SCA revascularisation), AVC, AIT, AOMI, anévrisme de l’aorte abdominale (voir la liste complète sur le site, sous le titre “Antécédents cardiovasculaires”)
diabete boolean Présence d’un diabète (Type 1 ou 2). Diabète type 1 ou 2
MRC boolean Maladie Rénale Chronique (DFG < 60 ou albuminurie). DFG < 60 ou albuminurie ou “Maladie rénale chronique”
autrepb boolean Autres situations (HyperCHO familiale, HTA secondaire, etc.). Hypercholestérolémie familiale hétérozygote, grossesse, etc. (voir la liste complète sur le site, sous le titre “Autre situation particulière ?”)

2. Valeurs numériques

Clé Type Unité Description
age number ans Âge du patient
PAS number mmHg Pression Artérielle Systolique (mesurée ce jour si possible).
CT number mmol/L Cholestérol Total
HDL number mmol/L Cholestérol HDL
LDL number mmol/L Cholestérol LDL
DFG number mL/min Débit de Filtration Glomérulaire
HbA1c number % Hémoglobine glyquée
crp number mg/L Protéine C-réactive ultra-sensible (hs-CRP) (attention pas la CRP standard)
imc number kg/m² Indice de Masse Corporelle
agediabete number ans Âge lors du diagnostic du diabète
age_atcd number ans Âge lors du premier événement cardiovasculaire (AVC, AIT, SCA, IDM, AOMI, anévrisme de l’aorte abdominale)

3. Valeurs de type string

Clé Type Valeurs autorisées (exemples)
sexe string "homme", "femme"
typediabete string "type1", "type2", "autre"
albuminurie string "non", "micro", "oui"
pays string "France", "region_low", "region_moderate", "region_high", "region_veryhigh"

Note sur la région/pays : Nous recommandons d’utiliser directement les codes de stratification européenne du risque ("region_low", "region_moderate", "region_high", "region_veryhigh") si votre logiciel en dispose. À défaut, vous pouvez envoyer le nom du pays européen en toutes lettres (ex: "France", "Belgique"), RisqueCV déduira automatiquement la région associée.

4. Booléens

Clé Type Description
tabac boolean Tabagisme actif actuel.
aspirine boolean Traitement antiagrégant plaquettaire en cours.
insuline boolean Diabète traité par insuline.
hyperCHOfamille boolean Hypercholestérolémie familiale hétérozygote connue.
retinopathie boolean Présence d’une rétinopathie diabétique.
neuropathie boolean Présence d’une neuropathie diabétique.
atcd_coronarien boolean Antécédent de maladie coronaire (IDM, SCA, revascularisation).
atcd_cerebrovasculaire boolean Antécédent d’AVC ou d’AIT.
atcd_aomi boolean Antécédent d’Artériopathie Oblitérante des Membres Inférieurs.
atcd_anevrismeAorte boolean Antécédent d’anévrisme de l’aorte abdominale.
microangiopathie3sites boolean Présence d’une microangiopathie sur ≥3 sites (ex: rétino + neuro + albu).
autreFacteurMajeur boolean Présence d’un autre facteur de risque majeur (pour l’HF).
evaluationComplete boolean Force l’affichage de l’évaluation complète (tunnel détaillé).

🛠 Exemples JS d’intégration côté partenaire

Voici des exemples prêts à l’emploi selon la méthode de rendu que vous utilisez (WebView ou Popup). N’hésitez pas à les dérouler pour voir le code.

💻 Exemple d'intégration pour WebView (Electron, React Native...)
// --- 1. CONFIGURATION ---
const CONFIG = {
    version: 1, // Version du protocole d'intégration RisqueCV
    partnerSlug: 'votre-slug', // Identifiant de votre logiciel (ex : "weda")
    targetOrigin: 'https://risquecv.fr' // Origine stricte
};

// --- 2. ÉTAT DE LA SESSION ---
const webview = document.getElementById('risquecv-webview');
let handshakeTimeout = null;

// --- 3. FONCTIONS UTILITAIRES ---
function fermerWebView() {
    webview.style.display = 'none';
    webview.src = 'about:blank';
}

/** Transmet le PDF (Base64) à votre API pour l'enregistrer dans le dossier patient */
async function sauvegarderPdf(base64Data, filename) {
    try {
        console.log(`Enregistrement du PDF ${filename} en cours...`);
        
        // Exemple d'appel API interne à votre logiciel
        const response = await fetch('/api/votre-logiciel/patients/12345/documents', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                nom_fichier: filename,
                contenu_base64: base64Data,
                type_document: 'EVALUATION_RISQUE_CV'
            })
        });

        if (response.ok) {
            console.log("✅ PDF sauvegardé avec succès dans le dossier patient.");
        } else {
            console.error("❌ Échec de la sauvegarde côté serveur.");
        }
    } catch (error) {
        console.error("Erreur technique lors de la sauvegarde du PDF :", error);
    }
}

// --- 4. DÉCLENCHEMENT DE L'OUVERTURE ---
document.getElementById('bouton-ouvrir-risquecv').addEventListener('click', () => {
    
    // Charger l'URL d'intégration
    webview.src = `${CONFIG.targetOrigin}/${CONFIG.partnerSlug}/`;
    webview.style.display = 'block'; 
    
    // Sécurité : Timeout si le chargement échoue. On effectue un "Ping" pro-actif.
    handshakeTimeout = setTimeout(() => {
        console.warn("⏳ Délai d'attente dépassé : RisqueCV ne répond pas. Tentative de Ping...");
        // L'envoi dépend de votre framework (ici webview standard HTML5)
        if (webview.contentWindow) {
            webview.contentWindow.postMessage({ type: 'risquecv:ping' }, CONFIG.targetOrigin);
        }
    }, 3000);
});

// --- 5. GESTION DES MESSAGES ---

// L'écouteur dépend de votre pont natif. window.addEventListener (Electron), window.chrome.webview.addEventListener (WebView2), etc.
window.addEventListener('message', (event) => {
    
    // Ignorer tout message ne provenant pas de RisqueCV
    if (event.origin !== CONFIG.targetOrigin) return;
    
    const msg = event.data;

    switch (msg.type) {
        
        // Si on reçoit "ready", alors on peut envoyer les données du patient
        case 'risquecv:ready':
            clearTimeout(handshakeTimeout);

            // Envoi des données cliniques du patient
            const payloadMessage = {
                type: 'risquecv:prefill',
                version: CONFIG.version,
                partner: msg.partner,
                sessionId: msg.sessionId,
                payload: { 
                    // Les données doivent être formatées avant l'envoi (ex: "femme" et pas "Femme" ni "F")
                    age: 55, 
                    sexe: "femme", 
                    tabac: false,
                    PAS: 142,
                    CT: 5.2,
                    HDL: 1.3
                    // Ajoutez vos autres variables cliniques ici. Le payload n'a pas besoin d'être exhaustif.
                }
            };

            webview.contentWindow.postMessage(payloadMessage, CONFIG.targetOrigin);
            break;

        // Si on reçoit "ack", alors RisqueCV a bien reçu les données
        case 'risquecv:prefill:ack':
            // Si nécessaire pour debug, on peut vérifier l'injection
            if (msg.status === 'partial') {
                console.warn('⚠️ Données ignorées par RisqueCV (hors-bornes ou inconnues) :', msg.ignoredKeys);
            }
            break;

        // Si on reçoit "pdf", alors on peut sauvegarder le PDF recu dans le dossier du patient
        case 'risquecv:pdf':
            fermerWebView();
            sauvegarderPdf(msg.data, msg.filename);
            break;

        // Si le médecin clique sur le bouton "Retour au logiciel", on masque l'interface
        case 'risquecv:close':
            console.log("Fermeture demandée par RisqueCV.");
            fermerWebView();
            break;

        // Si on reçoit "error", il y a eu un problème métier ou protocolaire
        case 'risquecv:error':
            console.error(`❌ Erreur RisqueCV [${msg.code}]:`, msg.message);
            break;
    }
});
💻 Exemple d'intégration avec fenêtre popup dans un nouvel onglet
// --- 1. CONFIGURATION ---
const CONFIG = {
    version: 1, // Version du protocole d'intégration RisqueCV
    partnerSlug: 'votre-slug', // Identifiant de votre logiciel (ex : "weda"))
    targetOrigin: 'https://risquecv.fr' // Origine stricte
};

// --- 2. ÉTAT DE LA SESSION ---
let popupWindow = null;
let messageListener = null;
let pollClosedInterval = null;
let handshakeTimeout = null;

// --- 3. FONCTIONS UTILITAIRES ---

/** Nettoie les écouteurs pour éviter les fuites de mémoire (memory leaks) */
function cleanupSession() {
    if (messageListener) {
        window.removeEventListener('message', messageListener);
        messageListener = null;
    }
    if (pollClosedInterval) {
        clearInterval(pollClosedInterval);
        pollClosedInterval = null;
    }
    if (handshakeTimeout) {
        clearTimeout(handshakeTimeout);
        handshakeTimeout = null;
    }
    popupWindow = null;
}

/** Transmet le PDF (Base64) à votre API pour l'enregistrer dans le dossier patient */
async function sauvegarderPdfEnBaseDeDonnees(base64Data, filename) {
    try {
        const response = await fetch('/api/votre-logiciel/patients/12345/documents', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({
                nom_fichier: filename,
                contenu_base64: base64Data,
                type_document: 'EVALUATION_RISQUE_CV'
            })
        });

        if (response.ok) {
            console.log("✅ PDF sauvegardé avec succès dans le dossier du patient.");
        } else {
            console.error("❌ Échec de la sauvegarde du PDF côté serveur.");
        }
    } catch (error) {
        console.error("Erreur réseau lors de la sauvegarde du PDF :", error);
    }
}

// --- 4. DÉCLENCHEMENT DE L'OUVERTURE ---
document.getElementById('bouton-ouvrir-risquecv').addEventListener('click', () => {
    
    // Anti-spam : ramener la fenêtre au premier plan si elle est déjà ouverte (ne pas relancer le window.open pour éviter de recharger la page et de casser le Handshake)
    if (popupWindow && !popupWindow.closed) {
        popupWindow.focus();
        return; 
    }

    // Nettoyage complet avant ouverture
    cleanupSession();

    // Ouverture de l'interface RisqueCV dans un nouvel onglet
    popupWindow = window.open(`${CONFIG.targetOrigin}/${CONFIG.partnerSlug}/`, '_blank');
    
    if (!popupWindow) {
        alert("Ouverture bloquée. Veuillez autoriser les pop-ups pour utiliser RisqueCV.");
        return;
    }

    // Détection de la fermeture manuelle par l'utilisateur (croix de la fenêtre)
    pollClosedInterval = setInterval(() => {
        if (popupWindow && popupWindow.closed) {
            console.info("ℹ️ Session RisqueCV terminée (fenêtre fermée par l'utilisateur).");
            cleanupSession();
        }
    }, 1000);

    // Timeout si le site distant est inaccessible. On effectue un "Ping" pro-actif.
    handshakeTimeout = setTimeout(() => {
        console.warn("⏳ Délai d'attente dépassé : RisqueCV ne répond pas. Tentative de Ping...");
        if (popupWindow && !popupWindow.closed) {
            popupWindow.postMessage({ type: 'risquecv:ping' }, CONFIG.targetOrigin);
        }
    }, 3000);

    // --- 5. GESTION DES MESSAGES ---
    messageListener = (event) => {
        // Ignorer tout message ne provenant pas de RisqueCV
        if (event.origin !== CONFIG.targetOrigin) return;
        
        const msg = event.data;

        switch (msg.type) {
          // Si on reçoit "ready", alors on peut envoyer les données du patient
            case 'risquecv:ready':
                clearTimeout(handshakeTimeout);

                // Envoi des données cliniques du patient
                popupWindow.postMessage({
                    type: 'risquecv:prefill',
                    version: CONFIG.version,
                    partner: msg.partner,
                    sessionId: msg.sessionId,
                    payload: { 
                      // Les données doivent être formatées avant l'envoi (ex: "femme" et pas "Femme" ni "F")
                        age: 55, 
                        sexe: "femme", 
                        tabac: false,
                        PAS: 142,
                        CT: 5.2,
                        HDL: 1.3
                        // Ajoutez vos autres variables cliniques ici. Le payload n'a pas besoin d'être exhaustif.
                    }
                }, CONFIG.targetOrigin);
                break;

            // Si on reçoit "ack", alors RisqueCV a bien reçu les données
            case 'risquecv:prefill:ack':
                // Si nécessaire pour debug, on peut vérifier l'injection
                if (msg.status === 'partial') {
                    console.warn('⚠️ Données ignorées par RisqueCV (hors-bornes ou inconnues) :', msg.ignoredKeys);
                }
                break;

            // Si on reçoit "pdf", alors on peut sauvegarder le PDF recu dans le dossier du patient
            case 'risquecv:pdf':                
                // Fermeture propre de la popup
                if (popupWindow) popupWindow.close();
                cleanupSession();

                // Enregistrement du PDF dans le dossier du patient (Base64)
                sauvegarderPdfEnBaseDeDonnees(msg.data, msg.filename);
                break;
                
            // Si le médecin clique sur le bouton "Retour au logiciel"
            case 'risquecv:close':
                console.log("Fermeture demandée par RisqueCV.");
                if (popupWindow) popupWindow.close();
                cleanupSession();
                break;

            // En cas d'erreur métier ou protocolaire
            case 'risquecv:error':
                console.error(`❌ Erreur RisqueCV [${msg.code}]:`, msg.message);
                break;
        }
    };

    window.addEventListener('message', messageListener);
});

📋 Catalogue des messages

Tous les messages partagent une structure de base : type, version (fixée à 1) et partner.

Étape 1 : Le signal de départ

🟢 risquecv:ready (RisqueCV ➡️ Votre Logiciel)

Envoyé dès que RisqueCV est prêt à recevoir des données. Ce message contient le sessionId requis pour la suite.

{
  "type": "risquecv:ready",
  "version": 1, // Il s'agit de la version du protocole d'intégration RisqueCV
  "partner": "votre-slug", // ex : "weda", "doctolib", "medistory", etc.
  "sessionId": "uuid-genere-par-risquecv", // Identifiant unique de la session
  "capabilities": {
    "prefill": true, // Indique que RisqueCV accepte le pré-remplissage
    "pdfReturn": "base64" // Indique que RisqueCV peut renvoyer le PDF en base64
  }
}

🔄 risquecv:ping (Votre Logiciel ➡️ RisqueCV)

Permet de solliciter le renvoi du signal ready.

{
  "type": "risquecv:ping"
}

Étape 2 : L’injection des données du patient

📝 risquecv:prefill (Votre Logiciel ➡️ RisqueCV)

Message de réponse au ready. Permet d’injecter le contexte patient.

{
  "type": "risquecv:prefill",
  "version": 1,
  "partner": "votre-slug",
  "sessionId": "L_ID_RECU_DANS_READY",
  "payload": {
    "age": 55,
    "sexe": "femme",
    "tabac": false,
    "PAS": 142, // pour les valeurs numériques, il faut envoyer des nombres (pas d'unités)
    "atcd": true,
    // ... voir dictionnaire des clés ci-dessus
  }
}

Étape 3 : La confirmation de réception

risquecv:prefill:ack (RisqueCV ➡️ Votre Logiciel)

Envoyé après réception du prefill. Confirme quelles données ont été validées et injectées.

{
  "type": "risquecv:prefill:ack", // acknowledge
  "version": 1,
  "partner": "votre-slug",
  "sessionId": "L_ID_RECU_DANS_READY",
  "status": "ok", // "ok" ou "partial"
  "acceptedKeys": ["age", "sexe", "tabac", "atcd"],
  "ignoredKeys": ["cleInconnue"] 
}

Étape 4 : La récupération du résultat en PDF

📄 risquecv:pdf (RisqueCV ➡️ Votre Logiciel)

Envoyé lorsque le médecin clique sur le bouton de transfert dans RisqueCV. Contient le document final.

{
  "type": "risquecv:pdf",
  "version": 1,
  "partner": "votre-slug",
  "sessionId": "L_ID_RECU_DANS_READY",
  "filename": "RisqueCV_NomPatient.pdf",
  "mimeType": "application/pdf",
  "encoding": "base64",
  "data": "JVBERi..." // Flux binaire converti en string Base64 (environ 50kB)
}

Note technique : La propriété data contient la chaîne Base64 brute du PDF (ex: JVBERi0...). Elle ne contient pas l’en-tête Data URI. Si vous souhaitez générer un lien de téléchargement ou l’afficher, vous devez concaténer la chaîne ainsi en Javascript :

const pdfUrl = "data:application/pdf;base64," + msg.data;

Étape 5 : Signal de fermeture

🏁 risquecv:close (RisqueCV ➡️ Votre Logiciel)

Envoyé lorsque l’utilisateur clique sur le bouton de retour. Indique que l’hôte doit fermer l’interface d’intégration.

{
  "type": "risquecv:close",
  "version": 1,
  "partner": "votre-slug",
  "sessionId": "L_ID_RECU_DANS_READY"
}

Cas particulier : message d’erreur

🛑 risquecv:error (RisqueCV ➡️ Votre Logiciel)

Envoyé en cas de rupture du protocole ou d’erreur critique de session.

{
  "type": "risquecv:error",
  "version": 1,
  "partner": "votre-slug",
  "sessionId": "L_ID_RECU_DANS_READY", // Optionnel selon le type d'erreur
  "code": "INVALID_SESSION",
  "message": "La session d integration ne correspond pas a la page ouverte."
}
Code Signification
INVALID_MESSAGE_FORMAT Le JSON ne respecte pas la structure de base.
UNSUPPORTED_VERSION La version du protocole est différente de celle utilisée par le backend de RisqueCV.
UNSUPPORTED_MESSAGE_TYPE Le type de message n’est pas pris en charge.
INVALID_SESSION Le sessionId est manquant ou incorrect.
PAYLOAD_NOT_A_FLAT_OBJECT Le payload n’est pas un objet JSON plat.
VALID_BUT_EMPTY_PAYLOAD Aucune donnée clinique valide n’a été trouvée dans le payload (objet vide ou toutes les clés sont inconnues).
INVALID_PARTNER Le slug partenaire ne correspond pas à l’URL ouverte.
PDF_GENERATION_FAILED La génération du PDF a échoué.
PREFILL_ALREADY_APPLIED Un prefill a déjà été appliqué pour cette session.

🛠 Débogage de l’intégration

Si vous rencontrez des difficultés (pas de réponse au handshake, données non injectées, etc.), vous pouvez activer le Mode Verbeux de RisqueCV.

Ajoutez simplement le paramètre debug_integration=1 à l’URL :

Ce que le mode debug affiche dans votre console :

  1. Confirmation d’Initialisation :
    • [RisqueCV] Initialisation intégration pour partenaire : votre-slug
    • Valide que votre route d’intégration est correctement reconnue par WordPress.
  2. Erreurs de Sécurité (Rejets silencieux) :
    • [RisqueCV] Origine non autorisée : https://votre-url-test.com (Si votre domaine n’est pas dans notre liste blanche).
    • [RisqueCV] Source de message non attendue. (Si le message ne provient pas de l’objet window ayant ouvert RisqueCV).
  3. Erreurs Protocolaires (Messages corrompus) :
    • Chaque code d’erreur (INVALID_SESSION, UNSUPPORTED_VERSION, etc.) est journalisé avec une explication textuelle détaillée.
    • Facilite le débogage de vos payloads JSON sans avoir à inspecter manuellement chaque event.data.