#Consejos y trucos

0 Seguidores · 150 Publicaciones

Es la experiencia en el sector de la tecnología de InterSystems que resuelve algún problema en particular de una manera elegante o inusual.

Artículo Ricardo Paiva · oct 22, 2024 4m read

Cuando utilizáis InterSystems IRIS como motor de interoperabilidad, todos sabemos y apreciamos lo fácil que es usar el Visor de Mensajes para revisar las trazas de los mensajes y ver exactamente qué está ocurriendo en vuestra producción. Sin embargo, cuando un sistema maneja millones de mensajes al día, puede que no sepáis por dónde empezar vuestra investigación.

A lo largo de mis años apoyando producciones en IRIS, a menudo me encuentro investigando cosas como...

  • ¿Qué tipo de rendimiento tiene este flujo de trabajo?  
  • ¿Dónde está el cuello de botella?  
  • ¿Cuáles son mis errores más comunes?
0
0 78
Artículo Alberto Fuentes · oct 21, 2024 3m read

¡Muy buenas a todos! Os paso un ejemplo de resolución de problemas a la hora de implementar transformaciones de datos que es muy interesante: estaba trabajando en un transformación de datos (DTL) de mensajes HL7 pero no paraba de obtener errores del tipo ERROR #5002... MAXSTRING. El problema era que la mayor parte de acciones en la interfaz gráfica de DTL utilizan el tipo de datos %String al trabajar con segmentos de un mensaje HL7.

Un %String tiene un límite de 3,641,144 caracteres, y mi OBX5.1 tenía 5,242,952 caracteres de longitud, como en el ejemplo proporcionado. Por supuesto, el administrador del sistema PACS dijo que se necesitaban archivos de ultra alta calidad, incluyendo resolución 4K, por lo que no pudimos lograr que el proveedor comprimiera o reformateara estos archivos a jpg comprimido o algo similar.

Inicialmente, este proveedor envía un ORU^R01 en la versión 2.3, y el EHR espera un MDM^T02 también en la versión 2.3. Además, necesitábamos realizar las siguientes transformaciones:

  1. La imagen incrustada se enviaba en OBX-5.1, y necesitábamos moverla a OBX-5.5.
  2. El formato de la imagen se enviaba en OBX-6, y lo necesitábamos en OBX-5.3 y OBX-5.4.
  3. Necesitábamos crear un segmento TXA.
  4. Soportar un conjunto de 25 segmentos OBX que podían estar completamente vacíos (>25 x 5Mb = ¡más de 125Mb de tamaño de mensaje!).

Ejemplo de estructura de mensaje recibido (cada "..." quedaría reemplazado con datos de más de 5 MB):

MSH|^~\&|VENDOR||||20241017125335||ORU^R01|1|P|2.3|
PID|||203921||LAST^FIRST^^^||19720706|M||||||||||100001|
PV1||X||||||||GI6|||||||||100001|
ORC|RE||21||SC||1|||||||||||
OBR|1||21|21^VENDOR IMAGES|||20241017123056|||||||||1001^GASTROENTEROLOGY^PHYSICIAN|||||Y||||F||1|
OBX|1|PR|100001|ch1_image_001.bmp|...^^^^^^^|BMP|||||F|
OBX|2|PR|100001|ch1_image_003.bmp|...|BMP|||||F|
OBX|3|PR|100001|ch1_video_01thumbnail.bmp|...|BMP|||||F|
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||
OBX||||||||||||

Las herramientas y métodos de prueba habituales no estaban a la altura para manejar mensajes tan grandes. Cuando usaba este ejemplo reemplazando los datos con ..., la interfaz gráfica de DTL de arrastrar y soltar funcionaba bien, pero al insertar los datos reales, todo se venía abajo.

Finalmente, descubrí que tenía que usar un bloque de código con ObjectScript y los tipos de datos Stream para poder trabajar correctamente con estos mensajes grandes.

Comparto mi clase final de DTL para cualquiera que venga después de mí y pueda encontrar esto útil:

Class OrdRes.VendorMDM Extends Ens.DataTransformDTL [ DependsOn = EnsLib.HL7.Message ]
{

Parameter IGNOREMISSINGSOURCE = 1;

Parameter REPORTERRORS = 1;

Parameter TREATEMPTYREPEATINGFIELDASNULL = 0;

XData DTL [ XMLNamespace = "http://www.intersystems.com/dtl" ]
{
<transform sourceClass='EnsLib.HL7.Message' targetClass='EnsLib.HL7.Message' sourceDocType='2.3:ORU_R01' targetDocType='2.5:MDM_T02' create='new' language='objectscript' >
<assign value='source.{MSH}' property='target.{MSH}' action='set' />
<assign value='"MDM"' property='target.{MSH:MessageType.MessageCode}' action='set' />
<assign value='"T02"' property='target.{MSH:MessageType.TriggerEvent}' action='set' />
<assign value='"2.5"' property='target.{MSH:VersionID.VersionID}' action='set' />
<assign value='source.{MSH:DateTimeofMessage}' property='target.{EVN:2}' action='set' />
<assign value='source.{PIDgrpgrp().PIDgrp.PID}' property='target.{PID}' action='set' />
<assign value='source.{PIDgrpgrp().PIDgrp.PV1grp.PV1}' property='target.{PV1}' action='set' />
<assign value='source.{PIDgrpgrp().ORCgrp().ORC}' property='target.{ORCgrp().ORC}' action='set' />
<assign value='source.{PIDgrpgrp().ORCgrp().OBR}' property='target.{ORCgrp().OBR}' action='set' />
<assign value='source.{PIDgrpgrp().ORCgrp().NTE()}' property='target.{ORCgrp().NTE()}' action='set' />
<assign value='"Endoscopy Image"' property='target.{TXA:DocumentType}' action='set' />
<assign value='"AU"' property='target.{TXA:DocumentCompletionStatus}' action='set' />
<assign value='"AV"' property='target.{TXA:DocumentAvailabilityStatus}' action='set' />
<assign value='source.{PID:18}' property='target.{TXA:12.3}' action='set' />
<code>
<![CDATA[
 set OBXCount=source.GetValueAt("PIDgrpgrp(1).ORCgrp(1).OBXgrp(*)")
 For k1 = 1:1:OBXCount
 {
   // if OBX-1 is empty then it is assumed the rest of the segment will be empty too, so disregard it.
   If source.GetValueAt("PIDgrpgrp(1).ORCgrp(1).OBXgrp("_k1_").OBX:SetIDOBX") '= ""
   {
     // create new stream to read source OBX
     set srcOBXStream=##class(%Stream.GlobalCharacter).%New()
     // get stream data from source OBX
     set tSC=source.GetFieldStreamRaw(srcOBXStream,"PIDgrpgrp(1).ORCgrp(1).OBXgrp("_k1_").OBX")
     // get the positions of needed delimitters:
     set p1=srcOBXStream.FindAt(1,"|")    // 0>p1="OBX"
     set p2=srcOBXStream.FindAt(p1+1,"|") // p1>p2=OBX-1
     set p3=srcOBXStream.FindAt(p2+1,"|") // p2>p3=OBX-2
     set p4=srcOBXStream.FindAt(p3+1,"|") // p3>p4=OBX-3
     set p5=srcOBXStream.FindAt(p4+1,"|") // p4>p5=OBX-4
     set p6=srcOBXStream.FindAt(p5+1,"^") // p5>p6=OBX-5.1
     set p7=srcOBXStream.FindAt(p6+1,"|") // p6>p7=OBX-5.2 -> OBX 5.*
     // if no OBX-5.2 then there will not be the `^` and p6 and p7 will be `-1`
     // when that is the case, find p7 starting at `p5+1` and make p6 = p7
     if (p6 < 0) {
       set p7=srcOBXStream.FindAt(p5+1,"|") // p5>p7=OBX-5
       set p6=p7
     }
     set p8=srcOBXStream.FindAt(p7+1,"|") // p7>p8=OBX-6
     set tStream=##class(%Stream.GlobalCharacter).%New()

     // renumber OBX-1 to OBX 
     set tSC=tStream.Write("OBX|"_k1_"|")
     
     // set OBX2-2 to "ED"
     set tSC=tStream.Write("ED|")
     
     // copy source OBX-3 to target OBX-3
     set tSC=srcOBXStream.MoveTo(p3+1)
     set tSC=tStream.Write(srcOBXStream.Read(p4-p3-1))
     set tSC=tStream.Write("|")
     
     // copy source OBX-4 to target OBX-4
     set tSC=srcOBXStream.MoveTo(p4+1)
     set tSC=tStream.Write(srcOBXStream.Read(p5-p4-1))
     
     // copy source OBX-6 to OBX-5.3 & OBX-5.4
     set tSC=srcOBXStream.MoveTo(p7+1)
     set docType=srcOBXStream.Read(p8-p7-1)
     set tSC=tStream.Write("|^^"_docType_"^"_docType_"^")
     
     // copy source OBX-5.1 to target OBX-5.5
     // can only set up to 3,641,144 chars at once, so do while loop...
     set startPos=p5+1
     set remain=p6-p5-1
     // characters to read/write in each loop, max is 3,641,144 since .Write limit is a %String
     set charLimit=3000000
     while remain > 0 {
       set tSC=srcOBXStream.MoveTo(startPos)
       set toRead = charLimit
       if toRead > remain {
         set toRead=remain
       }
       set tSC=tStream.Write(srcOBXStream.Read(toRead))
       set remain=remain-toRead
       set startPos=startPos+toRead
     }
     set tSC=tStream.Write("|")

     set obxSegment=##class(EnsLib.HL7.Segment).%New()
     set obxSegment.SegType="2.5:OBX"
     set tSC=obxSegment.StoreRawDataStream(tStream)
     set tSC=target.setSegmentByPath(obxSegment,"OBXgrp("_k1_").OBX")
   }
 }
]]></code>
</transform>
}

}

