查找

Article
· 9 hr ago 3m read

Questionário Facilitado – com IRIS, FHIR SQL Builder e Pesquisa Vetorial

No cenário atual de dados de saúde, o FHIR se tornou o padrão para a troca de dados clínicos estruturados. No entanto, embora o FHIR se destaque em interoperabilidade, seu formato JSON torna a análise desafiadora — incluindo os FHIR QuestionnaireResponse.

Este projeto demonstra como transformar dados de FHIR QuestionnaireResponse de JSON aninhado em tabelas SQL relacionais e embeddings vetoriais. Ao integrar o InterSystems IRIS FHIR SQL Builder e Vector Search, desbloqueamos o significado semântico por trás das respostas dos pacientes.

Três Etapas para Construí-lo

1. Projetar e Coletar o Questionário

Comece projetando um questionário FHIR usando o National Library of Medicine(NLM) Form Builder. Esta ferramenta ajuda a criar formulários clínicos estruturados que seguem os padrões FHIR. Neste projeto, 100 respostas sintéticas de pacientes foram coletadas e salvas como arquivo JSON FHIR QuestionnaireResponse, prontas para serem importadas em um servidor FHIR.

 

2. Transformar e Consultar os Dados do Questionário via SQL

Após carregar os recursos FHIR QuestionnaireResponse no servidor, use o InterSystems IRIS FHIR SQL Builder para criar automaticamente tabelas SQL relacionais. Isso “achata” a estrutura JSON aninhada, permitindo uma análise fácil dos dados do questionário com SQL padrão — tudo configurável em apenas alguns cliques.

  • Consulte o README para a configuração completa do FHIR SQL Builder.
  • A tabela SQL gerada a partir dos dados do QuestionnaireResponse está pronta para consultas e análises.

 

3. Adicione Vector Search para Compreensão Semântica

Finalmente, integre o IRIS Vector Search para adicionar inteligência semântica sobre os dados estruturados do questionário. Isso permite que os usuários busquem e interajam com as respostas do questionário com base no significado e contexto, em vez de palavras exatas, transformando os dados em uma ferramenta mais intuitiva e inteligente.

       Exemplos:

  • Uma busca por “medicação para diabetes” recupera respostas que mencionam medicamentos como metformina, insulina glargina ou acarbose — mesmo que a frase exata não esteja presente. 
  • Quando um usuário pergunta: “Quais pacientes têm histórico familiar de doenças cardíacas e tomam medicação para reduzir o colesterol?”, o sistema conecta semanticamente os dados relacionados — associando condições cardíacas a medicamentos como propranolol, espironolactona ou atorvastatina — e produz um resumo conciso dos pacientes em risco.

Para explorar o fluxo completo de trabalho e a implementação do código, visite Open Exchange.

Principais Conclusões

Por meio de três etapas principais — projetar questionários com o NLM Form Builder, transformá-los em tabelas SQL e aprimorá-los com pesquisa vetorial — esse fluxo de trabalho transforma os dados de FHIR QuestionnaireResponse em uma ferramenta poderosa para compreensão clínica e suporte à decisão.

 

Referências

1. National Library of Medicine (NLM) Form Builder 

2. InterSystems IRIS For Health FHIR SQL Builder 

3. InterSystems IRIS Vector Search 

4. https://openexchange.intersystems.com/package/iris-fhirsqlbuilder

5. https://www.youtube.com/watch?v=ewxyh2XNLv0

Discussion (0)1
Log in or sign up to continue
Article
· 9 hr ago 4m read

Criando FHIR responses com a produção de Interoperabilidade do IRIS

Quando criamos um repositório FHIR no IRIS, temos um endpoint para acessar informações, criar novos recursos, etc. Mas existem alguns recursos no FHIR que provavelmente não teremos em nosso repositório, por exemplo, o recurso Binary (esse recurso retorna um documento, como um PDF, por exemplo).

Criei um exemplo em que, quando um recurso Binary é solicitado, o endpoint FHIR retorna uma resposta como se ele existisse no repositório.

Antes de tudo, precisamos de um Namespace e de um endpoint FHIR. Depois disso, precisamos configurar uma produção de Interoperabilidade que será conectada ao endpoint FHIR. Essa produção deve ter estes itens:

  • Business Operations:
    • HS.Util.Trace.Operations (na verdade, isso é opcional, mas pode ser muito útil)
    • HS.FHIRServer.Interop.Operation, com a propriedade TraceOperations definida como *FULL*
  • Business Service:
    • HS.FHIRServer.Interop.Service, com a propriedade TraceOperations definida como *FULL* e o Target Config Name definido como o nome do HS.FHIRServer.Interop.Operation

Isso é como a produção irá se parecer:

