Aller au contenu
OpesCare
Health ID

Le dossier est le produit : le Health ID d'OpesCare

Jude Nshome explique comment OpesCare fait du dossier médical du patient une infrastructure portable et régie par le consentement, au Cameroun.

Par Jude Nshome Publié le 14 min de lecture Lire en anglais Télécharger le PDF
Le dossier de santé d'un patient au centre, entouré des couches marché, gouvernance, famille et clinique d'OpesCare

Pas une application de transactions de santé, mais une application de relations de santé. Le dossier circule entre le patient, sa famille, la clinique et l'aidant — et chaque passage de relais est consenti, tracé et révocable.

Dans la plupart des systèmes de santé d'Afrique subsaharienne — et, pour être franc, dans la plupart des systèmes de santé du monde —, le dossier médical appartient à l'établissement qui l'a créé. Les résultats d'analyse dorment dans un classeur d'hôpital. L'historique des ordonnances reste dans une seule pharmacie. Quand un patient déménage, part à l'étranger, consulte ailleurs ou perd son carnet, son dossier ne le suit pas. Les réglages par défaut sont à l'envers : l'établissement est durable, le patient est une source de friction.

OpesCare renverse cette logique. C'est une plateforme de santé bilingue (français et anglais) pour le Cameroun, dans laquelle le dossier du patient — identité, antécédents, médicaments, groupe sanguin, allergies, résultats d'analyses, réglages de consentement et historique des accès — est le produit lui-même. Autour de ce dossier s'organise une couche de marché pour trouver des soins dans le monde réel : les stocks de médicaments déclarés par les pharmacies proches, la disponibilité du sang, les cliniciens et l'annuaire national des structures de santé. Et la même application, sur le même téléphone, sert aussi de poste de travail à la clinique : médecin, accueil, pharmacien et technicien de laboratoire ont chacun leur espace, tous travaillant sur le dossier qui appartient au patient.

Le dossier est le produit Le dossier du patient est au centre. Quatre couches travaillent dessus : le marché (recherche de médicaments, de sang et de soins), la gouvernance (registre des consentements, journal des accès, bris de glace), la famille (tuteur, agir pour, invitations) et le poste de travail de la clinique (médecin, accueil, pharmacie et laboratoire). COUCHE MARCHÉ POSTE DE LA CLINIQUE COUCHE FAMILLE COUCHE GOUVERNANCE Patient détient le Health ID Médicaments stocks déclarés Sang groupe · urgence · dons Soins carte · rendez-vous Invitations accepter ou refuser Pharmacie et labo délivrance · résultats Accueil arrivées · sans rendez-vous Médecin dossier · ordonnance Tuteur agit pour ses proches Bris de glace motif · alerte · contrôle Contexte « agir pour » quel dossier est ouvert Consentements demande · accord · retrait Le dossier du patient Health ID · antécédents Journal des accès lu par le patient Refusé sans base, pas de lecture Lecture limitée inscrite au journal des accès réserver accepter urgence base valide sans base Personne ou appareil Service OpesCare Données stockées Contrôle Issue : réussie Issue : refusée Requête Réponse Refus ou échec
  1. Le dossier du patient Identité, antécédents, médicaments, allergies, résultats, réglages de consentement et historique des accès. Tout le reste s'appuie sur ce dossier unique.
  2. Couche marché Trouve les soins dans le monde réel : stocks déclarés par les pharmacies, disponibilité du sang et cliniciens sur une carte.
  3. Couche gouvernance Décide qui peut lire le dossier : demandes et autorisations de consentement, journal des accès visible par le patient et voie d'urgence auditée.
  4. Couche famille Permet à un tuteur d'agir pour un enfant ou une personne à charge dans un contexte « agir pour » explicite ; un adulte ne rejoint qu'en acceptant une invitation.
  5. Poste de la clinique La même application donne au médecin, à l'accueil, au pharmacien et au technicien de laboratoire leurs propres outils sur le même dossier.
Comment ce diagramme est vérifié 21 contrôles sur 21 réussis

L'image, les étapes, le PDF et le JSON sont générés à partir d'une seule spécification. Un test automatisé démontre le graphe et vérifie chaque référence ci-dessous dans l'application en fonctionnement.

  • Chaque carte a un identifiant unique
  • Chaque carte a un type connu
  • Chaque flèche relie deux cartes existantes
  • Un seul point de départ (personne, appareil ou partenaire)
  • Chaque carte est atteignable depuis le départ
  • Chaque carte mène à une issue (aucune impasse)
  • Aucun cycle sauf les boucles de nouvel essai déclarées
  • Chaque étape numérotée suit de vraies flèches
  • Les issues terminent le flux
  • Deux cartes ne partagent jamais une case
  • Chaque carte cite sa preuve
  • Chaque route, classe, méthode et réglage existe
  • Chaque icône vient du jeu Lucide
  • Chaque icône correspond au type de sa carte
  • Chaque libellé existe en anglais et en français
  • Chaque libellé tient dans sa carte
  • Aucune flèche ne traverse une carte
  • Deux flèches sans rapport ne se superposent jamais
  • Aucune étiquette de flèche ne couvre une carte ou une autre étiquette
  • Chaque pointe de flèche est visible
  • Deux cartes reliées de types différents ne partagent jamais une couleur
