Aller au contenu
OpesCare
Produit

La plateforme derrière l'application : chaque guichet d'OpesCare

Jude Nshome présente la plateforme web d'OpesCare : un index patient unique, l'ingestion FHIR et des guichets pharmacie, labo et sang sur un même dossier.

Par Jude Nshome Publié le 13 min de lecture Lire en anglais Télécharger le PDF
La plateforme web d'OpesCare : un index patient unique et un même dossier partagé par la pharmacie, le laboratoire, la banque de sang et l'accueil

La plateforme web n'est pas un panneau d'administration greffé sur une application. C'est l'autre face du même dossier : un index patient unique, une seule porte d'entrée pour les données des partenaires, et le travail quotidien des pharmacies, des laboratoires et des banques de sang, repensé pour partager un dossier plutôt que le recopier.

L'application destinée aux patients, décrite dans Le dossier est le produit, est la moitié visible d'OpesCare. L'autre moitié est la plateforme web d'opescare.com, au service des établissements : la pharmacie indépendante, le centre de santé de district, le laboratoire d'analyses, le service d'imagerie, la banque de sang — et l'hôpital qui réunit plusieurs d'entre eux.

Cet article en fait la visite : l'index maître des patients, qui établit une fois pour toutes qui est le patient ; la couche d'interopérabilité, qui permet aux systèmes partenaires d'envoyer leurs données ; et les circuits de guichet — enregistrement, triage, file d'attente, prescription, délivrance, du prélèvement à la publication, demandes de sang — construits autour du dossier que le patient porte sur son téléphone. Il dit aussi clairement ce que la plateforme n'est pas. OpesCare est un produit de découverte, d'identité et de coordination. Ce n'est pas un système d'information hospitalier, et il ne prétend pas l'être.

Architecture de la plateforme OpesCare Les clients se connectent à opescare.com. Les pages web, l’API REST et le point FHIR R4 passent les contrôles d’authentification, de consentement et d’ingestion avant d’atteindre les services Health ID, dossiers cliniques, recherches, documents, paiements et webhooks, qui stockent dans PostgreSQL, utilisent des workers de file d’attente et écrivent un journal d’accès. OPESCARE.COM Clients site, app, partenaires, Bridge Pages web rendues côté serveur API REST /api/v1/connect, /api/mobile Ingestion FHIR R4 /api/fhir/R4 Authentification session, JWT, portées Contrôle consentement relation ou accord Garde d’ingestion établ., Health ID, accord Refusé 401 ou 403, rien lu Services OpesCare Health ID, dossiers, recherche PostgreSQL dossiers, registre, journal Journal d’accès qui a lu quoi, quand Réponse chaque lecture journalisée connecté base valide 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. Un client appelle opescare.com Le site, l'application, les systèmes partenaires et le Bridge Agent passent par l'un des trois points d'entrée : routes web, API REST ou point FHIR R4.
  2. Authentification Les routes web utilisent une session ; l'API vérifie un JWT signé et ses périmètres.
  3. Contrôle du consentement La lecture d'un clinicien passe le contrôle de la relation de soins avant toute réponse d'un service.
  4. Garde d'ingestion FHIR Les écritures des partenaires passent trois contrôles : établissement issu du jeton, Health ID existant, accord actif.
  5. Stocké et journalisé Les services lisent et écrivent dans PostgreSQL, et chaque lecture d'un dossier est inscrite au journal des accès.
  6. Refusé Un contrôle échoué répond 401 ou 403 et rien n'est lu ni écrit.
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
Clients route:docs.index route:docs.widget route:docs.bridge
Pages web route:login route:public.network.medicine-finder
API REST uri:POST api/v1/connect/auth/token uri:GET api/mobile/consents
Ingestion FHIR R4 uri:POST api/fhir/R4 uri:GET api/fhir/R4/metadata
Authentification route:login.submit method:App\Http\Controllers\Api\V1\Connect\AuthController::introspect
Contrôle consentement method:App\Support\ClinicalRelationshipGate::evaluate config:staff_capabilities.capabilities.clinical_chart
Garde d’ingestion method:App\Services\Fhir\FhirIngestGuard::requireConsent
Refusé route:docs.errors
Services OpesCare class:App\Modules\PatientIdentity\Services\PatientIdentityService class:App\Services\WebhookService route:public.care-map
PostgreSQL config:database.connections.pgsql
Journal d’accès class:App\Models\AccessLog uri:GET api/mobile/access-logs
Réponse route:docs.api

Tous les flux en JSON

1. Ce qu'est la plateforme

Une seule application Laravel sur PostgreSQL sert le site public, les consoles des établissements et une surface /api commune à l'application mobile et aux intégrations partenaires. Chaque établissement est accueilli, accompagné par un administrateur de la plateforme à travers une liste de mise en service et un score de préparation, puis participe à l'index patient partagé tout en faisant tourner ses propres guichets.

