MayVilleHop est une plateforme innovante de coordination ville-hôpital développée pour le territoire de la Mayenne, basée sur la solution HealthShare d'InterSystems. Voici une description fonctionnelle et technique de cette plateforme :

Fonctionnalités principales

1. Gestion des demandes semi-urgentes : La plateforme permet aux médecins de ville de soumettre des demandes d'hospitalisation semi-urgentes, avec une réponse garantie sous 48 heures[1][3].

2. Téléexpertise : Un service de téléexpertise est intégré, permettant aux médecins de ville de consulter des spécialistes hospitaliers à distance[1].

3. Espace de discussion : Les professionnels de santé disposent d'un espace dédié pour échanger directement sur la plateforme[1].

4. Accès aux dossiers médicaux : Les utilisateurs peuvent accéder à la synthèse du dossier médical hospitalier du patient ainsi qu'au Dossier Médical Partagé (DMP)[1].

5. Système de notifications : La plateforme envoie des notifications pour chaque événement important du parcours de soins du patient, comme l'admission, l'hospitalisation et la sortie[1].

6. Annuaire des professionnels : Un annuaire des professionnels de santé hospitaliers est intégré à la plateforme[1].

Aspects techniques

1. Authentification sécurisée : Les professionnels de santé se connectent à la plateforme via leur carte CPS, garantissant un accès sécurisé[1].

2. Interopérabilité : HealthShare permet l'interopérabilité entre les différents systèmes d'information de santé, facilitant le partage de données entre la ville et l'hôpital[3].

3. Identification transversale : La plateforme assure une identification sécurisée et transversale des patients dans l'ensemble des systèmes[4].

4. Analyse populationnelle : HealthShare offre des capacités d'analyse des données de santé de la population, permettant d'identifier les besoins en prévention et de notifier les équipes de prise en charge[3].

5. Personnalisation : La plateforme permet une personnalisation de l'utilisation pour les médecins, s'adaptant à leurs besoins spécifiques[2].

6. Sécurité des données : En tant que solution d'InterSystems, HealthShare intègre des fonctionnalités avancées de sécurité pour protéger les données de santé sensibles.

MayVilleHop vise à fluidifier la communication entre l'hôpital et la ville, optimiser le temps médical, et simplifier les parcours de soins complexes. Cette plateforme s'inscrit dans une démarche plus large de transformation numérique du système de santé, contribuant à renforcer le maillage territorial et la collaboration entre les différents acteurs de santé[4].

Citations:
[1] https://www.youtube.com/watch?v=MjlaarmRx98
[2] https://www.esante-paysdelaloire.fr/media-files/4630/le-numerique-en-san...
[3] https://www.youtube.com/watch?v=cmn1_s7c244
[4] https://emfps.fr/outils-de-coordination-ville-hopital/
[5] https://www.youtube.com/watch?v=wovGmt4ig5Y

Bonjour Moussa,

le messages.log indique une version IRIS 2023.1 :

Si tu utilises ARG IMAGE=intersystemsdc/irishealth-community tu obtiendras une version 2024.1

NB : pour récupérer régulièrement les images plus récentes, le repository officiel InterSystems est https://containers.intersystems.com/contents

Les noms des différentes images régulièrement mises-à-jour sont :
 

EXTENDED_MAINTENANCE=latest-em
CONTINUOUS_DELIVERY=latest-cd
DEVELOPER_PREVIEW=latest-preview
IMAGE_IRIS_EM=containers.intersystems.com/intersystems/irishealth-community:$EXTENDED_MAINTENANCE
IMAGE_IRIS_CD=containers.intersystems.com/intersystems/irishealth-community:$CONTINUOUS_DELIVERY
IMAGE_IRIS_PREVIEW=containers.intersystems.com/intersystems/irishealth-community:$DEVELOPER_PREVIEW

Tu peux utiliser ce repo pour tester les différentes versions d'IRIS for Health :  https://github.com/SylvainGuilbaud/IRISHealth_community 

Bonjour @Julia Pertin 