CartePreuve dans le code
Patient route:portals.patient.access-logs class:App\Modules\PatientIdentity\Services\PatientIdentityService
Médicaments route:public.network.medicine-finder
Sang route:public.network.blood-finder
Soins route:public.care-map
Invitations route:portals.patient.family.invite.send
Pharmacie et labo config:staff_capabilities.capabilities.dispense config:staff_capabilities.capabilities.lab_results
Accueil config:staff_capabilities.capabilities.front_desk
Médecin config:staff_capabilities.capabilities.clinical_chart
Tuteur route:portals.patient.family
Bris de glace method:App\Modules\Governance\Services\EmergencyAccessService::openBreakGlass config:staff_capabilities.capabilities.emergency_access
Contexte « agir pour » method:App\Http\Middleware\ActAsDependent::handle
Consentements class:App\Models\ConsentGrant method:App\Support\ClinicalRelationshipGate::evaluate
Le dossier du patient class:App\Models\Patient class:App\Modules\PatientIdentity\Services\PatientIdentityService
Journal des accès class:App\Models\AccessLog route:portals.patient.access-logs
Refusé method:App\Support\ClinicalRelationshipGate::none
Lecture limitée uri:GET api/mobile/access-logs

Tous les flux en JSON

Cet article en fait le tour, fonction par fonction : ce qu'un patient peut faire dès le premier jour, ce que peut faire le personnel derrière le comptoir, et la mécanique de gouvernance qui rend l'ensemble digne de confiance pour héberger des données médicales.

1. La colonne vertébrale : un Health ID portable

Chaque patient sur OpesCare reçoit le premier Health ID du Cameroun — une attestation vérifiable, présentée comme le document qu'elle est, avec un QR code et un lien de vérification qu'un clinicien peut scanner au moment du soin. Elle se prolonge en Passeport santé : une présentation longue et vivante du dossier (identité et synthèse médicale, médicaments, allergies et alertes, consultations, actes, vaccinations, santé maternelle et infantile), mise en page comme un passeport plutôt que comme un tableau de bord administratif, car c'est le format auquel les populations rurales et à faibles ressources accordent encore spontanément leur confiance : un document que l'on tient en main. Une page sans données reste vide ; rien n'est inventé pour la remplir.

Deux choix de conception comptent plus qu'il n'y paraît.

  1. L'identifiant fonctionne d'un établissement à l'autre. Le patient présente sa carte dans une nouvelle clinique, qui peut la vérifier et demander l'accès. Aucun patient n'est lié à « sa » clinique.
  2. La carte est conçue pour être montrée sans risque. Elle dispose d'un mode présentation ; les écrans qui affichent des données de santé bloquent les captures et l'enregistrement d'écran ; et l'application peut être verrouillée par la biométrie du téléphone, de sorte qu'un appareil laissé à un point de recharge ne s'ouvre pas directement sur le statut VIH ou l'historique de grossesse de quelqu'un.
Vérification du QR Health ID Un vérificateur scanne le QR Health ID du patient et opescare.com répond par l’un de quatre états ; un scan réussi est enregistré. Présenter le QR Health ID Patient Scan, /verify/qr/{token} Vérificateur Vérifier l’état du jeton opescare.com Enregistrer le scan réussi Journal Invalide jeton inconnu Révoqué la carte a été remplacée Expiré présenter un code récent Vérifié authentique et à jour présente valide Personne ou appareil Données stockées Décision Issue : réussie Issue : refusée Requête Réponse Refus ou échec
  1. Présenter le QR Health ID Le patient ouvre sa carte Health ID en mode présentation.
  2. Scan, /verify/qr/{token} N’importe quelle caméra ouvre la page de vérification sur opescare.com.
  3. Vérifier l’état du jeton Le jeton est recherché et contrôlé : expiration et révocation.
  4. Vérifié, expiré, révoqué ou invalide La page affiche exactement l’un des quatre états.
  5. Enregistrer le scan réussi Une vérification réussie est enregistrée comme événement de vérification.
Comment ce diagramme est vérifié 21 contrôles sur 21 réussis

L'image, les étapes, le PDF et le JSON sont générés à partir d'une seule spécification. Un test automatisé démontre le graphe et vérifie chaque référence ci-dessous dans l'application en fonctionnement.

  • Chaque carte a un identifiant unique
  • Chaque carte a un type connu
  • Chaque flèche relie deux cartes existantes
  • Un seul point de départ (personne, appareil ou partenaire)
  • Chaque carte est atteignable depuis le départ
  • Chaque carte mène à une issue (aucune impasse)
  • Aucun cycle sauf les boucles de nouvel essai déclarées
  • Chaque étape numérotée suit de vraies flèches
  • Les issues terminent le flux
  • Deux cartes ne partagent jamais une case
  • Chaque carte cite sa preuve
  • Chaque route, classe, méthode et réglage existe
  • Chaque icône vient du jeu Lucide
  • Chaque icône correspond au type de sa carte
  • Chaque libellé existe en anglais et en français
  • Chaque libellé tient dans sa carte
  • Aucune flèche ne traverse une carte
  • Deux flèches sans rapport ne se superposent jamais
  • Aucune étiquette de flèche ne couvre une carte ou une autre étiquette
  • Chaque pointe de flèche est visible
  • Deux cartes reliées de types différents ne partagent jamais une couleur
CartePreuve dans le code
Présenter le QR Health ID route:portals.patient.health-id-card method:App\Services\Identity\QrTokenService::generateToken
Scan, /verify/qr/{token} route:verify.qr
Vérifier l’état du jeton method:App\Http\Controllers\MedicalId\VerifyController::qr method:App\Services\Identity\QrTokenService::verifyToken method:App\Services\Identity\QrTokenService::failureState
Enregistrer le scan réussi class:App\Models\HealthIdVerificationEvent
Invalide method:App\Services\Identity\QrTokenService::failureState
Révoqué method:App\Services\Identity\QrTokenService::revokeToken
Expiré class:App\Models\HealthIdQrToken
Vérifié route:verify.qr

Tous les flux en JSON

Le sceptique posera la question évidente, et c'est la bonne : au Cameroun, le téléphone est souvent partagé, et le meilleur chiffrement ne vaut rien si la personne qui ramasse l'appareil hérite de tout ce que voyait la session de son propriétaire. OpesCare fait de cette réalité une contrainte de conception, pas un cas marginal. Les jetons sont conservés dans le stockage sécurisé du système ; la déconnexion ou l'expiration de la session efface tout — requêtes en cache, cache hors ligne, file d'attente des envois et PDF exportés — et la protection de la confidentialité s'applique à chaque écran qui affiche des données du patient.