Un établissement, de la fiche aux guichets en service Deux chemins distincts partent du responsable de l'établissement. La revendication de la fiche de l'annuaire est examinée par un administrateur et, une fois approuvée, la fiche est rattachée à l'établissement. L'intégration est un chemin à part : les points de la liste sont cochés, la préparation est notée, et un administrateur approuve la mise en service ou renvoie l'établissement à la liste. Après la mise en service, l'équipe rejoint l'établissement et les guichets ouvrent. Responsable de l'établissement Fiche revendiquée dans la carte des soins Revendication examinée par un administrateur Fiche vérifiée rattachée à l'établissement Liste d'intégration points cochés Préparation notée contrôle de mise en service Revendication rejetée fiche inchangée Décision de mise en service par un administrateur L'équipe rejoint invitations · demandes Guichets en service pharmacie · labo · file revendiquer accepter rejeter intégrer en service pas prêt Personne ou appareil Service OpesCare Contrôle Décision Issue : réussie Issue : refusée Requête Réponse Refus ou échec
  1. Fiche revendiquée Le responsable revendique la fiche de l'établissement dans la carte des soins ; un administrateur examine la revendication.
  2. Fiche vérifiée Une revendication approuvée permet de rattacher la fiche à l'établissement. L'approbation ne lance pas l'intégration.
  3. Début de l'intégration L'intégration est un chemin distinct, mené au moyen d'une liste.
  4. Préparation notée La préparation de l'établissement à la mise en service est notée.
  5. Décision de mise en service Un administrateur approuve la mise en service.
  6. Équipe et guichets Le personnel rejoint par invitation ou demande approuvée, et les guichets pharmacie, laboratoire et file d'attente ouvrent.
  7. Pas encore prêt Un établissement qui n'est pas prêt retourne à la liste.
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
Responsable route:public.care-map
Fiche revendiquée route:public.care-map.claim route:public.care-map.claim.store class:App\Http\Controllers\CareMap\FacilityClaimController
Revendication examinée route:admin.care-map.review route:admin.care-map.review.claims.approve
Fiche vérifiée route:admin.care-map.review.listings.link
Liste d'intégration route:portals.admin.onboarding.show route:portals.admin.onboarding.mark method:App\Http\Controllers\MedicalId\OnboardingPortalController::markItem
Préparation notée route:portals.admin.facilities.readiness route:portals.admin.facilities.readiness.score class:App\Http\Controllers\MedicalId\FacilityGoLiveReadinessController
Revendication rejetée route:admin.care-map.review.claims.reject
Décision de mise en service route:portals.admin.onboarding.approve method:App\Http\Controllers\MedicalId\OnboardingPortalController::approve
L'équipe rejoint route:portals.facility.team.join.approve route:professional.join.store
Guichets en service route:portals.pharmacy.stock route:portals.lab.index route:portals.queue.index

Tous les flux en JSON

Qui Ce qu'il utilise sur le web aujourd'hui
Direction de l'établissement Invitations et rôles de l'équipe, réglages de l'établissement, registre des services et des lits pour compter l'occupation, factures émises
Accueil Guichet de triage avec réévaluation ; la file du jour — arrivée, appel, début, fin, absence
Clinicien Prescription avec contrôle des interactions, demandes d'analyses, orientations, vaccinations, dossier consulté dans les limites du consentement
Pharmacie Ordonnances et délivrance, commandes de médicaments des patients, stock, lots, réceptions, ajustements, notes de réapprovisionnement, prix, import de stock, registre des médicaments contrôlés, rapports
Laboratoire Demandes d'analyses, prélèvement, résultats, validation, publication, tableau de bord du responsable avec rappels des valeurs critiques
Imagerie Demandes d'imagerie planifiées, réalisées et rapportées, et un moteur public de recherche d'examens
Banque de sang Inventaire par produit sanguin et par groupe, et guichet des demandes de sang
Administration de la plateforme Guichet de l'index maître des patients, accueil et préparation des établissements, identifiants partenaires, certifications d'intégration, rapportage agrégé DHIS2, registre des violations, documents juridiques
Développeurs Applications et identifiants, abonnements webhooks, historique des livraisons et rejeu, documentation

Rien de tout cela n'est une maquette. Chaque élément a une route enregistrée, un contrôleur, une page et un lien dans la navigation du rôle qui l'utilise. Et surtout, ce ne sont pas des produits séparés : un patient, un modèle de consentement, une piste d'audit.

2. L'index maître des patients : qui est cette personne

Un réseau national échoue en silence si la même personne y existe deux fois. L'index maître des patients (IMP) est donc un processus encadré, pas une barre de recherche.

  • Des identifiants exacts au guichet. À l'accueil, l'enregistrement et la prise de rendez-vous se font avec le Health ID exact. Un guichet ne peut pas parcourir la population en tapant un bout de nom ; si un enregistrement ressemble à une identité existante, il est refusé plutôt que dédoublé. Tous les chemins de création de patient passent par le même contrôle de doublon.
  • La détection est planifiée. Un balayage nocturne examine les inscriptions récentes, un balayage hebdomadaire regarde plus large. Tous deux signalent des paires candidates ; aucun ne fusionne quoi que ce soit.
  • Une personne tranche. Au guichet de l'IMP, un administrateur examine chaque paire, éléments à l'appui, puis fusionne ou rejette. Le personnel peut aussi signaler une paire à la main.
  • Les fusions sont réversibles. Une fusion note quel dossier est conservé et garde l'autre identifiant comme alias, si bien qu'un ancien Health ID ou un ancien QR code renvoie toujours à la bonne personne. Une fusion peut être annulée, la plus récente d'abord, depuis le même guichet.
  • La carte correspond à une seule ligne. Les jetons QR ont une courte durée de vie et le Health ID se résout par la table des alias : la carte que tient le patient désigne exactement une entrée de l'index.