Para desarrollar y probar esto, utilicé los plugins de VSCode para InterSystems porque las herramientas de prueba de integración no podían manejar el tamaño del mensaje.

También añadiré que, para enviar HL7 sobre HTTPS a InterConnect de Epic, fue necesario crear una clase HTTP personalizada y enviar el tipo de contenido personalizado x-application/hl7-v2+er7.

0
0 114
Artículo Ricardo Paiva · oct 17, 2024 1m read

Rúbrica de preguntas frecuentes de InterSystems

En Windows, esto no se puede cambiar, pero en plataformas tipo Unix, se puede cambiar utilizando el comando iris rename.

iris rename instname(<current instance name>) newname(<new instane name>)

Para obtener más información sobre el comando iris rename, por favor consultad el siguiente documento:

Sobre el comando iris

0
0 78
Artículo Jose-Tomas Salvador · oct 10, 2024 3m read

Rúbrica de preguntas frecuentes de InterSystems

Podéis comprobar el espacio libre en disco en cualquier momento usando la clase de utilidad del sistema: SYS.Database y la consulta: FreeSpace.

Aquí tenéis cómo probarlo en el terminal de IRIS (id al espacio de nombres %SYS y luego ejecutadlo):

zn"%SYS"set stmt=##class(%SQL.Statement).%New()
set st=stmt.%PrepareClassQuery("SYS.Database","FreeSpace")
set rset=stmt.%Execute()
do rset.%Display()

El resultado de salida es el siguiente:

0
0 69
Artículo Jose-Tomas Salvador · sep 30, 2024 3m read

Existen muchas aplicaciones para trabajar con mensajes HL7 V2, pero las herramientas para trabajar con XML en el Portal de Gestión o los IDE de IRIS son limitadas. Aunque hay muchas utilidades externas e IDEs que funcionan con mensajes XML e incluso documentos C-CDA, hay una razón convincente para poder hacer pruebas directamente en el marco de trabajo C-CDA de IRIS.

Hacer pruebas dentro del entorno de IRIS os proporciona el contexto necesario:

0
0 78
Artículo Ricardo Paiva · sep 10, 2024 3m read

Rúbrica de preguntas frecuentes de InterSystems

Los globales temporales almacenados en las bases de datos IRISTEMP/CACHETEMP se utilizan cuando un proceso no necesita almacenar datos de manera indefinida, pero requiere el potente rendimiento de los globales. Las bases de datos IRISTEMP/CACHETEMP no se registran en el diario, por lo que el uso de globales temporales no genera archivos de diario.

El sistema utiliza las bases de datos IRISTEMP/CACHETEMP para almacenamiento temporal y están disponibles para vosotros para el mismo fin.