2. La couche de marché : trouver les soins là où ils sont

Un annuaire qui se contente de lister des établissements n'est qu'un bottin. OpesCare traite l'offre de santé comme un inventaire qui existe maintenant, et l'expose à travers trois services.

Recherche de médicaments. Le patient cherche un médicament, voit les stocks déclarés par les pharmacies du réseau, classés par distance, et peut réserver une quantité dans la pharmacie qui l'a réellement. La réservation arrive dans la file de travail de cette pharmacie, où le pharmacien la confirme et la délivre. La disponibilité provient uniquement de relevés de stock en direct dont la source figure sur une liste autorisée : si aucune pharmacie n'a déclaré le médicament, la recherche le dit, au lieu d'afficher des données de remplissage.

Recherche de sang. Le sang est le stock le plus périssable qu'un système de santé ait à gérer. OpesCare affiche la disponibilité par groupe sanguin et par produit sur une carte, prend en charge les demandes urgentes et suit chaque demande jusqu'à son issue. Puis il fait ce qu'un outil d'approvisionnement fait rarement : il invite le patient à devenir donneur, avec un annuaire de donneurs et des contenus de sensibilisation — car augmenter le nombre de donneurs est la seule stratégie qui ait jamais résolu une pénurie de sang à grande échelle.

Recherche de soins. Cliniciens, établissements et annuaire national partagent une même interface cartographique : on trouve un clinicien disponible et proche, on réserve le créneau et on s'y rend. La carte n'est pas un ornement ; elle montre l'offre de soins en réseau d'un pays selon un autre axe que les rendez-vous — la géographie plutôt que l'agenda.

C'est un marché parce que cela ne fonctionne que si chaque côté de la transaction est instrumenté, et pas seulement la barre de recherche. Les annuaires échouent précisément quand le stock, l'urgence et la confiance ne coïncident pas.

3. La couche de gouvernance : le consentement comme protocole à part entière

C'est ici qu'OpesCare cesse de ressembler à une application bien faite pour ressembler à une infrastructure de santé.

Un clinicien qui veut consulter un dossier qui ne lui a pas été ouvert n'obtient pas de contournement : il fait une demande. Le téléphone du patient l'affiche sur une fiche de consentement — qui demande, pourquoi, quelles données et pour combien de temps — et le patient accepte ou refuse. Les autorisations sont conservées dans un registre des consentements. Chaque accès au dossier est inscrit dans un journal des accès consultable par le patient : la personne à qui appartiennent les données voit qui les a ouvertes, et quand. Le consentement peut être révoqué, ce qui fait du « consentement » un mot plutôt qu'une case à cocher. Enfin, la demande de rectification reconnaît que les dossiers contiennent des erreurs : le patient dépose sa demande depuis l'application et elle est examinée par le service des droits des patients d'OpesCare.

Consentement et accès limité Un clinicien demande, le patient approuve dans l’application, l’accès est limité et temporaire, chaque lecture est journalisée et le patient peut révoquer. Clinicien web ou application Recherche du Health ID API OpesCare Base pour lire ? relation ou accord Demande : portée + motif API OpesCare Données limitées renvoyées Clinicien Accès journalisé Dossier clinique Contrôle du fondement API OpesCare Notification au patient Patient Lectures suivantes refusées révoqué ou expiré Accord : portée, expires_at Dossier clinique Approuver (ou refuser) Patient Demande refusée le dossier reste fermé sans base base valide accepter refuser ouvrir admis Personne ou appareil Service OpesCare Données stockées Contrôle Décision Issue : réussie Issue : refusée Requête Réponse En file / asynchrone Refus ou échec
  1. Recherche du Health ID Le clinicien scanne le QR du patient ou saisit son Health ID.
  2. Identité seule, pas de dossier Sans rendez-vous, lien d’équipe de soins ou accord, le dossier reste fermé.
  3. Demande : portée + motif La demande précise ce qui sera lu et pourquoi.
  4. Notification au patient La demande apparaît dans l’application du patient avec une notification.
  5. Approuver (ou refuser) Le patient décide. Un refus met fin au flux.
  6. Accord : portée, expires_at Un accord de consentement est enregistré avec sa portée et sa date d’expiration.
  7. Ouvrir le dossier Le clinicien consulte le dossier.
  8. Contrôle du fondement Le contrôle de relation clinique n’autorise que ce que couvre l’accord.
  9. Accès journalisé Qui a lu quoi, quand et sur quel fondement est inscrit au journal visible par le patient.
  10. Données limitées renvoyées Seule la partie autorisée du dossier est renvoyée.
  11. Révocation ou expiration Le patient peut révoquer à tout moment ; sinon l’accord expire à son échéance.
  12. Demande refusée Si le patient refuse la demande, aucun accord n'est créé et le dossier reste fermé.
Comment ce diagramme est vérifié 21 contrôles sur 21 réussis

L'image, les étapes, le PDF et le JSON sont générés à partir d'une seule spécification. Un test automatisé démontre le graphe et vérifie chaque référence ci-dessous dans l'application en fonctionnement.

  • Chaque carte a un identifiant unique
  • Chaque carte a un type connu
  • Chaque flèche relie deux cartes existantes
  • Un seul point de départ (personne, appareil ou partenaire)
  • Chaque carte est atteignable depuis le départ
  • Chaque carte mène à une issue (aucune impasse)
  • Aucun cycle sauf les boucles de nouvel essai déclarées
  • Chaque étape numérotée suit de vraies flèches
  • Les issues terminent le flux
  • Deux cartes ne partagent jamais une case
  • Chaque carte cite sa preuve
  • Chaque route, classe, méthode et réglage existe
  • Chaque icône vient du jeu Lucide
  • Chaque icône correspond au type de sa carte
  • Chaque libellé existe en anglais et en français
  • Chaque libellé tient dans sa carte
  • Aucune flèche ne traverse une carte
  • Deux flèches sans rapport ne se superposent jamais
  • Aucune étiquette de flèche ne couvre une carte ou une autre étiquette
  • Chaque pointe de flèche est visible
  • Deux cartes reliées de types différents ne partagent jamais une couleur