Détection des doublons et fusion réversible Des analyses planifiées proposent des Health ID probablement en double, une personne examine chaque paire, et une fusion conserve un survivant, transforme l’autre en alias et peut être annulée. Planificateur chaque nuit et semaine Noter les paires candidates Analyse doublons Paires mises en revue Bureau de revue Comparer côte à côte Bureau de revue Un seul Health ID l'ancien ID devient un alias Les recherches suivent Registre patients Fusion : survivant + alias Bureau de revue Ou rejeter la paire Bureau de revue Dossiers séparés fusion annulée Annuler si besoin Bureau de revue planifié même personne annuler Personne ou appareil Service OpesCare Données stockées Décision Issue : réussie Issue : refusée Requête Réponse En file / asynchrone Refus ou échec
  1. Lancer l’analyse Les analyses tournent chaque nuit et chaque semaine selon le planning.
  2. Noter les paires candidates Les dossiers sont comparés par blocs pour rester rapides sur un registre national.
  3. Paires mises en revue Les doublons probables deviennent des candidats. Rien n’est fusionné automatiquement.
  4. Comparer côte à côte Un administrateur examine les deux dossiers. Une paire peut aussi être signalée à la main.
  5. Fusion : survivant + alias Un Health ID survit ; l’autre devient un alias qui reste résolu.
  6. Les recherches suivent Recherches, scans et liens vers l’ancien ID aboutissent au survivant.
  7. Ou rejeter la paire Une paire rejetée est écartée et les deux dossiers restent inchangés.
  8. Annuler si besoin Les fusions sont réversibles, dernière entrée première sortie, depuis l’onglet Fusionnés.
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
Planificateur command:mpi:detect class:App\Console\Commands\DetectDuplicatePatients
Noter les paires candidates method:App\Modules\MasterPatientIndex\Services\MasterPatientIndexService::detectDuplicates method:App\Modules\MasterPatientIndex\Services\MasterPatientIndexService::scoreMatch
Paires mises en revue class:App\Models\MpiCandidate route:portals.admin.mpi.index route:portals.admin.mpi.candidates.raise
Comparer côte à côte route:portals.admin.mpi.candidates.show
Un seul Health ID class:App\Models\PatientMergeAlias
Les recherches suivent method:App\Models\Patient::findExistingIdentity class:App\Models\PatientMerge
Fusion : survivant + alias route:portals.admin.mpi.candidates.merge method:App\Modules\MasterPatientIndex\Services\PatientMergeService::merge
Ou rejeter la paire route:portals.admin.mpi.candidates.reject method:App\Modules\MasterPatientIndex\Services\MasterPatientIndexService::rejectMatch
Dossiers séparés method:App\Modules\MasterPatientIndex\Services\PatientMergeService::unmerge
Annuler si besoin route:portals.admin.mpi.merges.unmerge

Tous les flux en JSON

C'est là que repose l'argument « une personne, plusieurs établissements ». Les questions auxquelles un index national doit répondre — qui est-ce ? et, un an plus tard, figure-t-il deux fois ? — trouvent leur réponse dans un processus avec revue humaine et piste d'audit, et non dans la manière dont quelqu'un a tapé un nom.

3. La couche d'interopérabilité

OpesCare traite l'interopérabilité comme une discipline qui commence par ce qui entre.

FHIR en entrée, et l'export du patient en sortie

  • L'ingestion des partenaires. Les partenaires agréés envoient des ressources FHIR R4 — DiagnosticReport, Observation, Immunization et bundles de transaction — à un point d'entrée restreint doté d'une déclaration de capacités publiée. Chaque partenaire détient des identifiants porteurs limités aux périmètres accordés par un administrateur. Une garde vérifie que le partenaire a le droit d'écrire au sujet de ce patient et que la ressource peut être placée ; sinon, l'ingestion refuse ouvertement au lieu de ranger la donnée au mauvais endroit.
  • L'export du patient. Depuis l'application mobile, le patient peut exporter son propre dossier en bundle FHIR, et en importer un.
  • Ce qui est absent. Il n'existe pas de serveur FHIR sortant interrogeable par des tiers, ni d'interface HL7 v2. C'est un choix : le dossier quitte OpesCare quand le patient l'emporte, pas quand un système le demande.