0
0 95
Artículo Luis Angel Pérez Ramos · sep 2, 2024 1m read

[FAQ] Preguntas frecuentes de InterSystems

El siguiente código descarga https://www.intersystems.com/assets/intersystems-logo.png y guarda el archivo como c:\temp\test.png.

Es necesario definir una configuración SSL llamada SSLTEST antes de ejecutar este código.

0
0 66
Artículo Saul Perez · mayo 29, 2024 7m read

¡Hola a todos los estimados miembros de la comunidad de desarrolladores de InterSystems en español!

Aunque suelo consultar la comunidad de desarrolladores y alguna vez he dejado alguna pregunta por aquí, este será mi primer artículo y qué mejor ocasión para hacerlo que participando en el 3er concurso de artículos técnicos.

El tema que trataré en este artículo será el de las diferentes herramientas que nos proporciona InterSystems IRIS para optimizar tanto las bases de datos como las consultas que ejecutamos así como los nuevos tipos de almacenamiento y de datos.

0
0 226
Artículo Luis Angel Pérez Ramos · mayo 16, 2024 3m read

Revisando los diferentes artículos que he ido publicando he caído en la cuenta de que me faltaba explicar una funcionalidad bastante práctica dentro de nuestro EMPI (Enterprise Master Patient Index) y no es otra que la notificación de altas y vinculaciones a sistemas externos al EMPI.

0
0 82
Artículo Ricardo Paiva · mayo 8, 2024 1m read

Preguntas Frecuentes de InterSystems

Si necesita migrar su servidor por algún motivo, se puede reducir el trabajo de configuración del nuevo entorno. Bastará copiar la información de configuración del entorno previo al nuevo entorno. 

Se puede migrar la siguiente información de configuración.

  • iris.cpf
  • configuración del SQL gateway 
  • configuración del web gateway *Nota 1
  • rutinas de usuario, etc... almacenadas en la base de datos IRISSYS *Nota 2
  • configuración de seguridad 
  • configuración de tareas
0
0 106
Artículo Ricardo Paiva · mayo 2, 2024 2m read

Preguntas frecuentes de InterSystems

Este error ocurre cuando una instancia de la clase ya está abierta en el momento de la compilación.

Hay dos formas de abordar este problema:

  1. Terminar el proceso o aplicación que tiene la instancia abierta
  2. Opciones de compilación en el menú de compilación de Studio: marque el indicador de compilación "Compilar clases en uso" y compile.

Si desea determinar qué proceso está utilizando la clase, pruebe la rutina de ejemplo siguiente.

0
0 106
Artículo Alberto Fuentes · ene 11, 2024 2m read

¿Alguna vez habéis estado editando ficheros en VS Code, pero necesitábais comprobar el valor de un global o ejecutar algunos comandos de ObjectScript? Ahora podéis hacerlo, sin necesidad de configuración! Si tenéis la versión 2.10.0 o posterior de la extensiónvscode-objectscript y estáis conectados a InterSystems IRIS 2023.2 o posterior, ahora podéis abrir una conexión del terminal a vuestro servidor, sin importar dónde se encuentre.

Hay tres formas de abrir este nuevo terminal:

1
0 262
Artículo Ricardo Paiva · ene 29, 2024 2m read

Preguntas frecuentes de InterSystems

Para resolver el error <PROTECT>, hay que eliminar el atributo de solo lectura de la base de datos de la biblioteca de todo el sistema (IRISLIB para InterSystems IRIS, CACHELIB para Caché/Ensemble/HealthShare (basado en Caché))

Una vez se haya terminado de importar la rutina, hay que acordarse de volver a cambiarla a solo lectura.
 

[Versión 2013.1 y superior]
[Portal de Gestión] > [Administración] > [Configuración] > [Configuración de Sistema] > [Bases de Datos Local] Desmarcad "Mount Read-Only" (Montar solo lectura) en el enlace del nombre de la base de datos.

0
0 115
Artículo Luis Angel Pérez Ramos · ene 29, 2024 4m read

Preguntas frecuentes de InterSystems

Si el sistema no se para durante 24 horas, los archivos journal serán eliminados a las 0:30 según la "Configuración de la eliminación de archivos journal".

Una posible causa de que los archivos journal permanezcan más tiempo del establecido en la "Configuración de la eliminación de archivos journal" es que hay transacciones que permanecen abiertas.