CartePreuve dans le code
Clinicien config:staff_capabilities.capabilities.identify_patient route:portals.chart.consent_request
Recherche du Health ID uri:POST api/mobile/doctor/patients/scan method:App\Http\Controllers\Api\Mobile\MobileProviderScanController::scan
Base pour lire ? method:App\Support\ClinicalRelationshipGate::evaluate method:App\Support\ClinicalRelationshipGate::holds
Demande : portée + motif uri:POST api/mobile/doctor/consent-requests method:App\Http\Controllers\Api\Mobile\MobileConsentRequestController::store config:staff_capabilities.capabilities.request_access
Données limitées renvoyées uri:GET api/mobile/doctor/patients/{patient} method:App\Http\Controllers\Api\Mobile\MobileDoctorChartController::show
Accès journalisé class:App\Models\AccessLog uri:GET api/mobile/access-logs
Contrôle du fondement method:App\Support\ClinicalRelationshipGate::hasActiveConsentGrant method:App\Support\ClinicalRelationshipGate::coversFullRecord
Notification au patient uri:GET api/mobile/consent-requests uri:GET api/mobile/consent-requests/pending-count
Lectures suivantes refusées uri:POST api/mobile/consents/{id}/revoke method:App\Http\Controllers\Api\Mobile\MobileGovernanceController::revokeConsent
Accord : portée, expires_at class:App\Models\ConsentGrant method:App\Http\Controllers\Api\Mobile\MobileGovernanceController::approveConsent
Approuver (ou refuser) uri:POST api/mobile/consent-requests/{id}/approve uri:POST api/mobile/consent-requests/{id}/deny
Demande refusée method:App\Http\Controllers\Api\Mobile\MobileGovernanceController::denyConsent

Tous les flux en JSON

Il existe aussi une voie d'urgence. L'accès « bris de glace », pour un patient inconscient qui ne peut pas consentir, exige un motif, n'ouvre qu'un profil d'urgence limité, alerte le patient et fait l'objet d'un contrôle a posteriori — car un système de gouvernance sans accès d'urgence est un système qui coûte des vies.

À l'export, le dossier a deux portes : le PDF pour les personnes et FHIR R4 pour les systèmes, de sorte qu'un autre prestataire reçoit un format normalisé plutôt qu'une capture d'écran. Les dossiers peuvent aussi être importés — un lot FHIR ou des documents numérisés — avec une honnêteté rare dans les applications de santé : les données importées sont conservées et étiquetées comme fournies par le patient et non vérifiées. La provenance compte trop pour être maquillée.

Le même esprit traverse tout le produit : la piste d'audit est tournée vers le patient, et non vers un journal serveur que personne ne lit. Dans la plupart des dossiers informatisés, « qui a consulté ce dossier » relève d'une base de conformité. Dans OpesCare, c'est un écran que le patient peut interroger. Quand la gouvernance est lisible par ceux qu'elle gouverne, elle cesse d'être du théâtre.

4. La couche familiale : agir pour ses proches

Une grand-mère qui gère son diabète n'a ni les mêmes compétences numériques, ni le même niveau de lecture, ni le même téléphone que ses petits-enfants. Derrière beaucoup de dossiers se cache une réalité familiale : un aidant qui manipule le téléphone, ou un proche qui arrive en pleine urgence alors que personne ne peut consentir.

OpesCare dispose d'une véritable architecture familiale, pas d'un simple bouton « partager mon dossier ». Un tuteur peut agir pour ses enfants et les personnes à sa charge dans un contexte « agir pour » explicite, et les écrans de la personne à charge indiquent à qui appartient le dossier ouvert, ce qui évite les confusions d'identité qui mettent les patients en danger. Le dossier d'une personne à charge se lit par les mêmes points d'accès que celui du tuteur : un parent qui s'occupe d'un enfant dispose d'un vrai accès au dossier, et non d'un compte lié cosmétique dont on aurait retiré l'essentiel.

Agir pour une personne à charge Un tuteur connecté choisit une personne à charge ; l'application joint un contexte « agir pour » à chaque requête ; le serveur vérifie le lien familial avant de renvoyer le dossier. Les adultes sont invités et peuvent accepter ou refuser ; une invitation en attente ou refusée ne donne aucun droit. AGIR POUR : UN TUTEUR LIT LE DOSSIER D'UN PROCHE INVITATION : UN ADULTE ACCEPTE D'ÊTRE AIDÉ Tuteur connecté à son compte « Agir pour » joint à chaque requête Lien familial vérifié par le serveur Dossier du proche mêmes points d'accès Refusé aucun lien familial Dossier affiché l'écran nomme son titulaire Inviter un adulte depuis l'écran Famille En attente aucun droit pour l'instant Acceptée par la personne invitée Peut aider aux soins lien actif · révocable Refusée aucun droit accordé agir pour lié aucun lien inviter accepter refuser Personne ou appareil Service OpesCare Données stockées Contrôle Décision Issue : réussie Issue : refusée Requête Réponse En file / asynchrone Refus ou échec
  1. Le tuteur se connecte Le tuteur utilise son propre compte ; aucun mot de passe n'est partagé.
  2. Contexte « agir pour » Choisir une personne à charge joint un contexte « agir pour » à chaque requête de l'application.
  3. Vérification du lien familial Le serveur vérifie que le tuteur détient bien un lien familial avec cette personne avant de répondre.
  4. Dossier de la personne à charge Le dossier se lit par les mêmes points d'accès que celui du tuteur, et l'écran indique à qui il appartient.
  5. Inviter un adulte Un adulte ne peut pas être ajouté comme personne à charge ; il est invité.
  6. En attente Tant que la personne invitée n'a pas répondu, l'invitation ne donne aucun accès.
  7. Acceptée Une fois acceptée, le lien est actif et peut encore être retiré plus tard.
  8. Refusée Une invitation refusée ne donne aucun droit.