Ingestion FHIR R4 Un partenaire envoie un Bundle transaction avec un jeton porteur ; trois contrôles vérifient l’établissement, le Health ID et le consentement ; le Bundle est enregistré en entier ou pas du tout. Système partenaire SIH, labo, DPI Vérifier JWT et portée Jeton porteur Contrôle 1 : établissement FhirIngestGuard Contrôle 2 : Health ID existant FhirIngestGuard Refus : OperationOutcome rien stocké 200 transaction- response chaque entrée 201 Created Tout enregistrer, ou rien Dossier clinique Contrôle 3 : accord actif FhirIngestGuard Bundle validé un contrôle échoue Système externe Données stockées Contrôle Issue : réussie Issue : refusée Requête Réponse Refus ou échec
  1. POST /api/fhir/R4 Bundle Un Bundle de type transaction avec un jeton porteur. Les ressources isolées vont vers /Observation, /DiagnosticReport ou /Immunization.
  2. Vérifier JWT et portée La signature et les portées du jeton sont vérifiées ; chaque entrée exige la portée de son type de ressource.
  3. Contrôle 1 : établissement L’établissement auteur est pris dans le jeton vérifié uniquement, jamais dans le contenu.
  4. Contrôle 2 : Health ID existant Le patient doit correspondre exactement à un Health ID existant. Un partenaire n’en crée jamais.
  5. Contrôle 3 : accord actif Le patient doit avoir un accord actif envers cet établissement. Pas d’accord, pas d’écriture.
  6. Tout enregistrer, ou rien Toutes les entrées sont écrites dans une seule transaction ; tout refus annule l’ensemble.
  7. 200 transaction-response Chaque entrée indique 201 Created. Un POST de ressource isolée renvoie 201.
  8. Refus : OperationOutcome Tout contrôle échoué renvoie un OperationOutcome FHIR et rien n’est enregistré.
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
Système partenaire uri:POST api/fhir/R4 uri:GET api/fhir/R4/metadata
Vérifier JWT et portée method:App\Services\Fhir\FhirIngestGuard::scopes method:App\Services\Fhir\FhirIngestGuard::requireScope
Contrôle 1 : établissement method:App\Services\Fhir\FhirIngestGuard::facilityId
Contrôle 2 : Health ID existant method:App\Services\Fhir\FhirIngestGuard::resolveSubject
Refus : OperationOutcome method:App\Services\Fhir\FhirIngestGuard::recordRefusal
200 transaction- response method:App\Services\Fhir\FhirIngestGuard::recordAccepted uri:POST api/fhir/R4/Observation
Tout enregistrer, ou rien method:App\Http\Controllers\Api\Fhir\FhirIngestController::transaction class:App\Services\Fhir\FhirIngestService
Contrôle 3 : accord actif method:App\Services\Fhir\FhirIngestGuard::requireConsent class:App\Models\ConsentGrant

Tous les flux en JSON

Des vocabulaires comme données, pas comme texte

Diagnostics, analyses, médicaments et unités sont codés selon des vocabulaires publiés, importés comme des données : la CIM-10 de l'Organisation mondiale de la Santé, avec ses libellés français ; LOINC pour les observations de laboratoire ; ATC pour les médicaments ; et UCUM pour les unités de mesure, afin que milligrammes et micromoles par litre ne se confondent jamais lors d'une transmission. Un dictionnaire de codes les coiffe, pour qu'un code reçu par ingestion et un code choisi au guichet veuillent dire la même chose.

Une surface développeurs avec garde-fous

Le portail développeurs permet à une organisation d'enregistrer des applications et d'obtenir des identifiants, de s'abonner aux webhooks, de consulter chaque livraison et d'en rejouer une qui a échoué. Un partenaire peut aussi transmettre ses niveaux de stock de pharmacie et de sang par l'API Connect, qui n'alimente la recherche que si la source figure sur la liste autorisée. Les administrateurs de la plateforme tiennent une liste de contrôle de certification des intégrations. La documentation est sur opescare.com/docs. Un éditeur de logiciel de laboratoire peut s'intégrer à une surface autorisée et auditée plutôt qu'à un fil de courriels.

Rapportage national, agrégé uniquement

OpesCare peut transmettre ses propres chiffres mensuels agrégés — jamais de données individuelles — à l'instance nationale DHIS2 du MINSANTE. Les établissements sont rattachés à des unités d'organisation et les chiffres à des éléments de données ; un brouillon est généré le premier de chaque mois, et un administrateur de la plateforme l'examine et l'approuve avant tout envoi. Aujourd'hui, les brouillons sont générés mais rien n'est transmis : cela attend que le MINSANTE ouvre l'accès à l'instance nationale. Il s'agit d'un rapportage à sens unique, pas d'un échange de données de santé.

4. L'accueil et la consultation

Pour un centre de santé, la plateforme couvre les moments de la journée qui concernent les patients d'OpesCare :

  • Le triage enregistre les constantes au regard des normes adultes et permet la réévaluation. Il réordonne la file selon l'urgence ; il ne raccourcit l'attente de personne et ne bloque jamais les soins.
  • La file d'attente mène le patient de l'arrivée à l'appel, au début puis à la fin de la prise en charge, ou le note absent ; elle est triée côté serveur, si bien que tous les écrans voient le même ordre.
  • La prescription passe par un contrôle des interactions avant l'émission, et l'ordonnance imprimée porte un code de vérification.
  • Les orientations sont envoyées, acceptées, menées à terme ou refusées entre cliniciens ; le patient peut en demander une depuis l'application.
  • Les vaccinations sont enregistrées au nom du patient et peuvent être annulées, jamais modifiées en silence.
  • Les factures peuvent être émises et réglées par mobile money — indisponible tant que les comptes marchands ne sont pas connectés — et les soins ne sont jamais conditionnés au paiement.

Ce que le côté clinique n'est pas : une documentation clinique complète, les admissions, sorties et transferts, la gestion des lits, les sinistres d'assurance et les ententes préalables. Un registre des services et des lits existe pour qu'un établissement puisse déclarer son occupation ; c'est un registre, pas un système d'admission.

5. La pharmacie : pas une liste de stock, un circuit