Após criar essa produção, precisamos conectá-la ao endpoint FHIR. Então, edite o endpoint FHIR e defina o parâmetro Service Config Name com o nome do Business Service:

Agora, se começarmos a enviar requisições para o repositório FHIR, veremos todos os rastreamentos no Message Viewer:

Agora podemos ter um Business Process para controlar o que fazer com caminhos específicos.

Neste exemplo, temos um Business Process que recebe todas as requisições (agora o Business Service está conectado a esse Business Process, em vez do Business Operation) e 2 novos Business Operations que executam outras ações que serão explicadas depois:

Vamos das uma olhada no Business Process FHIRRouter:

Se olharmos com atenção, veremos que, se o RequestPath contiver "Binary/", então faremos algo com essa requisição: gerar nossa resposta Binary personalizada. Caso contrário, enviaremos a requisição diretamente para o repositório FHIR.

Vamos dar uma olhada na sequência chamada "Generate Binary":

Antes de tudo, criamos uma nova instância de HS.FHIRServer.Interop.Response. E obtemos o ID do documento a partir do Request Path. Como? Toda vez que alguém quiser um recurso Binary, ele deve ser solicitado com o ID do documento no caminho da URL, algo como: ..../fhir/r4/Binary/XXXXX. Então extraímos o ID do documento do Request Path com esta expressão:

$Replace(request.Request.RequestPath,"Binary/","")

(Não é muito elegante, mas funciona).

Se tivermos um ID de documento, então fazemos uma chamada a um Business Operation chamado Find para localizar o nome do arquivo associado a esse ID de documento:

 

Na verdade, esse Business Operation Find sempre retorna o mesmo nome de arquivo:

É um exemplo do que podemos fazer.

Se tivermos um nome de arquivo, então chamamos outro Business Operation chamado File para obter o conteúdo desse arquivo, codificado em base64:

E, finalmente, podemos retornar 2 tipos de respostas:

  • Se não tivermos o conteúdo do arquivo (porque não temos um ID de documento ou não encontramos o nome do arquivo ou conteúdo associado), retornamos uma resposta 404, com esta resposta personalizada:
 set json = {
    "resourceType": "OperationOutcome",
    "issue": [
        {
            "severity": "error",
            "code": "not-found",
            "diagnostics": "<HSFHIRErr>ResourceNotFound",
            "details": {
                "text": "No resource with type 'Binary'"
            }
        }
    ]
 }
 set json.issue.%Get(0).details.text = json.issue.%Get(0).details.text_" and id '"_context.docId_"'"
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"
  • Se tivermos o conteúdo do arquivo, então retornamos uma resposta 200 com esta resposta personalizada:
 set json = {
  "resourceType": "Binary",
  "id": "",
  "contentType": "application/pdf",
  "securityContext": {
    "reference": "DocumentReference/"
  },
  "data": ""
 }
 set json.id = context.docId
 set json.securityContext.reference = json.securityContext.reference_json.id
 set json.data = context.content.Read(context.content.Size)
 
 set qs = ##class(HS.SDA3.QuickStream).%New()
 do qs.Write(json.%ToJSON())
 set response.QuickStreamId = qs.%Id()
 set response.ContentType = "application/fhir+json"
 set response.CharSet = "UTF-8"

 

O ponto-chave aqui é criar um HS.SDA3.QuickStream, que contém o objeto JSON. E adicionar esse QuickStream à resposta.

E agora, se testarmos nosso endpoint, ao solicitar um documento Binary, veremos a resposta:

E se solicitarmos um documento Binary que não existe (você pode testar passando nenhum ID de documento), veremos a resposta 404:

Em resumo, conectando nosso endpoint FHIR com a interoperabilidade, podemos fazer o que quisermos, aproveitando todas as capacidades do InterSystems IRIS.

Discussion (0)1
Log in or sign up to continue
Question
· 11 hr ago

Does %XML.Security.Signature require a pre-existing <Signature> element when signing an XML document

I’m working on XML Digital Signature in InterSystems IRIS using %XML.Security.Signature

I start with an XML document that is created by parsing an input XML string, and I want to digitally sign this document using an X509 certificate.

Set x509 = ##class(%SYS.X509Credentials).GetByAlias(credAlias)
Set signature = ##class(%XML.Security.Signature).CreateX509(x509,$$$SOAPWSIncludeNone ,$$$KeyInfoX509Certificate)

Set signature.Id = "SIG1"
DO signature.SetSignatureMethod($$$SOAPWSrsasha1)
DO signature.SetDigestMethod($$$SOAPWSsha1)
Set signature.SignedInfo.CanonicalizationMethod.Algorithm=$$$SOAPWSc14n

Set ref = ##class(%XML.Security.Reference).Create("", $$$SOAPWSEnvelopedSignature_","_$$$SOAPWSc14n)
Do signature.AddReference(ref)