Comment ce diagramme est vérifié 21 contrôles sur 21 réussis

L'image, les étapes, le PDF et le JSON sont générés à partir d'une seule spécification. Un test automatisé démontre le graphe et vérifie chaque référence ci-dessous dans l'application en fonctionnement.

  • Chaque carte a un identifiant unique
  • Chaque carte a un type connu
  • Chaque flèche relie deux cartes existantes
  • Un seul point de départ (personne, appareil ou partenaire)
  • Chaque carte est atteignable depuis le départ
  • Chaque carte mène à une issue (aucune impasse)
  • Aucun cycle sauf les boucles de nouvel essai déclarées
  • Chaque étape numérotée suit de vraies flèches
  • Les issues terminent le flux
  • Deux cartes ne partagent jamais une case
  • Chaque carte cite sa preuve
  • Chaque route, classe, méthode et réglage existe
  • Chaque icône vient du jeu Lucide
  • Chaque icône correspond au type de sa carte
  • Chaque libellé existe en anglais et en français
  • Chaque libellé tient dans sa carte
  • Aucune flèche ne traverse une carte
  • Deux flèches sans rapport ne se superposent jamais
  • Aucune étiquette de flèche ne couvre une carte ou une autre étiquette
  • Chaque pointe de flèche est visible
  • Deux cartes reliées de types différents ne partagent jamais une couleur
CartePreuve dans le code
Tuteur route:portals.patient.family uri:GET api/mobile/family
« Agir pour » route:portals.patient.family.switch class:App\Http\Middleware\ActAsDependent
Lien familial method:App\Http\Middleware\ActAsDependent::handle class:App\Models\FamilyLink
Dossier du proche uri:GET api/mobile/family/members/{linkId}
Refusé method:App\Http\Middleware\ActAsDependent::handle
Dossier affiché route:portals.patient.family.switch.back
Inviter un adulte uri:POST api/mobile/family/invitations route:portals.patient.family.invite.send
En attente uri:GET api/mobile/family/invitations/incoming route:portals.patient.family.invitations
Acceptée uri:POST api/mobile/family/invitations/{id}/accept method:App\Http\Controllers\Api\Mobile\MobileFamilyController::acceptInvitation
Peut aider aux soins class:App\Models\FamilyLink route:portals.patient.family.revoke
Refusée uri:POST api/mobile/family/invitations/{id}/decline method:App\Http\Controllers\Api\Mobile\MobileFamilyController::declineInvitation

Tous les flux en JSON

La délégation elle-même est encadrée. Un adulte peut être invité à aider à gérer les soins d'une personne, et l'invitation peut être acceptée ou refusée — tant qu'elle n'est pas acceptée, elle ne donne aucun droit. Il n'y a pas de réseau social, et personne n'est ajouté aux soins de quelqu'un sans avoir dit oui.

Pour les équipes produit, c'est la couche à étudier. Beaucoup d'applications de santé sont conçues pour le titulaire du compte, et la grand-mère reste sans solution. OpesCare a été conçu pour le foyer dès le départ.

5. Une application, cinq postes de la clinique

Le choix de produit le moins visible d'OpesCare — et sans doute le plus audacieux — est que la même application sert toute la clinique.

Quand un membre du personnel se connecte, l'application prend une forme différente selon les capacités de son rôle, définies par le serveur. La journée d'un médecin, c'est un agenda, une boîte de demandes de rendez-vous, une liste de patients et un dossier découpé en sections. L'accueil dispose de l'agenda de l'établissement : enregistrement des arrivées, inscription des patients sans rendez-vous et orientation vers un clinicien. Le pharmacien reçoit les ordonnances, délivre, gère les réservations et ajuste les stocks avec une piste d'audit. Le technicien de laboratoire enregistre les prélèvements, saisit et valide les résultats — et la validation d'un résultat prévient à la fois le patient et le clinicien prescripteur.

Une application, cinq postes Patient, médecin, accueil, pharmacien et technicien de laboratoire ont chacun leur espace dans la même application. Chaque requête passe le contrôle des capacités du rôle et de la relation de soins avant d'atteindre l'unique dossier du patient. Une seule app OpesCare connexion ; rôle du compte Patient Health ID · consentement Médecin dossier · ordonnances Accueil arrivées · orientation Pharmacien délivrance · stock Laboratoire prélèvements · résultats Contrôle des droits rôle · lien de soins ou accord Refusé sans capacité ni base Un seul dossier patient le même dossier pour les cinq Lecture journalisée inscrite au journal des accès sans base autorisé Personne ou appareil Données stockées Contrôle Issue : réussie Issue : refusée Requête Réponse Refus ou échec
  1. Patient Détient le Health ID, répond aux demandes de consentement et consulte le journal des accès.
  2. Médecin Agenda, demandes de rendez-vous, liste de patients, dossier par sections, prescription, demandes d'analyses, suivis et boîte de résultats.
  3. Accueil L'agenda de l'établissement : enregistrement des arrivées, inscription sans rendez-vous et orientation vers un clinicien.
  4. Pharmacien Réception des ordonnances, délivrance, réservations et ajustements de stock avec piste d'audit.
  5. Technicien de laboratoire Prélèvements, saisie et validation des résultats ; la validation prévient le patient et le clinicien prescripteur.
  6. Capacités et relation de soins Le serveur décide de ce que chaque rôle peut faire et vérifie une relation de soins ou un consentement avant toute lecture d'un dossier par un clinicien.
  7. Un seul dossier Les cinq travaillent sur le même dossier : rien n'a besoin de faire le tour de la clinique.