En ese caso, se podrá eliminar el archivo journal buscando procesos que estén ejecutando transacciones y finalizando las transacciones.

1
0 134
Artículo Ricardo Paiva · ene 16, 2024 2m read

Preguntas frecuentes de InterSystems

Si se establece una relación y hay una gran cantidad de n en una proporción de 1:n, se puede consumir una gran cantidad de memoria debido al procesamiento secuencial de la relación.

Después de hacer referencia a un objeto de muchos lados en un programa y cambiarlo internamente, simplemente liberar la variable que contiene el OREF (eliminarla, establecer otro valor, etc.) no liberará el objeto de muchos lados ni el objeto de relación. Ésta es la causa.

0
0 74
Artículo Daniel Aguilar · dic 11, 2023 1m read

Preguntas frecuentes de InterSystems

La cache de las consultas SQL puede ser purgada mediante programación usando el método Purge* de la clase %SYSTEM.SQL.

*Para ver el detalle de cada uno de los métodos, por favor consulta los siguientes enlaces:

%SYSTEM.SQL class【IRIS】

%SYSTEM.SQL class

① Comando para borrar todas las consultas SQL cacheadas en el sistema

Do $SYSTEM.SQL.PurgeAllNamespaces()


② Comando para borrar las consultas SQL cacheadas en el namespace actual

0
0 116
Artículo Ricardo Paiva · dic 7, 2023 1m read

Preguntas frecuentes de InterSystems

Cuando ejecutéis comandos del SO, utilizad el comando $ZF(-100).

do$ZF(-100,"",program,args) // Execute the Windows command [synchronously].
do$ZF(-100,"/ASYNC",program,args) // Executes a Windows command [asynchronously].

Cuando ejecutéis comandos de la shell del SO, como mkdir o copy, hemos de especificar /SHELL.

do$zf(-100,"/shell /async","mkdir","c:\temp\x")
0
0 81
Artículo Luis Angel Pérez Ramos · dic 5, 2023 3m read

Preguntas frecuentes de InterSystems

Las definiciones de clases creadas por los usuarios se almacenan en clases de definición de clases. Estas se pueden utilizar para obtener una lista de definiciones de clases desde un programa.

Nota: Las clases de definición de clase se refieren a todas las clases contenidas en el paquete %Dictionary.

En el siguiente código de muestra, se obtiene una lista de definiciones de clases utilizando la consulta Resumen de la clase %Dictionary.ClassDefinitionQuery.

0
0 102
Artículo Ricardo Paiva · dic 4, 2023 2m read

Preguntas frecuentes de InterSystems

Para crear un error definido por el usuario, hemos de preparar un XML que describa el código de error y el mensaje correspondiente que desea utilizarse como error definido por el usuario.

Hemos de establecer el código de error como un número entero negativo.

<?xml version="1.0" encoding="UTF-8"?> 
<MsgFileLanguage="en"><MsgDomainDomain="UserErrors"><MessageId="-111"Name="MyError">An error has occured</Message> 
    <MessageId="-222"Name="MyError2">An error has occured 2</Message> 
  </MsgDomain></MsgFile>
0
0 105
Artículo Daniel Aguilar · nov 25, 2023 1m read

Preguntas frecuentes de InterSystems

Puedes establecer el tamaño máximo de la base de datos IRISTemp en el arranque de IRIS configurando el parámetro MaxIRISTempSizeAtStart.

Después de configurarlo, el sistema truncará IRISTemp al valor establecido (MB) en el siguiente inicio de IRIS. Si el tamaño actual es inferior al especificado MaxIRISTempSizeAtStart, no realizará el truncado. Si se especifica el valor 0 no se realizará el truncado nunca.

Puedes configurarlo en el siguiente menú.

1
0 94
Artículo Ricardo Paiva · nov 23, 2023 2m read

Preguntas frecuentes de InterSystems

Para ejecutar un backup online desde un comando, se puede utilizar la rutina API BACKUP^DBACK.

Este es un ejemplo de realización de un backup completo.

set  status = $$ BACKUP ^DBACK( "" , "F" , "full backup" , "c:\backup\full.cbk" , "Y" , "c:\backup\full-log.log" , " NOINPUT" , "Y" , "Y" , "" , "" )