Set sc = signature.SignDocument(document)

During signing, I got the below error:

Canonicalize error: Signature not found

From debugging, it appears that the signing process attempts to locate a <Signature> element in the XML document by its Id, but no such element exists at that point.

This leads to my main question:

Is it expected that XML doc already contains a <Signature> element including <SignedInfo>, <Reference>etc. before calling the SignDocument()

For example, do I need to manually add a skeleton like the following to the XML document prior to signing?

 <Signature Id="SIG1">
    <SignedInfo>
      <CanonicalizationMethod
        Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
      <SignatureMethod
        Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
      <Reference URI="">
        <Transforms>
          <Transform
            Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature" />
          <Transform
            Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315" />
        </Transforms>
        <DigestMethod
          Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
        <DigestValue></DigestValue>
      </Reference>
    </SignedInfo>
    <SignatureValue></SignatureValue>
    <KeyInfo>
      <X509Data>
        <X509Certificate></X509Certificate>
      </X509Data>
    </KeyInfo>
  </Signature>

If a pre-existing signature skeleton is not required, could someone clarify the correct and supported workflow for signing an XML document using %XML.Security.Signature?

Any guidance or examples would be greatly appreciated.

1 new Comment
Discussion (1)1
Log in or sign up to continue
Digest
· 12 hr ago
Article
· 14 hr ago 3m read

Aspectos destacados de OAuth para FHIR (2024.3+) – Guía rápida para nuevos clientes

También en versiones anteriores podíais definir vuestro servidor FHIR para aceptar solicitudes mediante OAuth 2.0 (por ejemplo, para un cliente SMART on FHIR), pero hoy en día, con la versión v2024.3, que se lanzó hace ya un tiempo, existe una nueva funcionalidad que permite hacerlo de forma más sencilla: el OAuth FHIR Client QuickStart.

Este “QuickStart” es un asistente tipo wizard que os permite conectar vuestro servidor FHIR a un servidor OAuth y habilitar la autenticación y autorización OAuth para las solicitudes FHIR en 5 sencillos pasos (en realidad, solo 3…).

  • Paso 1 – Crear o elegir un servidor FHIR

Puede que ya tengáis un servidor FHIR (endpoint) definido, o puede que todavía no hayáis definido ninguno y queráis hacerlo ahora como parte de este QuickStart.

  • Paso 2 – Seleccionar servidor FHIR

Si elegisteis “Usar uno existente”, se os mostrarán los endpoints disponibles por namespace. Por ejemplo:

Si elegís “Crear nuevo”, se os mostrará un pequeño formulario para crear un nuevo endpoint.

Esto es similar a lo que veríais si crearais el endpoint previamente por vuestra cuenta:

  • Paso 3 – Seleccionar el tipo de servidor OAuth

Podéis elegir usar un servidor OAuth externo (por ejemplo, Auth0 de Okta) o utilizar el servidor OAuth integrado en InterSystems IRIS.

Si queréis usar IRIS como vuestro servidor OAuth, necesitaréis configurar IRIS como un servidor OAuth que soporte FHIR. También disponéis de un “atajo” para ello: un método que podéis llamar y que realizará esta configuración por vosotros.

Tened en cuenta que es necesario configurar la comunicación segura para que esto funcione.

  • Paso 4 – Configurar el servidor OAuth

Si elegisteis usar un servidor OAuth externo, se os pedirá que indiquéis su Issuer Endpoint:

Si ya habíais definido uno, podéis seleccionarlo del desplegable; si no, podéis escribirlo (o pegarlo).

En cualquier caso, podéis probar este endpoint del servidor OAuth, por ejemplo:

  • Paso 5 (o 4 si elegisteis el servidor OAuth interno de IRIS) – Confirmar

Veréis una breve información de confirmación y un botón “Confirmar”.

Por ejemplo (al elegir crear un nuevo servidor FHIR y usar el servidor OAuth interno de IRIS):

O por ejemplo (al elegir un endpoint FHIR existente y un servidor OAuth externo):

Si todo va bien, veréis un mensaje indicando que se creó correctamente.

Si no, recibiréis un mensaje adecuado.

Entre bastidores, deberíais poder observar algunas cosas:

  • Veréis el cliente definido dentro de los clientes OAuth (con sus detalles):

  • Veréis el cliente definido en vuestro endpoint FHIR:

  • En la sección general de Seguridad del Management Portal, bajo OAuth 2.0, también podréis encontrar una Definición de Cliente con su Configuración de Cliente.

Suponiendo que todo lo anterior funcione, podéis comenzar a usar OAuth (y específicamente SMART on FHIR) para comunicaros con vuestro servidor FHIR.

Más sobre esto… en un artículo futuro…

Discussion (0)1
Log in or sign up to continue