Comment ce diagramme est vérifié 21 contrôles sur 21 réussis

L'image, les étapes, le PDF et le JSON sont générés à partir d'une seule spécification. Un test automatisé démontre le graphe et vérifie chaque référence ci-dessous dans l'application en fonctionnement.

  • Chaque carte a un identifiant unique
  • Chaque carte a un type connu
  • Chaque flèche relie deux cartes existantes
  • Un seul point de départ (personne, appareil ou partenaire)
  • Chaque carte est atteignable depuis le départ
  • Chaque carte mène à une issue (aucune impasse)
  • Aucun cycle sauf les boucles de nouvel essai déclarées
  • Chaque étape numérotée suit de vraies flèches
  • Les issues terminent le flux
  • Deux cartes ne partagent jamais une case
  • Chaque carte cite sa preuve
  • Chaque route, classe, méthode et réglage existe
  • Chaque icône vient du jeu Lucide
  • Chaque icône correspond au type de sa carte
  • Chaque libellé existe en anglais et en français
  • Chaque libellé tient dans sa carte
  • Aucune flèche ne traverse une carte
  • Deux flèches sans rapport ne se superposent jamais
  • Aucune étiquette de flèche ne couvre une carte ou une autre étiquette
  • Chaque pointe de flèche est visible
  • Deux cartes reliées de types différents ne partagent jamais une couleur
CartePreuve dans le code
Une seule app OpesCare route:login.submit config:staff_capabilities.capabilities
Patient route:portals.patient.access-logs
Médecin config:staff_capabilities.capabilities.clinical_chart config:staff_capabilities.capabilities.prescribe
Accueil config:staff_capabilities.capabilities.front_desk
Pharmacien config:staff_capabilities.capabilities.dispense
Laboratoire config:staff_capabilities.capabilities.lab_results route:portals.lab.release
Contrôle des droits config:staff_capabilities.capabilities method:App\Support\ClinicalRelationshipGate::evaluate
Refusé method:App\Support\ClinicalRelationshipGate::none
Un seul dossier patient class:App\Models\Patient class:App\Models\AccessLog
Lecture journalisée uri:GET api/mobile/access-logs

Tous les flux en JSON

Pourquoi est-ce audacieux ? Parce que le dossier est un objet unique, partagé par ces cinq personnes. Quand la même application fonctionne à l'accueil, chez le médecin, à la pharmacie et au laboratoire, le dossier n'a pas à faire le tour de la clinique : il y est déjà. Les passages de relais qui se perdent sur papier (un bon qui ne suit pas le prélèvement, une ordonnance qui ne suit pas la consultation) deviennent la norme.

À ces rôles s'ajoutent les capacités cliniques qu'exige le dossier : prescription, demandes d'analyses, demandes de suivi, boîte de résultats, scan du QR code du Health ID au moment du soin, et la voie « bris de glace » décrite plus haut. L'application du clinicien est un véritable outil de rédaction du dossier — pas un tableau de facturation plaqué dessus.

6. Sous le capot (pour les ingénieurs)

Pour un public technique, l'architecture est propre et les choix d'ingénierie sont prudents là où il le faut.

  • Expo SDK 57, React Native 0.86, React 19 et TypeScript strict : une seule base de code TypeScript pour l'application Android, avec un profil de compilation iOS préparé et une version web.
  • Routage d'abord : un routage par fichiers sur plus de quatre-vingt-dix écrans, avec un audit de navigation dans le dépôt qui signale tout écran vers lequel rien ne mène.
  • État serveur et état client séparés : TanStack Query et Zustand, avec un seul client HTTP et un seul endroit où les jetons sont joints et renouvelés.
  • Un modèle de session explicite : un seul emplacement de jeton par appareil, avec un marqueur de type de session, pour qu'une session de clinicien et une session de patient ne puissent pas se contaminer.
  • Hors ligne, avec un circuit de règlement : un cache local chiffré, activé sur demande et délimité par une politique par appareil émise et révocable par le serveur, et une file d'envoi qui capte les écritures échouées faute de réseau et les règle dans une file chiffrée côté serveur — dédoublonnée, auditée et ouverte comme tâche de rapprochement. Les requêtes d'authentification ne sont jamais écrites sur l'appareil.
  • Sécurité du transport : sur Android, une configuration de sécurité réseau épingle TLS sur les clés des autorités de certification racines plutôt que sur le certificat du site, pour que les renouvellements de routine ne cassent pas les applications installées ; aucun trafic en clair hors d'un profil de développement local, sauvegardes de l'application désactivées, et une liste d'autorisations courte qui bloque explicitement le stockage, le micro et la superposition d'écran dont l'application n'a pas besoin.
  • Contrôle qualité : TypeScript, ESLint et une suite Jest ciblant les chemins critiques pour la sécurité — effacement de session, stockage des jetons, renouvellement d'un jeton expiré une seule fois, verrouillage de l'application, ouverture sûre des liens externes et stockage hors ligne —, le tout exécuté en intégration continue à chaque envoi et à chaque demande de fusion.
  • L'internationalisation est systémique, pas cosmétique : français et anglais à parité dans toute l'application, et montants en XAF (FCFA).
  • Des paiements pensés pour le marché : le règlement d'une facture par MTN Mobile Money ou Orange Money en XAF est intégré — et la règle du produit est inscrite dans le code et ses tests : les soins ne sont jamais conditionnés au paiement.