Une pharmacie indépendante dispose d'une console complète, construite autour de la délivrance.

  • Les ordonnances arrivent dans une seule liste — des cliniciens sur OpesCare comme des patients qui les partagent — et passent par acceptée → prête → délivrée. Une ordonnance rédigée dans un établissement peut être servie dans un autre : le patient l'emporte avec lui.
  • Les commandes des patients — les réservations de médicaments faites depuis l'application — suivent leur propre parcours : acceptée, prête, puis retirée ou expédiée et livrée, ou annulée.
  • Le stock, c'est ce que la pharmacie détient vraiment : niveaux et lots, réceptions des livraisons, ajustements motivés, notes de réapprovisionnement, liste de prix avec historique, et import par tableur avec aperçu, correspondance des colonnes et rapport d'erreurs avant toute validation.
  • Les médicaments contrôlés ont leur propre registre.
  • Les rapports exportent les chiffres de délivrance et de stock en CSV ou en PDF.
De l'ordonnance au médicament délivré Un clinicien établit une ordonnance après un contrôle des interactions. Le patient peut la partager ou être simplement retrouvé au comptoir ; la pharmacie l'accepte, la prépare et la délivre, en déduisant le stock et en imprimant les étiquettes. Par ailleurs, un patient peut réserver un médicament dans l'application ; la pharmacie accepte la commande, la prépare, puis elle est retirée ou livrée, ou annulée tant qu'elle est ouverte. Clinicien poste du prescripteur Ordonnance établie après contrôle des interactions Patient détient l'ordonnance Médicament réservé depuis l'app Liste de la pharmacie ou recherche par Health ID Partagée à une pharmacie facultatif, depuis l'app Annulée depuis tout état ouvert Commande acceptée par la pharmacie Acceptée par le pharmacien Prête patient prévenu Expédiée en livraison Commande prête à retirer ou livrer Délivrée stock déduit · étiquettes Livrée au patient Retirée au comptoir recherche réserver retrait livrer Personne ou appareil Service OpesCare Issue : réussie Issue : refusée Requête Réponse En file / asynchrone Refus ou échec
  1. Ordonnance établie Le clinicien rédige l'ordonnance ; un contrôle des interactions s'exécute avant l'enregistrement.
  2. Partagée à une pharmacie Le patient peut partager l'ordonnance depuis l'application pour qu'elle apparaisse dans la liste de cette pharmacie.
  3. Retrouvée au comptoir Sans partage, le pharmacien la retrouve par le Health ID du patient. Elle peut être rédigée dans un établissement et servie dans un autre.
  4. Acceptée et préparée Le pharmacien accepte l'ordonnance et la marque prête.
  5. Délivrée La délivrance enregistre ce qui a été remis, déduit le stock et imprime les étiquettes.
  6. Médicament réservé Un patient réserve un médicament dans l'application ; la pharmacie accepte la commande et la prépare.
  7. Retirée Le patient retire la commande au comptoir.
  8. Livrée Ou la pharmacie l'expédie et la marque livrée.
  9. Annulée Une commande peut être annulée par le patient ou la pharmacie tant qu'elle est ouverte.
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.prescribe
Ordonnance établie route:portals.prescriber.store route:portals.prescriber.interaction_check method:App\Http\Controllers\MedicalId\PrescriberController::store
Patient uri:GET api/mobile/prescriptions
Médicament réservé uri:POST api/mobile/pharmacy/reservations method:App\Http\Controllers\Api\Mobile\MobilePharmacyController::reserve
Liste de la pharmacie route:portals.pharmacy.prescriptions route:portals.pharmacy.prescriptions.lookup uri:GET api/mobile/pharmacy-desk/prescriptions/lookup
Partagée à une pharmacie uri:POST api/mobile/prescriptions/{id}/share method:App\Http\Controllers\Api\Mobile\MobilePrescriptionController::share
Annulée route:portals.pharmacy.orders.cancel method:App\Http\Controllers\Api\Mobile\MobilePharmacyController::cancelReservation
Commande acceptée route:portals.pharmacy.orders.accept method:App\Http\Controllers\Api\Mobile\Pharmacy\PharmacyReservationController::accept
Acceptée method:App\Http\Controllers\Api\Mobile\Pharmacy\PharmacyDeskController::accept
Prête method:App\Http\Controllers\Api\Mobile\Pharmacy\PharmacyDeskController::ready
Expédiée route:portals.pharmacy.orders.dispatch
Commande prête route:portals.pharmacy.orders.ready
Délivrée route:portals.pharmacy.dispense method:App\Http\Controllers\Api\Mobile\Pharmacy\PharmacyDeskController::dispense class:App\Services\Clinical\PrescriptionService route:documents.new.labels
Livrée route:portals.pharmacy.orders.delivered
Retirée route:portals.pharmacy.orders.collected

Tous les flux en JSON

Deux limites comptent. Le stock déclaré par une pharmacie ne devient une disponibilité trouvable que si sa source figure sur la liste autorisée : une recherche vide est la réponse honnête, plutôt qu'une démonstration remplie d'un stock inventé. Et les achats — bons de commande, contrats fournisseurs — ne font pas partie d'OpesCare ; une simple liste de fournisseurs existe pour que les réceptions indiquent d'où vient le stock.