pour tester un objet dynamique vide tu peux utiliser la méthode d'instance %Size() qui renverra 0

IRISAPP>set monobjet={}

IRISAPP>write monobjet.%Size()
0
IRISAPP>zw monobjet
monobjet={}  ; <DYNAMIC OBJECT>

IRISAPP>set monobjet.data="une valeur"

IRISAPP>write monobjet.%Size()
1
IRISAPP>zw monobjet
monobjet={"data":"une valeur"}  ; <DYNAMIC OBJECT>

Simplement en utilisant l'option Resource dans une instruction CreateDatabase de la section [Actions] du fichier merge.cpf :

[Actions]
CreateResource:Name=%DB_IRISAPP_DATA,Description="IRISAPP_DATA database"
CreateDatabase:Name=IRISAPP_DATA,Directory=/usr/irissys/mgr/IRISAPP_DATA,Resource=%DB_IRISAPP_DATA
CreateResource:Name=%DB_IRISAPP_CODE,Description="IRISAPP_CODE database"
CreateDatabase:Name=IRISAPP_CODE,Directory=/usr/irissys/mgr/IRISAPP_CODE,Resource=%DB_IRISAPP_CODE
CreateNamespace:Name=IRISAPP,Globals=IRISAPP_DATA,Routines=IRISAPP_CODE,Interop=1

Avec le résultat suivant :

python account.py 
Deposit succeeded: Balance after deposit: 100
Deposit of negative amount failed as expected: Deposit amount must be non-negative
Withdrawal succeeded: Balance after withdrawal: 50
Withdrawal of more than available balance failed as expected: Insufficient funds
Balance invariant holds true
Balance invariant violated as expected: Balance invariant violated: Balance is negative
Account operations completed successfully

Exemple en Python :

class Account:
    def __init__(self):
        self.balance = 0

    def deposit(self, amount):
        if amount < 0:
            raise ValueError("Deposit amount must be non-negative")
        
        old_balance = self.balance
        self.balance += amount
        
        # Postconditions
        if self.balance != old_balance + amount:
            raise ValueError("Postcondition failed: Balance calculation error")

    def withdraw(self, amount):
        if amount < 0:
            raise ValueError("Withdrawal amount must be non-negative")
        if self.balance < amount:
            raise ValueError("Insufficient funds")

        old_balance = self.balance
        self.balance -= amount
        
        # Postconditions
        if self.balance != old_balance - amount:
            raise ValueError("Postcondition failed: Balance calculation error")

    def check_balance_invariant(self):
        if self.balance < 0:
            raise ValueError("Balance invariant violated: Balance is negative")

    @classmethod
    def test_account(cls):
        account = cls()
        
        try:
            # Test depositing a positive amount
            account.deposit(100)
            print("Deposit succeeded: Balance after deposit:", account.balance)
            
            # Test depositing a negative amount (should fail)
            account.deposit(-50)
        except ValueError as e:
            print("Deposit of negative amount failed as expected:", e)
        else:
            raise ValueError("Deposit of negative amount unexpectedly succeeded")
        
        try:
            # Test withdrawing a valid amount
            account.withdraw(50)
            print("Withdrawal succeeded: Balance after withdrawal:", account.balance)
            
            # Test withdrawing more than the available balance (should fail)
            account.withdraw(200)
        except ValueError as e:
            print("Withdrawal of more than available balance failed as expected:", e)
        else:
            raise ValueError("Withdrawal of more than available balance unexpectedly succeeded")
        
        try:
            # Check balance invariant (should succeed)
            account.check_balance_invariant()
            print("Balance invariant holds true")
        except ValueError as e:
            print("Balance invariant violated:", e)
        
        # Intentionally set balance to negative value to trigger balance invariant failure
        account.balance = -10
        
        try:
            # Check balance invariant (should fail)
            account.check_balance_invariant()
        except ValueError as e:
            print("Balance invariant violated as expected:", e)
        else:
            raise ValueError("Balance invariant unexpectedly held true")
        
        print("Account operations completed successfully")

# Run the test
Account.test_account()

Avec le résultat suivant :