L'accès hors ligne et la file d'envoi Le serveur émet une politique révocable par appareil qui délimite un cache local chiffré. Les écritures échouées faute de réseau vont dans une file d'envoi, puis sont réglées dans une file chiffrée côté serveur, dédoublonnée, qui ouvre une tâche de rapprochement et est auditée. La déconnexion efface le cache, la file et la politique. SUR LE TÉLÉPHONE SUR LE SERVEUR OPESCARE Le patient accepte sur ce téléphone Politique hors ligne par appareil · délimitée · révocable Déconnexion ou retrait efface cache, file, politique Une modification hors ligne la requête reste sans réponse Cache chiffré seulement ce qui est autorisé File d'envoi connexions jamais conservées Retour du réseau la file est réglée File chiffrée côté serveur chiffrée · dédoublonnée Rapprochement une tâche par modification Modification appliquée rapprochée et auditée Piste d'audit chaque étape enregistrée périmètre révoquer en ligne toujours hors ligne Personne ou appareil Service OpesCare Données stockées Contrôle Issue : réussie Issue : refusée Requête Réponse En file / asynchrone Refus ou échec
  1. Politique hors ligne Le patient l'active. Le serveur émet pour cet appareil une politique qui précise les parties du dossier pouvant être conservées, et peut la révoquer.
  2. Cache chiffré Seuls les périmètres autorisés par la politique sont stockés sur le téléphone, chiffrés.
  3. Une modification hors ligne Une modification faite sans réseau n'atteint pas le serveur.
  4. File d'envoi L'écriture échouée est conservée dans une file d'envoi. Les requêtes de connexion ne sont jamais écrites sur l'appareil.
  5. Retour du réseau À la reconnexion, la file d'envoi est transmise au serveur.
  6. File chiffrée côté serveur Chaque modification est stockée chiffrée et dédoublonnée : l'envoyer deux fois ne l'applique pas deux fois.
  7. Tâche de rapprochement Chaque modification mise en file ouvre une tâche de rapprochement sur le serveur.
  8. Piste d'audit La création de la politique, chaque modification mise en file et la révocation sont inscrites dans la piste d'audit.
  9. Déconnexion ou retrait La déconnexion, ou la révocation de la politique, efface du téléphone le cache, la file d'envoi et la politique enregistrée.
Comment ce diagramme est vérifié 21 contrôles sur 21 réussis

L'image, les étapes, le PDF et le JSON sont générés à partir d'une seule spécification. Un test automatisé démontre le graphe et vérifie chaque référence ci-dessous dans l'application en fonctionnement.

  • Chaque carte a un identifiant unique
  • Chaque carte a un type connu
  • Chaque flèche relie deux cartes existantes
  • Un seul point de départ (personne, appareil ou partenaire)
  • Chaque carte est atteignable depuis le départ
  • Chaque carte mène à une issue (aucune impasse)
  • Aucun cycle sauf les boucles de nouvel essai déclarées
  • Chaque étape numérotée suit de vraies flèches
  • Les issues terminent le flux
  • Deux cartes ne partagent jamais une case
  • Chaque carte cite sa preuve
  • Chaque route, classe, méthode et réglage existe
  • Chaque icône vient du jeu Lucide
  • Chaque icône correspond au type de sa carte
  • Chaque libellé existe en anglais et en français
  • Chaque libellé tient dans sa carte
  • Aucune flèche ne traverse une carte
  • Deux flèches sans rapport ne se superposent jamais
  • Aucune étiquette de flèche ne couvre une carte ou une autre étiquette
  • Chaque pointe de flèche est visible
  • Deux cartes reliées de types différents ne partagent jamais une couleur
CartePreuve dans le code
Le patient accepte uri:POST api/mobile/offline/policies
Politique hors ligne method:App\Modules\Offline\Services\SyncService::createLocalCachePolicy class:App\Models\LocalCachePolicy
Déconnexion ou retrait uri:POST api/mobile/offline/policies/{policy}/revoke method:App\Modules\Offline\Services\SyncService::revokeLocalCachePolicy
Une modification hors ligne class:App\Models\OfflineQueue
Cache chiffré class:App\Models\LocalCachePolicy
File d'envoi class:App\Models\OfflineQueue
Retour du réseau uri:POST api/mobile/offline/policies/{policy}/queue
File chiffrée côté serveur method:App\Modules\Offline\Services\SyncService::queueEncryptedPayload class:App\Models\OfflineQueue
Rapprochement class:App\Models\ReconciliationCase method:App\Modules\Offline\Services\SyncService::detectConflict
Modification appliquée method:App\Modules\Offline\Services\SyncService::resolveConflict
Piste d'audit class:App\Models\AuditEvent

Tous les flux en JSON

7. Les limites, en toute honnêteté

Une publication sérieuse ne prétend pas qu'un jeune produit est achevé. Voici ce que demandera un relecteur technique, et où en sont les choses.

  • Le paiement mobile n'est pas encore disponible. Les parcours MTN Mobile Money et Orange Money sont construits, mais les vrais paiements exigent d'abord le raccordement des comptes marchands d'OpesCare. D'ici là, l'application indique que le paiement est indisponible — et aucun rendez-vous, dossier ou consultation n'en dépend.
  • Les notifications push n'atteignent pas encore la version publiée. Le dispositif existe de bout en bout, et l'application dit honnêtement ce qu'une version donnée peut ou ne peut pas faire plutôt que de promettre des alertes qui n'arrivent pas, mais les identifiants push doivent être livrés avec une version avant que rappels et alertes de résultats ne parviennent aux utilisateurs.
  • L'épinglage TLS ne concerne qu'Android. La version iOS est par ailleurs préparée ; sur iPhone, les connexions reposent sur la validation standard des certificats, et la publication sur l'App Store reste à venir.
  • La version web est la petite sœur, par choix. Les navigateurs n'ont pas de coffre sécurisé du système, si bien que la version web refuse le cache hors ligne et garde les jetons en mémoire, adossés uniquement à un stockage limité à l'onglet.

Une limite citée dans les premières versions de ce texte ne s'applique plus : depuis le 19 octobre 2026, l'application dialogue avec le serveur de production d'opescare.com. Une version de production doit nommer explicitement son API, et la compilation refuse d'être publiée par erreur vers un serveur de démonstration.