6. Le laboratoire : du prélèvement à la publication

Les laboratoires suivent un circuit de publication, pas une boîte de réception.

  • Les demandes des cliniciens ou des patients sont acceptées ou refusées par le laboratoire.
  • Les analyses passent par le prélèvement, la saisie des résultats, la validation et la publication. Un résultat publié peut être corrigé, mais la correction est consignée, jamais écrasée.
  • La publication prévient les deux côtés à la fois. Le patient reçoit le résultat dans son application, et le clinicien prescripteur est informé dans la même étape. Une valeur critique est signalée en priorité haute, et le laboratoire consigne son rappel téléphonique au clinicien.
  • Un tableau de bord du responsable affiche les délais, le travail en attente et les alertes critiques.
Du prélèvement au résultat publié Un examen est prescrit par un clinicien, ou demandé par le patient puis approuvé par le laboratoire. Le prélèvement est fait, les résultats sont saisis et validés, et la publication est refusée sans résultats. Une seule publication prévient ensemble le patient et le clinicien prescripteur ; les tuteurs sont prévenus une fois, les valeurs critiques donnent lieu à un rappel consigné, et les corrections ultérieures sont consignées sans écraser l'original. Patient a besoin d'un examen Clinicien prescrit depuis le dossier Examen prescrit demande créée Prélèvement fait au laboratoire Examen demandé par le patient, dans l'app Le responsable décide accepter ou refuser Publication refusée pas encore de résultats Résultats saisis valeur par valeur Refusé aucune demande créée Correction consignée jamais écrasée Publication une étape verrouillée Validés second contrôle Tuteurs prévenus une fois Patient prévenu cloche + push Clinicien prévenu dans la même étape Rappel consigné valeurs critiques consulte accepter refuser sans résultat plus tard critique 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 clinicien prescrit Le clinicien prescrit l'examen depuis le dossier du patient.
  2. Ou le patient demande Un patient peut demander un examen dans l'application ; le responsable du laboratoire l'accepte ou le refuse.
  3. Prélèvement fait Le laboratoire enregistre le prélèvement.
  4. Résultats saisis Les résultats sont saisis sur la demande.
  5. Validés Les résultats sont validés avant toute publication.
  6. Publiés La publication s'exécute en une seule étape verrouillée.
  7. Patient prévenu Le patient reçoit une notification et un push, en priorité haute si une valeur est critique.
  8. Clinicien prévenu Le clinicien prescripteur est prévenu dans la même étape.
  9. Tuteurs prévenus une fois Les tuteurs liés au patient sont prévenus une fois.
  10. Rappel critique Pour une valeur critique, le laboratoire consigne le rappel téléphonique effectué.
  11. Correction après publication Une correction ultérieure est consignée à côté de la valeur d'origine, sans l'écraser.
  12. Refusée sans résultats La publication est refusée tant qu'il n'y a aucun résultat.
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 uri:POST api/mobile/labs/requests
Clinicien config:staff_capabilities.capabilities.clinical_chart
Examen prescrit uri:POST api/mobile/doctor/patients/{patient}/lab-orders method:App\Http\Controllers\Api\Mobile\MobileDoctorLabOrderController::store
Prélèvement fait route:portals.lab.collect method:App\Http\Controllers\MedicalId\LabDeskWebController::collect
Examen demandé uri:POST api/mobile/labs/requests
Le responsable décide route:portals.lab_manager.requests.approve route:portals.lab_manager.requests.decline
Publication refusée method:App\Services\Lab\LabDeskService::release
Résultats saisis route:portals.lab.results.store
Refusé route:portals.lab_manager.requests.decline
Correction consignée route:portals.lab.results.correct
Publication route:portals.lab.release method:App\Services\Lab\LabDeskService::release
Validés route:portals.lab.validate
Tuteurs prévenus method:App\Listeners\NotifyGuardiansOfPatientEvent::handleLabResult
Patient prévenu method:App\Services\Lab\LabDeskService::notifyReleased method:App\Services\Lab\LabDeskService::bellPatient method:App\Services\Lab\LabDeskService::pushPatient
Clinicien prévenu method:App\Services\Lab\LabDeskService::notifyReleased
Rappel consigné route:portals.lab_manager.critical_callback method:App\Http\Controllers\MedicalId\LabManagerDeskController::criticalCallback

Tous les flux en JSON

L'imagerie suit la même logique pour les demandes : demandée, planifiée, commencée, réalisée, rapportée, puis finalisée et diffusée, avec une possibilité d'amendement. OpesCare conserve le compte rendu et sa pièce jointe ; ce n'est pas une archive d'images, et il n'y a ni PACS ni visionneuse DICOM.

7. La banque de sang : l'offre rencontre la demande

  • L'inventaire est tenu par produit sanguin et par groupe, avec ajustements et signalements, et peut aussi être synchronisé depuis un système partenaire.
  • Le guichet des demandes mène chaque demande d'un clinicien ou d'un patient de la décision à la préparation puis au service, et imprime un bon de demande.
  • Les donneurs peuvent déclarer leur disponibilité depuis l'application.
  • Le côté patient referme la boucle. La recherche de sang qu'utilise le patient est alimentée par l'inventaire que tient la banque de sang, et une demande faite dans l'application arrive au même guichet.