write ##class(MyApp.Account).TestAccount()
Deposit succeeded: Balance after deposit: 100
Deposit of negative amount failed as expected: ERROR #5001: Deposit amount must be non-negative
Withdrawal succeeded: Balance after withdrawal: 50
Withdrawal of more than available balance failed as expected: ERROR #5001: Insufficient funds
Balance invariant holds true
Balance invariant violated as expected: ERROR #5001: Balance invariant violated: Balance is negative
Account operations completed successfully
1

Exemple en ObjectScript

Include %occErrors

Class MyApp.Account Extends %Persistent
{

Property Balance As %Numeric;

/// Deposit money into the account
Method Deposit(amount As %Numeric) As %Status
{
    // Preconditions
    If amount < 0 {
        Return $$$ERROR($$$GeneralError, "Deposit amount must be non-negative")
    }

    // Store the old balance
    Set oldBalance = ..Balance

    // Update balance
    Set ..Balance = oldBalance + amount

    // Postconditions
    If (..Balance '= $$$NULLOREF) && (..Balance '= (oldBalance + amount)) {
        Return $$$ERROR($$$GeneralError, "Postcondition failed: Balance calculation error")
    }

    Quit $$$OK
}

/// Withdraw money from the account
Method Withdraw(amount As %Numeric) As %Status
{
    // Preconditions
    If amount < 0 {
        Return $$$ERROR($$$GeneralError, "Withdrawal amount must be non-negative")
    }
    If (..Balance = $$$NULLOREF) || (..Balance < amount) {
        Return $$$ERROR($$$GeneralError, "Insufficient funds")
    }

    // Store the old balance
    Set oldBalance = ..Balance

    // Update balance
    Set ..Balance = oldBalance - amount

    // Postconditions
    If (..Balance '= $$$NULLOREF) && (..Balance '= (oldBalance - amount)) {
        Return $$$ERROR($$$GeneralError, "Postcondition failed: Balance calculation error")
    }

    Quit $$$OK
}

/// Invariant: Balance should always be non-negative
Method CheckBalanceInvariant() As %Status
{
        Set tSC = $$$OK
        If ..Balance < 0 {
            Set tSC = $$$ERROR($$$GeneralError, "Balance invariant violated: Balance is negative")
        }
        Quit tSC
}

/// Class method to test the Account class
ClassMethod TestAccount() As %Status
{
    // Create a new instance of Account
    Set account = ##class(MyApp.Account).%New()
    
    // Initialize the balance
    Set account.Balance = 0
    
    // Test depositing a positive amount
    Set tSC = account.Deposit(100)
    If $$$ISERR(tSC) {
        Write "Deposit failed: ", $system.Status.GetErrorText(tSC), !
        Quit tSC
    }
    Write "Deposit succeeded: Balance after deposit: ", account.Balance, !
    
    // Test depositing a negative amount (should fail)
    Set tSC = account.Deposit(-50)
    If $$$ISERR(tSC) {
        Write "Deposit of negative amount failed as expected: ", $system.Status.GetErrorText(tSC), !
    } Else {
        Write "Deposit of negative amount unexpectedly succeeded", !
        Quit $$$ERROR($$$GeneralError, "Deposit of negative amount unexpectedly succeeded")
    }
    
    // Test withdrawing a valid amount
    Set tSC = account.Withdraw(50)
    If $$$ISERR(tSC) {
        Write "Withdrawal failed: ", $system.Status.GetErrorText(tSC), !
        Quit tSC
    }
    Write "Withdrawal succeeded: Balance after withdrawal: ", account.Balance, !
    
    // Test withdrawing more than the available balance (should fail)
    Set tSC = account.Withdraw(200)
    If $$$ISERR(tSC) {
        Write "Withdrawal of more than available balance failed as expected: ", $system.Status.GetErrorText(tSC), !
    } Else {
        Write "Withdrawal of more than available balance unexpectedly succeeded", !
        Quit $$$ERROR($$$GeneralError, "Withdrawal of more than available balance unexpectedly succeeded")
    }
    
    // Check balance invariant (should succeed)
    Set tSC = account.CheckBalanceInvariant()
    If $$$ISERR(tSC) {
        Write "Balance invariant violated: ", $system.Status.GetErrorText(tSC), !
        Quit tSC
    }
    Write "Balance invariant holds true", !
    
    // Intentionally set balance to negative value to trigger balance invariant failure
    Set account.Balance = -10
    
    // Check balance invariant (should fail)
    Set tSC = account.CheckBalanceInvariant()
    If $$$ISERR(tSC) {
        Write "Balance invariant violated as expected: ", $system.Status.GetErrorText(tSC), !
    } Else {
        Write "Balance invariant unexpectedly held true", !
        Quit $$$ERROR($$$GeneralError, "Balance invariant unexpectedly held true")
    }
    
    Write "Account operations completed successfully", !
    Quit $$$OK
}

Storage Default
{
<Data name="AccountDefaultData">
<Value name="1">
<Value>%%CLASSNAME</Value>
</Value>
<Value name="2">
<Value>Balance</Value>
</Value>
</Data>
<DataLocation>^MyApp.AccountD</DataLocation>
<DefaultData>AccountDefaultData</DefaultData>
<IdLocation>^MyApp.AccountD</IdLocation>
<IndexLocation>^MyApp.AccountI</IndexLocation>
<StreamLocation>^MyApp.AccountS</StreamLocation>
<Type>%Storage.Persistent</Type>
}

}