El valor de retorno es 1 si el backup se realiza con éxito, y 0 si el backup no se realiza correctamente. Por favor, consultad el fichero log para conocer más detalles sobre el fallo.

0
0 72
Artículo Ricardo Paiva · nov 16, 2023 3m read

Preguntas frecuentes de InterSystems

Para rutinas (*.mac)

Se puede ocultar el código fuente exportando/importando solo el *.obj que se genera después de compilar el programa fuente.

El ejemplo de ejecución de comandos especifica EX1Sample.obj y EX2Sample.obj, que se generan al compilar EX1Sample.mac y EX2Sample.mac, como destinos de exportación y los exporta al segundo archivo de argumentos.

Después de pasarlo a otro namespace, se usa el archivo XML exportado para realizar la importación.

0
0 111
Artículo Ricardo Paiva · nov 8, 2023 2m read

Preguntas frecuentes de InterSystems

La información sobre las propiedades definidas en una clase se puede obtener usando las siguientes clases del sistema:

%Dictionary.ClassDefinetion

%Dictionary.PropertyDefinition

El ejemplo de descripción del código es el siguiente.

0
0 134
Artículo Ricardo Paiva · nov 2, 2023 2m read

Preguntas Frecuentes de InterSystems

El significado de cada valor de tiempo de espera es el siguiente.

1. [Tiempo de espera de respuesta del servidor]

Si el procesamiento de IRIS/Caché (ejecución de rutina o consulta) no finaliza dentro de este tiempo establecido, el navegador devolverá un error.

Por ejemplo, si este valor es 60 segundos y se necesitan 90 segundos para ejecutar una rutina/método/consulta, se producirá un error.

0
0 117
Artículo Ricardo Paiva · oct 31, 2023 2m read

Preguntas frecuentes de InterSystems

Una herramienta (utilidad ^GLOBUFF) está disponible para verificar el uso de la memoria caché de la base de datos para cada global.

La utilidad se puede ejecutar directamente o mediante programación en el namespace %SYS .

Así se ejecutaría directamente:

0
0 113
Artículo Ricardo Paiva · oct 20, 2023 1m read

Preguntas frecuentes de InterSystems

ObjectScript permite pasar cualquier número de argumentos utilizando arrays. Se hace añadiendo ... después del nombre del argumento.

Os muestro un ejemplo. En la sentencia del ejemplo, la información del argumento se establece en una variable global (una variable almacenada en la base de datos) para que pueda ser fácilmente verificada después de que se ejecute el método.

Class TEST.ARGTEST1 Extends%RegisteredObject
{
ClassMethod NewMethod1(Arg... As %StringAs %Boolean
{
 kill ^a
 merge ^a = Arg
}
}
0
0 120
Artículo Ricardo Paiva · oct 12, 2023 2m read

Preguntas frecuentes de InterSystems

En el siguiente ejemplo, un archivo de imagen se codifica en una cadena Base64 en una propiedad de clase, se guarda, se decodifica la cadena en Base64 y se restaura en otro archivo.

【Classe ejemplo】

Class User.test Extends %Persistent
{
Property pics As %GlobalBinaryStream;
}


【Cuando se importa】

0
0 296
Pregunta Jose-Tomas Salvador · oct 21, 2022

Buenos días, tardes, noches,... wink

Una pequeña reflexión/pregunta para hoy... es una realidad que las nuevas versiones de IRIS for Health son cada vez más potentes en cuanto a capacidades FHIR. Permiten consumir recursos FHIR con extrema facilidad, podemos crear conexiones con end-points de servidores FHIR externos muy facilmente y hacer que IRIS actúe de passthrough o que consuma esos recursos... o, más aún, podemos definir y poner en funcionamiento un repositorio FHIR, literalmente, en menos de 5 minutos.

Sin embargo, hay una cosa que echo en falta en proyectos de tipo FHIR Façade, cuando tenemos que implementar una capa FHIR sobre un sistema que "no habla" FHIR. Se trata de la posiblidad de tener ayuda en nuestro IDE (Studio o VS Code) a la hora de codificar la lógica que crearía el o los objetos dinámicos (%DynamicObject) que representan los recursos FHIR que queremos definir...

3
0 128