Une demande de sang, de la demande à la remise Une demande de sang vient de l'application patient ou d'un clinicien dans un établissement. La banque de sang décide au vu de son inventaire : une demande acceptée est préparée puis honorée, avec un bon de demande ; une demande refusée s'arrête là, et un patient peut annuler sa propre demande. Le même inventaire alimente la recherche publique de sang. Clinicien dans un établissement Demande du guichet personnel de l'établissement La banque décide accepter ou refuser Inventaire du sang saisie · synchro partenaire Patient ou un proche Demande depuis l'app groupe · unités · urgence Prête unités réservées Visible dans la recherche disponibilité par groupe Annulée par le demandeur Honorée bon de demande PDF Refusée demandeur prévenu sur place annuler vérifié accepter refuser Personne ou appareil Service OpesCare Données stockées Décision Issue : réussie Issue : refusée Requête Réponse En file / asynchrone Refus ou échec
  1. Demande depuis l'app Un patient demande du sang depuis l'application en indiquant le groupe, le nombre d'unités et l'urgence.
  2. Demande d'un établissement Un clinicien ou le guichet de l'établissement fait la demande pour le patient.
  3. Vérifiée sur l'inventaire La banque de sang décide avec son propre inventaire sous les yeux.
  4. Prête, puis honorée Une demande acceptée est mise de côté puis honorée ; le bon de demande sort en PDF.
  5. Refusée Une demande refusée s'arrête là et le demandeur est prévenu.
  6. Annulée Un patient peut annuler sa propre demande.
  7. La recherche lit l'inventaire La recherche publique de sang affiche la disponibilité issue du même inventaire.
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.blood_inventory
Demande du guichet route:portals.staff.blood_requests.store method:App\Http\Controllers\MedicalId\BloodRequestDeskController::store
La banque décide route:portals.staff.blood_requests.decide uri:POST api/mobile/blood-desk/requests/{id}/decide method:App\Http\Controllers\Api\V1\BloodRequestQueueController::decide
Inventaire du sang route:portals.staff.inventory.blood route:portals.staff.inventory.blood.adjust uri:POST api/v1/connect/inventory/blood-stock/sync
Patient uri:GET api/mobile/blood/requests
Demande depuis l'app uri:POST api/mobile/blood/requests method:App\Http\Controllers\Api\Mobile\MobileBloodController::store
Prête route:portals.staff.blood_requests.ready method:App\Http\Controllers\Api\Mobile\MobileBloodDeskController::ready
Visible dans la recherche route:public.network.blood-finder uri:GET api/mobile/blood/search
Annulée uri:POST api/mobile/blood/requests/{id}/cancel
Honorée route:portals.staff.blood_requests.fulfil method:App\Http\Controllers\Api\Mobile\MobileBloodDeskController::fulfil route:documents.new.blood_request
Refusée route:portals.staff.blood_requests.decide

Tous les flux en JSON

8. La colonne vertébrale de la gouvernance

Tout ce qui précède repose sur la même gouvernance que l'application.

  • Le consentement comme protocole. Chaque lecture d'un patient par un clinicien franchit une barrière qui exige une relation de soins — un rendez-vous, une équipe soignante, un épisode ouvert dans l'établissement — ou une autorisation approuvée par le patient.
  • Les journaux d'accès. Les lectures sont journalisées, et la vue des accès du patient est ce même journal.
  • L'accès d'urgence. Le bris de glace exige un motif, n'ouvre qu'un profil limité, alerte le patient et fait l'objet d'une revue.
  • Les opérations de sécurité. Les administrateurs tiennent un registre des violations dans lequel un incident est ouvert, contenu, notifié puis clos.
  • Les documents juridiques — conditions et politiques — sont versionnés, publiés depuis la console d'administration et consultables par tous à une adresse publique.
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

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

  • Back-end : Laravel sur PHP 8.3 et PostgreSQL. Les tâches de fond tournent sur un worker de file géré par le système d'exploitation, avec des files distinctes pour les imports et les webhooks.
  • Documents : les PDF — ordonnances, demandes d'analyses, factures, reçus, étiquettes — sont produits à la demande sur une feuille sécurisée portant un QR code de vérification, si bien qu'une page imprimée peut être confrontée au serveur.
  • API : l'application mobile est un client de l'API comme un autre ; la description OpenAPI est générée à partir du code.
  • Audit : l'accès au dossier patient depuis chaque guichet est inscrit dans la piste d'audit, avec le motif et l'auteur.
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

10. Les limites, honnêtement

  • En production, sans prétendre à l'échelle. OpesCare sert opescare.com en production depuis le 19 octobre 2026. Nous ne publions pas ici de chiffres d'adoption.
  • Un seul pays. OpesCare est conçu pour le Cameroun, en français et en anglais. Il n'y a pas de déploiement multi-pays.
  • Le DHIS2 attend le MINSANTE. Les brouillons mensuels sont générés ; rien n'est envoyé tant que l'accès à l'instance nationale n'est pas accordé.
  • Les paiements attendent les comptes marchands. Le paiement par mobile money est développé et reste indisponible tant que ces comptes ne sont pas connectés.
  • Les notifications push ne sont pas encore dans la version des stores ; elles attendent les identifiants des stores.
  • Pas un système d'information hospitalier. Pas d'admissions, pas de soins infirmiers d'hospitalisation, pas de sinistres d'assurance, pas d'achats, pas de PACS. Ces fonctions relèvent d'autres outils, et le dire garde la plateforme honnête.