Bienvenue à IRIS 2024 !!


Chez un de nos clients, la nouvelle fonctionnalité des bases de données multi-volumes a notamment permis de pallier la contrainte de la taille des fichiers sur leur serveur de stockage en réseau (NAS) limitée à 4To.

Le portail  System > Databases > Database Details permet de voir les différents volumes créés ; ici avec un seuil à 15Mo : 

Extrait de la documentation en ligne :

À mesure que les bases de données clients se développent, les fichiers de bases de données évoluent également. Pour éviter que ces fichiers ne deviennent trop volumineux ou n'atteignent les limites strictes du système de fichiers, InterSystems IRIS prend désormais en charge la division transparente de votre base de données sur plusieurs « volumes » physiques. Cette nouvelle fonctionnalité se configure facilement : pour n'importe quelle base de données, vous pouvez désormais configurer une taille de seuil. Lorsque votre fichier IRIS.DAT initial est sur le point d'atteindre cette taille et que de nouvelles données globales doivent être écrites, InterSystems IRIS créera de manière transparente un nouveau fichier « volume de base de données » et commencera à écrire de nouvelles données dans ce fichier. Lorsque ce volume atteint le seuil, un autre fichier est créé, et ainsi de suite.

Il n'y a aucun impact sur les applications et le code qui accèdent aux données, car ils continuent de voir le contenu complet de la base de données, quel que soit le nombre de volumes sur lesquels elle est répartie. De plus, vous pouvez configurer le répertoire dans lequel le prochain volume doit être créé et, si nécessaire, vous pouvez réorganiser les volumes de base de données dans les répertoires en tant qu'opération de maintenance. Combiné aux travaux prévus pour augmenter la taille maximale globale de la base de données, cela garantira que vos données restent faciles à gérer, bien dans la plage des pétaoctets.

Merci à @Vitaliy Serdtsev : il est aussi possible de récupérer directement un JSON à partir d'une requête SQL, avec les fonctions JSON_ARRAYAGG et JSON_OBJECT :

SELECT JSON_ARRAYAGG(json_obj)
  FROM (SELECT TOP 5
            JSON_OBJECT(
              'Name':name
              ,'Age':age
              ,'DOB':to_char(dob,'Day DD Month YYYY')
            ) json_obj
           FROM sample.person
       )
SELECT JSON_ARRAYAGG(json_obj)
  FROM (SELECT JSON_OBJECT(
                'Name':name
                ,'Age':age
                ,'DOB':to_char(dob,'Day DD Month YYYY')
                ) json_obj
       FROM sample.person
       )
  WHERE %VID BETWEEN 1 AND 5

Résultat :