Nous préférons que ces limites soient visibles et corrigées en vol plutôt que passées sous silence.

8. Pourquoi cela compte au-delà du Cameroun

Il y a un schéma qui mérite d'être nommé. La technologie de santé conçue dans les pays à hauts revenus optimise en général la transaction : prendre rendez-vous, payer une facture, écrire à un médecin. Ce qu'elle manque, c'est la relation en dessous : à qui sont les données, qui peut les voir, qui agit pour vous quand vous ne le pouvez pas, et ce qui se passe quand le réseau tombe au moment précis où vous avez besoin de soins.

OpesCare construit d'abord ces fondations — propriété, consentement, délégation, accès hors ligne, identité — puis y accroche les transactions. Cet ordre traduit un pari précis : sur les marchés de santé émergents, l'infrastructure de confiance est la ressource rare, et les parcours de réservation sont des commodités que chacun peut acheter ou refaire.

Le Cameroun est le terrain de la preuve, mais le modèle ne lui est pas propre. Quelle que soit l'étiquette choisie — infrastructure de santé numérique, identité médicale portable, dossier de santé fondé sur le consentement, réseau d'identifiants de santé détenus par les patients, inédit en son genre —, l'idée de fond est simple :

Le dossier appartient au patient. Tout le reste découle du protocole.


OpesCare est développé par OPES Health Systems pour les soins au Cameroun. Il est disponible en français et en anglais, pour les patients comme pour le personnel, sur Android et sur le web dès aujourd'hui, iOS étant prévu. Pour aller plus loin : le consentement expliqué aux patients, le Health ID, FHIR et l'index maître des patients, ou la documentation développeurs.

Article compagnon : La plateforme derrière l'application — comment la pharmacie, le laboratoire, la banque de sang et l'accueil travaillent sur le même dossier.

Questions fréquentes

Que signifie « le dossier est le produit » ?

OpesCare est construit autour du dossier longitudinal du patient plutôt qu'autour d'une transaction isolée comme une réservation ou un paiement. La recherche de soins, le consentement, l'accès familial et les outils de la clinique reposent tous sur ce dossier unique, que le patient emporte avec lui.

Le Health ID d'OpesCare est-il la carte nationale d'identité ?

Non. C'est un identifiant de santé délivré par OpesCare. Il s'agit d'un réseau d'identifiants de santé détenus par les patients, inédit au Cameroun, mais ce n'est pas une pièce d'identité officielle et il ne revendique aucune approbation de l'État.

Une clinique peut-elle lire mon dossier simplement parce qu'elle a scanné mon Health ID ?

Non. Le scan vérifie votre identité. Pour lire votre dossier, un clinicien doit avoir une relation de soins avec vous — un rendez-vous, une place dans votre équipe soignante ou un épisode ouvert dans sa structure — ou une autorisation que vous avez approuvée. Chaque lecture est inscrite dans un journal que vous pouvez consulter.

Que se passe-t-il en urgence si je ne peux pas consentir ?

Un clinicien peut recourir à l'accès « bris de glace ». Il doit indiquer un motif ; seul un profil d'urgence limité s'ouvre ; vous êtes alerté et l'accès est contrôlé ensuite.

Puis-je gérer le dossier de mon enfant ou de mon parent ?

Oui. Un tuteur peut agir pour un enfant ou une personne à charge dans un contexte « agir pour » explicite. Un adulte n'est jamais ajouté à son insu : il reçoit une invitation qu'il peut accepter ou refuser.

OpesCare fonctionne-t-il sans connexion ?

En partie, et seulement si vous l'activez. L'accès hors ligne conserve une copie chiffrée des parties de votre dossier qu'autorise une politique émise et révocable par le serveur. Les modifications faites hors ligne sont mises en attente et réglées avec le serveur à la reconnexion.

Dois-je payer pour être soigné via OpesCare ?

Non. Les soins ne sont jamais conditionnés au paiement. Le règlement d'une facture par MTN Mobile Money ou Orange Money est intégré à l'application, mais reste indisponible tant que les comptes marchands ne sont pas raccordés.

OpesCare est-il disponible sur iPhone ?

Android passe en premier. Une version iOS est préparée et la version web fonctionne dans n'importe quel navigateur, mais la publication sur l'App Store reste à venir.

Sources

  1. Flux de consentement — documentation OpesCare — OpesCare (consulté le 19 octobre 2026)
  2. Vérification par QR — documentation OpesCare — OpesCare (consulté le 19 octobre 2026)
  3. Ingestion FHIR R4 — documentation OpesCare — OpesCare (consulté le 19 octobre 2026)
  4. Architecture de la plateforme — documentation OpesCare — OpesCare (consulté le 19 octobre 2026)
  5. HL7 FHIR Release 4 — HL7 International (consulté le 19 octobre 2026)
  6. Loi n° 2010/012 du 21 décembre 2010 relative à la cybersécurité et à la cybercriminalité au Cameroun — Digital Watch Observatory (consulté le 19 octobre 2026)
  7. Configuration de la sécurité réseau (épinglage de certificats) — Android Developers (consulté le 19 octobre 2026)

Partager cet article

Trouver des soins avec OpesCare

Gratuit, en français et en anglais, partout au Cameroun.

Aucun commentaire

Soyez le premier à commenter. Les commentaires sont relus avant publication.

Laisser un commentaire

Tous les commentaires sont modérés.

Jamais affiché publiquement. Utilisé uniquement si nous devons vous contacter au sujet de votre commentaire.

Jusqu'à 2000 caractères. Les liens s'affichent en texte simple. Ne partagez pas d'informations de santé personnelles.

Cet article est une information générale, pas un avis médical. En cas d'urgence, rendez-vous à l'hôpital le plus proche.

Tous les articles