11. La plateforme en un paragraphe

Un index patient unique — vérifié chaque nuit, fusionné seulement par une personne, réversible, adressé par le Health ID — alimente une couche d'interopérabilité — ingestion FHIR des partenaires, export FHIR par le patient, CIM-10, LOINC, ATC et UCUM comme données, identifiants restreints et webhooks rejouables, rapportage agrégé au DHIS2 dès qu'il sera ouvert — qui sert les circuits qui existent déjà : triage, file d'attente, prescription, délivrance, du prélèvement à la publication, comptes rendus d'imagerie et demandes de sang. Le téléphone du patient parle à la même colonne vertébrale que le comptoir de la pharmacie.

Le dossier du patient n'a besoin d'être recopié à aucun guichet, parce que chaque guichet travaille sur le même dossier.


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. Cet article accompagne Le dossier est le produit, qui décrit le côté patient. Pour aller plus loin : comment les hôpitaux rejoignent OpesCare, le Health ID, FHIR et l'index maître des patients, ou la documentation développeurs.

Questions fréquentes

Quelle différence entre l'application OpesCare et la plateforme OpesCare ?

L'application est ce que le patient — ou le clinicien en déplacement — tient en main. La plateforme est l'application web d'opescare.com qu'utilisent les établissements : consoles de pharmacie, de laboratoire, d'imagerie, de banque de sang, d'accueil et d'administration, ainsi que l'API à laquelle parlent l'application et les partenaires. Toutes deux travaillent sur le même dossier.

Comment OpesCare évite-t-il de créer des patients en double ?

À l'accueil, l'enregistrement et la prise de rendez-vous se font avec le Health ID exact, et chaque chemin de création de patient vérifie d'abord qu'une identité n'existe pas déjà. Un balayage nocturne signale les doublons probables au guichet de l'index maître des patients. Une personne tranche chaque paire ; les fusions sont journalisées et réversibles.

OpesCare échange-t-il des données avec les systèmes hospitaliers en FHIR ?

En entrée, oui : les partenaires agréés peuvent envoyer, avec des identifiants restreints, des comptes rendus diagnostiques, des observations, des vaccinations et des transactions FHIR R4. OpesCare n'exploite pas de serveur FHIR sortant. Le patient peut exporter son propre dossier sous forme de bundle FHIR depuis l'application.

Une pharmacie peut-elle gérer son stock dans OpesCare ?

Oui, pour ce dont elle a besoin pour être trouvée et pour délivrer : niveaux de stock, lots, réceptions, ajustements, notes de réapprovisionnement, liste de prix et import par tableur. Les bons de commande, les achats et les contrats fournisseurs sont hors périmètre.

Qui est prévenu quand un résultat d'analyse est publié ?

Le patient et le clinicien qui a prescrit l'analyse, dans la même étape. Une valeur critique est signalée en priorité haute, et le laboratoire consigne son rappel téléphonique au clinicien.

OpesCare envoie-t-il des données au DHIS2 ?

Uniquement des chiffres agrégés, jamais de données individuelles, et seulement après qu'un administrateur de la plateforme a approuvé chaque brouillon mensuel. Les brouillons sont générés aujourd'hui ; rien n'est envoyé tant que le MINSANTE n'a pas ouvert l'accès à l'instance nationale.

OpesCare gère-t-il les sinistres d'assurance ou les hospitalisations ?

Non. Les sinistres d'assurance, les ententes préalables, les admissions, sorties, transferts et la gestion des lits sont volontairement hors périmètre. Un registre des services et des lits existe uniquement pour qu'un établissement puisse compter son occupation.

Un développeur peut-il s'intégrer à OpesCare aujourd'hui ?

Oui. Le portail développeurs délivre des identifiants d'application, permet de s'abonner aux webhooks, de consulter les livraisons et de les rejouer, et la documentation sur opescare.com/docs couvre l'API, l'authentification, les webhooks et les flux consentement, QR, FHIR et index maître des patients.

Sources

  1. Architecture de la plateforme — documentation OpesCare — OpesCare (consulté le 19 octobre 2026)
  2. Flux de l'index maître des patients — documentation OpesCare — OpesCare (consulté le 19 octobre 2026)
  3. Flux d'ingestion FHIR R4 — documentation OpesCare — OpesCare (consulté le 19 octobre 2026)
  4. Flux de consentement — documentation OpesCare — OpesCare (consulté le 19 octobre 2026)
  5. Webhooks — documentation OpesCare — OpesCare (consulté le 19 octobre 2026)
  6. Spécification HL7 FHIR Release 4 — HL7 International (consulté le 19 octobre 2026)
  7. LOINC — Logical Observation Identifiers Names and Codes — Regenstrief Institute (consulté le 19 octobre 2026)
  8. Classification internationale des maladies, 10e révision (CIM-10) — Organisation mondiale de la Santé (consulté le 19 octobre 2026)
  9. Index ATC/DDD — Centre collaborateur de l'OMS pour la méthodologie des statistiques sur les médicaments (consulté le 19 octobre 2026)
  10. The Unified Code for Units of Measure (UCUM) — Regenstrief Institute (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