Pesquisar

Artigo
· 1min atrás 15min de leitura

Implementing openEHR with IRIS for Health

Does your blood run cold when you hear about openEHR? Do archetypes give you goosebumps?

Overcome your fears with this article and master OpenEHR using the capabilities of InterSystems IRIS for Health!

What is openEHR?

openEHR is an open, vendor-neutral specification designed to represent, store, and exchange clinical information in a semantically rich and long-term sustainable way. Instead of defining fixed message structures (as many interoperability standards do) OpenEHR separates clinical knowledge from technical implementation through a multi-layered modelling approach.

At its core, openEHR relies on three fundamental concepts:

  • Reference Model (RM)
    A model that defines the core structures used in health records, such as Compositions, Entries, Observations, Evaluations, and Actions. The RM is deliberately generic and technology-agnostic.
  • Archetypes
    Machine-readable models (expressed in ADL) that define the detailed clinical semantics for a specific concept, such as a blood pressure measurement or a discharge summary. Archetypes constrain the RM and provide a reusable clinical vocabulary.
  • Templates (OPT files)
    Specializations built on top of archetypes. Templates tailor archetypes to a specific use case, system, or form (for example, a vital signs template, or a regional discharge note). Templates eliminate optionality and produce operational definitions that systems can safely implement.

Let's see an example of a RAW file base on a Composition (in JSON):

{
  "_type": "COMPOSITION",
  "archetype_node_id": "openEHR-EHR-COMPOSITION.diagnostic_summary.v1",
  "archetype_details": {
    "_type": "ARCHETYPED",
    "archetype_id": {
      "_type": "ARCHETYPE_ID",
      "value": "openEHR-EHR-COMPOSITION.diagnostic_summary.v1"
    },
    "template_id": {
      "_type": "TEMPLATE_ID",
      "value": "ES - AP - Diagnoses and treatment"
    },
    "rm_version": "1.0.4"
  },
  "uid": {
    "_type": "OBJECT_VERSION_ID",
    "value": "diag-1003::ehr.local::1"
  },
  "name": {
    "_type": "DV_TEXT",
    "value": "Summary of diagnoses and treatment – Moderate COPD"
  },
  "language": {
    "_type": "CODE_PHRASE",
    "terminology_id": {
      "_type": "TERMINOLOGY_ID",
      "value": "ISO_639-1"
    },
    "code_string": "es"
  },
  "territory": {
    "_type": "CODE_PHRASE",
    "terminology_id": {
      "_type": "TERMINOLOGY_ID",
      "value": "ISO_3166-1"
    },
    "code_string": "ES"
  },
  "category": {
    "_type": "DV_CODED_TEXT",
    "value": "event",
    "defining_code": {
      "_type": "CODE_PHRASE",
      "terminology_id": {
        "_type": "TERMINOLOGY_ID",
        "value": "openehr"
      },
      "code_string": "433"
    }
  },
  "composer": {
    "_type": "PARTY_IDENTIFIED",
    "name": "Dr. García"
  },
  "context": {
    "_type": "EVENT_CONTEXT",
    "start_time": {
      "_type": "DV_DATE_TIME",
      "value": "2025-11-22T08:45:00Z"
    },
    "setting": {
      "_type": "DV_CODED_TEXT",
      "value": "primary medical care",
      "defining_code": {
        "_type": "CODE_PHRASE",
        "terminology_id": {
          "_type": "TERMINOLOGY_ID",
          "value": "openehr"
        },
        "code_string": "228"
      }
    }
  },
  "content": [
    {
      "_type": "SECTION",
      "archetype_node_id": "openEHR-EHR-SECTION.diagnoses_and_treatments.v1",
      "name": {
        "_type": "DV_TEXT",
        "value": "Respiratory diagnosis and treatment"
      },
      "items": [
        {
          "_type": "EVALUATION",
          "archetype_node_id": "openEHR-EHR-EVALUATION.problem_diagnosis.v1",
          "name": {
            "_type": "DV_TEXT",
            "value": "Moderate COPD"
          },
          "archetype_details": {
            "_type": "ARCHETYPED",
            "archetype_id": {
              "_type": "ARCHETYPE_ID",
              "value": "openEHR-EHR-EVALUATION.problem_diagnosis.v1"
            },
            "template_id": {
              "_type": "TEMPLATE_ID",
              "value": "ES - AP - Diagnoses and treatment"
            },
            "rm_version": "1.0.4"
          },
          "language": {
            "_type": "CODE_PHRASE",
            "terminology_id": {
              "_type": "TERMINOLOGY_ID",
              "value": "ISO_639-1"
            },
            "code_string": "es"
          },
          "encoding": {
            "_type": "CODE_PHRASE",
            "terminology_id": {
              "_type": "TERMINOLOGY_ID",
              "value": "IANA_character-sets"
            },
            "code_string": "UTF-8"
          },
          "subject": {
            "_type": "PARTY_SELF"
          },
          "data": {
            "_type": "ITEM_TREE",
            "archetype_node_id": "at0001",
            "name": {
              "_type": "DV_TEXT",
              "value": "Diagnostic data"
            },
            "items": [
              {
                "_type": "ELEMENT",
                "archetype_node_id": "at0002",
                "name": {
                  "_type": "DV_TEXT",
                  "value": "Diagnosis description"
                },
                "value": {
                  "_type": "DV_TEXT",
                  "value": "Moderate COPD with exertional dyspnoea."
                }
              },
              {
                "_type": "ELEMENT",
                "archetype_node_id": "at0003",
                "name": {
                  "_type": "DV_TEXT",
                  "value": "Diagnosis code"
                },
                "value": {
                  "_type": "DV_CODED_TEXT",
                  "value": "J44.1",
                  "defining_code": {
                    "_type": "CODE_PHRASE",
                    "terminology_id": {
                      "_type": "TERMINOLOGY_ID",
                      "value": "ICD-10"
                    },
                    "code_string": "J44.1"
                  }
                }
              },
              {
                "_type": "ELEMENT",
                "archetype_node_id": "at0004",
                "name": {
                  "_type": "DV_TEXT",
                  "value": "Onset date"
                },
                "value": {
                  "_type": "DV_DATE_TIME",
                  "value": "2020-09-15T00:00:00Z"
                }
              }
            ]
          }
        },
        {
          "_type": "EVALUATION",
          "archetype_node_id": "openEHR-EHR-EVALUATION.medication_summary.v1",
          "name": {
            "_type": "DV_TEXT",
            "value": "Inhaled treatment for COPD"
          },
          "archetype_details": {
            "_type": "ARCHETYPED",
            "archetype_id": {
              "_type": "ARCHETYPE_ID",
              "value": "openEHR-EHR-EVALUATION.medication_summary.v1"
            },
            "template_id": {
              "_type": "TEMPLATE_ID",
              "value": "ES - AP - Diagnoses and treatment"
            },
            "rm_version": "1.0.4"
          },
          "language": {
            "_type": "CODE_PHRASE",
            "terminology_id": {
              "_type": "TERMINOLOGY_ID",
              "value": "ISO_639-1"
            },
            "code_string": "es"
          },
          "encoding": {
            "_type": "CODE_PHRASE",
            "terminology_id": {
              "_type": "TERMINOLOGY_ID",
              "value": "IANA_character-sets"
            },
            "code_string": "UTF-8"
          },
          "subject": {
            "_type": "PARTY_SELF"
          },
          "data": {
            "_type": "ITEM_TREE",
            "archetype_node_id": "at0001",
            "name": {
              "_type": "DV_TEXT",
              "value": "Associated medication tree"
            },
            "items": [
              {
                "_type": "ELEMENT",
                "archetype_node_id": "at0002",
                "name": {
                  "_type": "DV_TEXT",
                  "value": "Medication associated with the diagnosis"
                },
                "value": {
                  "_type": "DV_TEXT",
                  "value": "Inhaled salbutamol 100 mcg as needed; inhaled tiotropium 18 mcg every 24 hours."
                }
              }
            ]
          }
        }
      ]
    }
  ]
}

This layered modelling approach enables openEHR systems to remain stable over years—even decades—while allowing clinical models to evolve independently from the underlying software platform.

A key piece of the openEHR ecosystem is AQL (Archetype Query Language), the standard query language used to retrieve clinical data stored in openEHR repositories.

Archetype Query Language (AQL)

AQL is inspired by SQL but adapted to the openEHR information model. Instead of querying relational tables, AQL allows developers to query structured clinical content inside openEHR Compositions, taking advantage of archetype paths.

Key characteristics of AQL

  • Path-based querying: AQL uses archetype paths (similar to XPath) to navigate the internal structure of a Composition, such as:
    /content[openEHR-EHR-OBSERVATION.blood_pressure.v1]/data/events/time
  • Clinical semantic awareness: Queries refer to clinical concepts (archetypes, entry types, data points) rather than database column names.
  • Flexible WHERE clauses: AQL supports filtering on values within Compositions, e.g. systolic blood pressure > 140 or diagnoses matching a specific code.
  • Multi-composition queries: It can retrieve data across multiple Compositions, for example all Observations for a given patient over time.
  • Vendor-neutral: Any openEHR implementation that supports AQL should, in principle, accept the same queries.

Let's see an example of AQL:

SELECT
    c/uid/value AS composition_id,
    o/data[at0001]/events[at0006]/data[at0003]/value/magnitude AS systolic,
    o/data[at0001]/events[at0006]/data[at0004]/value/magnitude AS diastolic
FROM
    EHR e
    CONTAINS COMPOSITION c
    CONTAINS OBSERVATION o[openEHR-EHR-OBSERVATION.blood_pressure.v1]
WHERE
    e/ehr_id/value = '12345'
AND
    o/data[at0001]/events[at0006]/time/value > '2023-01-01T00:00:00Z'

OpenEHR - FHIR comparation

Technically speaking, OpenEHR and FHIR are very very similar. Information based in documental format, API REST, etc. Let's see the main concepts of FHIR and OpenEHR and its correlation:

What do we need to implement openEHR in IRIS for Health?

RAW Composition Storage

  • Store incoming Compositions in RAW JSON or XML exactly as received.
  • No transformation should modify semantic content.
  • For our example we are going to work with JSON format, but there are multiple options.

REST API Services

Our implementation has to expose the following API REST:

EHR Services

To create and locate a patient's "history."

  • POST /ehr: Creates a new EHR.
  • GET /ehr/{ehr_id}: Retrieve EHR metadata.
  • GET /ehr?subject_id=?: Locate an EHR based on external identifiers.

Composition Services

To store patient's clinical information.

  • POST /ehr/{id}/composition: Commit a new composition in RAW format. Validate against OPT when possible
  • GET /composition/{version_uid}: Retrieve a specific version.
  • GET /ehr/{id}/compositions: List compositions for an EHR.
  • DELETE /composition/{uid}: Mark composition as deleted (logical delete).

AQL Query Endpoint

  • POST /query/aql: Accept an AQL query, translate to IRIS SQL or JSON-path-based lookup and return results in openEHR canonical JSON.

RAW Composition Validation

We have to force validation of RAW compositions based on OPT2 files, we can't save in our repository any JSON that we will receive.

Implementing openEHR in IRIS for Health

Well, to implement all the functionalities available in a openEHR server will take some time, so I'm going to focus in the core functionalities:

Using web application to deploy REST API Service

To publish a REST API is straight forward, we only need two components, a class extending %CSP.REST and a new record in the list of web applications. Let's see the header of our extended %CSP.REST class:

As you can see we have defined all the minimum required routes for our repository. We have all the managament of compositions, OPT2 files for RAW validations and finally, execution of AQL queries.

For our example we are not going to define any security configuration, but JWT Authentication is recommended.

Ok, we have our class and our %CSP.REST class, what else?

RAW validations

openEHR is anything but new, so you can guess that there are multiple libraries to support some functionalities like raws validations. For this example we've used and customized Arche library, an open source library developed in Java to validate rawcompositions against OPT2 files. The validator is a jar file configured from the External Language Server (by default on docker image deployment) and invoked before to save the raw using the JavaGateway functionality:

set javaGate = $system.external.getJavaGateway()
set result = javaGate.invoke("org.validator.openehr.Cli", "validate", filePath, optPath)

If the raw is validated the JSON document will be saved into the database.

JSON raw storage

We could use DocDB, but we want to leverage the performance of SQL databases. One of the biggest problems related with openEHR is the poor performance querying documents, so we are going to pre-process the compositions to get common information to all composition types to boost queries.

Our Composition class define the following properties:

Class OPENEHR.Object.Composition Extends (%Persistent, %XML.Adaptor) [ DdlAllowed ]
{
/// Description
Property ehrId As %Integer;
Property compositionUid As %String(MAXLEN = 50);
Property compositionType As %String;
Property startTime As %DateTime;
Property endTime As %Date;
Property archetypes As list Of %String(MAXLEN = 50000);
Property doc As %String(MAXLEN = 50000);
Property deleted As %Boolean [ InitialExpression = 0 ];
Index compositionUidIndex On compositionUid;
Index ehrIdIndex On ehrId;
Index ExampleIndex On archetypes(ELEMENTS);
}
  • ehrId: with the electronic health record of the patient.
  • compositionUid: composition identifier.
  • compositionType: type of composition saved.
  • startTime: time when the composition was created.
  • archetypes: list of archetypes contained on the composition.
  • doc: JSON format document.
  • deleted: boolean value for soft deletes.

The indexes will be used to improve the queries.

AQL support

As we said before AQL is a path-based query language. How could we emulate the same behaviour in IRIS for Health? Welcome to JSON_TABLE!

What is JSON_TABLE?

The JSON_TABLE function returns a table that can be used in a SQL query by mapping JSON values into columns. Mappings from a JSON value to a column are written as SQL/JSON path language expressions.

As a table-valued function, JSON_TABLE returns a table that can be used in the FROM clause of a SELECT statement to access data stored in a JSON value; this table does not persist across queries. Multiple calls to JSON_TABLE can be made within a single FROM clause and can appear alongside other table-valued functions.

We have implemented a ClassMethod in Python to translate AQL into SQL, but there is a problem, AQL is based on relative paths of the archetypes, not in absolute paths, so we need identify the absolute path for each archetype and join it with the relative path of the AQL.

How can we know the absolute path? Very easy! We can find it when the user save the OPT2 file for the composition into IRIS! As soon as we get the absolute path we save it into a CSV file specific for the composition so, we only have to get the absolute path from the specific composition file or, if the AQL doesn't define the composition, search into the available CSV files the absolute path for the archetypes of the AQL.

Let's see how it works. Here is an example of AQL to get all the diagnosis with a specific ICD-10 code:

SELECT
  c/uid/value AS comp_uid,
  c/context/start_time/value AS comp_start_time,
  dx/data[at0001]/items[at0002]/value/value AS diagnosis_text,
  dx/data[at0001]/items[at0003]/value/defining_code/code_string AS diagnosis_code
FROM EHR e
CONTAINS COMPOSITION c[openEHR-EHR-COMPOSITION.diagnostic_summary.v1]
CONTAINS SECTION s[openEHR-EHR-SECTION.diagnoses_and_treatments.v1]
CONTAINS EVALUATION dx[openEHR-EHR-EVALUATION.problem_diagnosis.v1]
WHERE dx/data[at0001]/items[at0003]/value/defining_code/code_string
      MATCHES {'E11', 'I48.0'}
ORDER BY c/context/start_time/value DESC

The funcion Transform from OPENEHR.Utils.AuxiliaryFunctions class translates it into:

SELECT comp_uid, comp_start_time, diagnosis_text, diagnosis_code 
FROM ( 
    SELECT c.compositionUid AS comp_uid, 
        jt_root.comp_start_time AS comp_start_time, 
        jt_n1.diagnosis_text AS diagnosis_text, 
        jt_n1.diagnosis_code AS diagnosis_code 
    FROM OPENEHR_Object.Composition AS c, 
        JSON_TABLE( c.doc, '$' COLUMNS ( comp_start_time VARCHAR(4000) PATH
            '$.context.start_time.value' ) ) AS jt_root, 
        JSON_TABLE( c.doc, '$.content[*]?(@._type=="SECTION" && @.archetype_node_id==
            "openEHR-EHR-SECTION.diagnoses_and_treatments.v1").items[*]?
            (@._type=="EVALUATION" && @.archetype_node_id=="openEHR-EHR-EVALUATION.problem_diagnosis.v1")'
            COLUMNS ( 
                diagnosis_text VARCHAR(4000) PATH '$.data[*]?(@.archetype_node_id=="at0001").items[*]?
                    (@.archetype_node_id=="at0002").value.value', 
                diagnosis_code VARCHAR(255) PATH '$.data[*]?(@.archetype_node_id=="at0001").items[*]?
                    (@.archetype_node_id=="at0003").value.defining_code.code_string' ) ) AS jt_n1 
    WHERE ('openEHR-EHR-COMPOSITION.diagnostic_summary.v1' %INLIST (c.archetypes) 
        AND 'openEHR-EHR-EVALUATION.problem_diagnosis.v1' %INLIST (c.archetypes)) 
        AND (jt_n1.diagnosis_code LIKE '%E11%' OR jt_n1.diagnosis_code LIKE '%I48.0%') ) U 
ORDER BY comp_start_time DESC

Let's try our API REST with an AQL:

Success!

And now with a numeric comparation:

SELECT
  c/uid/value AS comp_uid,
  c/context/start_time/value AS comp_start_time,
  a/items[at0024]/value/magnitude AS creatinine_value,
  a/items[at0024]/value/units AS creatinine_units
FROM EHR e
CONTAINS COMPOSITION c[openEHR-EHR-COMPOSITION.lab_results_and_medications.v1]
CONTAINS OBSERVATION o[openEHR-EHR-OBSERVATION.laboratory_test_result.v1]
CONTAINS CLUSTER a[openEHR-EHR-CLUSTER.laboratory_test_analyte.v1]
WHERE a/items[at0001]/value/value = 'Creatinina (mg/dL)'
  AND a/items[at0024]/value/magnitude BETWEEN 1.2 AND 1.8
ORDER BY c/context/start_time/value DESC

Transformed into:

SELECT comp_uid, comp_start_time, ldl_value, ldl_units 
FROM ( 
    SELECT c.compositionUid AS comp_uid, jt_root.comp_start_time AS comp_start_time,
        jt_n1.ldl_value AS ldl_value, jt_n1.ldl_units AS ldl_units 
    FROM OPENEHR_Object.Composition AS c, 
        JSON_TABLE( c.doc, '$' COLUMNS ( comp_start_time VARCHAR(4000) 
            PATH '$.context.start_time.value' ) ) AS jt_root, 
        JSON_TABLE( c.doc, '$.content[*]?(@._type=="OBSERVATION" && 
            @.archetype_node_id=="openEHR-EHR-OBSERVATION.laboratory_test_result.v1")
                .data.events[*]?(@._type=="POINT_EVENT").data.items[*]?(@._type=="CLUSTER" &&
                @.archetype_node_id=="openEHR-EHR-CLUSTER.laboratory_test_analyte.v1")'
                COLUMNS ( 
                    ldl_value NUMERIC PATH '$.items[*]?
                        (@.archetype_node_id=="at0024").value.magnitude', 
                    ldl_units VARCHAR(64) PATH '$.items[*]?
                        (@.archetype_node_id=="at0024").value.units', 
                    _w1 VARCHAR(4000) PATH '$.items[*]?
                        (@.archetype_node_id=="at0001").value.value' ) ) AS jt_n1 
    WHERE ('openEHR-EHR-COMPOSITION.lab_results_and_medications.v1' %INLIST (c.archetypes) 
        AND 'openEHR-EHR-OBSERVATION.laboratory_test_result.v1' %INLIST (c.archetypes) 
        AND 'openEHR-EHR-CLUSTER.laboratory_test_analyte.v1' %INLIST (c.archetypes)) 
        AND jt_n1._w1 = 'LDL (mg/dL)' AND jt_n1.ldl_value <= 130 ) 
    U ORDER BY comp_start_time DESC

Another resounding success!

Conclusions

Well, as you can see in this example, InterSystems IRIS for Health provide to you of all the tools required to implement and deploy an openEHR repository. If you have any question don't hesitate to write a comment!

Disclaimer

The associated code is just a proof of concept, It does not aim to implement a repository with all the functionalities but to demonstrate that it is perfectly possible with InterSystems IRIS for Health. Enjoy!

Discussão (0)1
Entre ou crie uma conta para continuar
Artigo
· 3 hr atrás 7min de leitura

"Vibe coding" towards IRIS implementations?

Keywords:  Vibe coding, Windsurf, IRIS, TIE

Why not? 

Has anyone not been trying "vibe coding" so far?

Even merely 3 years ago, if anyone asked

  • "Could I do IRIS implementation for NHS TIE in English or Spanish or just Chinese ?", or
  • "Can I just instruct TIE in English to build itself an e2e route, to pick up a PDF report then turn into ORU/MDM message and submit into the PAS ?", or
  • "Could we query IRIS database in English only, and build up dashboard or ad hoc report of my own by English instructions?"

you would probably have laughed, tried not to be offended, found a chair and started to count how many man*days or man*weeks just those analysis/SoW/requirement/design/test/service docs would take, as well as hands-on engineering efforts. 

Yet as the foundation models leaping and progressing, it certainly gets more realistic by today.

I also wish to know how others are playing with it.  Below just a rushed-up casual note from myself.

Scope

  • IDE: Windsurf (yes it's still there) or Cursor etc (about 20+ popular/powerful ones now) or just VSCode with such extensions.
  • VSCode ExtensionIntersystems IRIS Extension Pack
  • TIE Server: IRIS Health Connect
  • CVS Repo: Github/Gitlab
  • OS: Windows or MacOS

Nothing unusual here. 

 

The proper approach?  

By end of 2025 the popular fashion would be "multi-agentic AI ecosystems", "Remote MCP with enterprise security", DSPy-alike features, LLMLite-alike gateways, legacy RAG or GAG, and "self-evolving systems" like AlphaEvolve style evaluators. We might need some feature engineering like them, so hope to talk more about them next time.

But in the meantime, is there also a lightweight approach with minimum engineering overhead, mostly surfing on LLM's evolving capabilities?

 

The minimalism approach?

Or, the short list in the scope might be sufficient to start with?

1. Download and install Windsurf

I happened to use Windsurf for a year now - no particular reason, but just was impressed by its auto-execution at very first try.

No - it's not fading away yet, I am still using its Pro subscription. But free version using its free models would work too.

Download Windsurf Editor and Plugins | Windsurf

When it runs 

2. Install Intersystems IRIS Extension Pack 

Various Intersystems extensions are all helpful but for this one this single pack would be sufficient to start with for all "vibe coding" needs.

3. Connect into IRIS server

Click the Intersystems icon on IDE's left toolbar, connect into an IRIS server.  Explore its namespaces, and open some Projects to explore.  

I happened to use IRIS 2022.x but newer version would all work.  

4. Move the IRIS project package(s) into workspace

Click the Explorer icon on left toolbar to open Workspace, then simply pick some IRIS project and drag-and-drop it into your local workspace within the IDE. 

This step is simple. But it helps - it would move those IRIS service items (classes, schema and lookup tables etc) into current local working folder being used by Windsurf etc, so it can find these files and start to work on them per your instructions in English etc on the right chat panel, called "Cascade" in Windsurf.

Note: this is not very tidy occasionally - you might get a lot alerts in the IDE. Hope we will have better experiences here. 

5. Start the vibe coding any tasks

Now, you can do anything with really simply or comprehensive instructions in any natural language, for any quick customer demands, brief demos, or real-world enterprise grade NHS clinical requirements. 

I normally just set the Cascade to "Code" mode instead of "Chat", then select a free LLM such as GPT5.1 ()

6. What could we try now?

Why don't we try some quick asks as listed in the initial "Why Not" use cases? Or any use case throughout release lifecycles of some real-world requirements or tasks I normally took on too, such as

  • Analysis: Ask it to conduct a comprehensive code analysis and reverse it to a detailed design or implementation guide in MD format?
  • Productisation and reusability: State your new clinical requirement, and ask it to search through all available project repo items to identify anything similar that could be reused or refactored?
  • Implementations: Ask it to do new TIE implementation for you, by stating specific requirements, such as changing PAS or RIS providers by attaching the new vendor's interface specs and sample messages? 
  • Documentation - requirement spec, design spec, test spec, plans, and services specs: Ask it to do proper requirements or architecture design docs with embedded drawings for you, per your organisation's template or outlines?
  • Development: Develop a new web app by CSP for a bespoke message search tool on IRIS, or display a nice dashboard in React then connect into IRIS?
  • Tests:  Ask to generate some auto-executable Unit/System/Integration/RFO/NFR test script coverages for you.
  • Supports:  Ask it to look into the IRIS message logs and identify issues
  • Release Management and Change Control:  Ask it periodically check in mini releases and code/config changes into GitHub or Gitlab, or any legacy CVS you got. You don't even need Git experiences - just by English to the most tricky git operations including merge?   
  • DevOps: Create a Gitlab CI pipeline that auto provisions into EKS or AKS? It could assist well too.


You can add in your own MCP servers for IRIS DB or local resources etc, or even your local RAG and KAG etc APIs wrapped in remote MCPs,  but you don't have to.  Windsurf has its own built-in "agentic AI capabilities", which are actually more generalised than normal enterprises' in-house tools. 

In today's AI/GenAI world, minimalism is not necessarily less capable than those heavily engineered or over-engineered in-house agentic AI solutions, in most real-world enterprise use cases, which turn out more costly and difficult to grow with the evolving foundation models. It probably sounds somehow similar to investments - most of the actively managed funds actually perform worse than major indexes over a relatively long period. 

6. Data Governance

Be aware of data compliance requirements as usual. A good practice is to start with your local dev instance outside controlled data environments, to make sure only codes, configs and docs are provisioned. Starts with some fun with caution - why not. 
 

7. Outcome quality

The engineering quality depends on yourself, the engineer, more than the LLM. 

One frequent quote is:  Terence Tao (a Stanford math professor) uses ChatGPT to assit him solving some real math challenges. Can we, given exactly the same tool? No, we can't.  We don't even understand the problem, let along solution approaches and options. 

The same is to Healthcare Interoperability or IRIS implementation. It won't replace anyone by today, (thank God); it only amplifies your specialty.  If you are an experienced architect, it makes you a lot more efficient - deliver a few design docs with quality in a day, rather than each in a few days or weeks, because you know what the outcomes should look like, and you own the liability. If you are a COS specialist, it can code in your style with a lot more productivity, because you may have a lot reusable code repos of high quality from the past; you are able to break down its action plans in good details; and you know its code quality; you know whether it's on the right or wrong path immediately.  It's your amplifier. 

 

Reflections?

  • "Vibe coding" is not about vibe, depending on how you use it. It has no problem in delivering enterprise qualities, the same as any other tools/approaches.  
  • Intelligence is being outsourced now, just like Computation was being outsourced 15 years ago. It sounds scary. It's another topic whether we trust that a handful of unicorns actually own the "Intelligence as a Service" for everybody. 
  • AI/GenAI starts to bridge up the abyss among human and machine languages. That opens all possibilities - some would sound crazy. 
  • This post doesn't touch on the self-evolving software yet. Yet again, it would still depend on our own optimisation targets; your own capability. 
  • By today it still doesn't do COS as well as you would hope (it's not LLM's fault - don't blame it). But LLM also turns out to be a pretty good logical abstractor, so if you have established code bases with good quality, ask it to reuse/refactor/refer to them.  It worked well for me. 
  • Don't over-engineer in-house solutions - think more about strategy while still diving-in for fun.  Minimalism is not necessarily less effective or less capable than over-engineered agentic solutions in today's AI/GenAI world. Sometimes we want to build the boats that surf the seas and get us somewhere, instead of creating rigid structures stuck on the sea bed waiting for being submerged by rising tides, particualrly when today's transformer-based LLMs are still bad at engineering certainty and consistency.  The same caution goes with fine-tuned LLM/SLMs for IRIS COS - it's fun and could be reffective but possibly not very economical to maintain over the long term. 


Apologies in advance if anyone else mentioned the above already. It might look too simple, too bare and too basic to start with, without any fancy tricks. I had many discussions on these topics, so think it might be helpful to record them so don't have to repeat them in every chat.

Anyway.  It's pretty hard today to identify anything that can't be assited by AI at all; and it's certainly one of the few posts I ever typed in compltely manually over the past 2-3 years.    


I assume the 10 means 10 year anniversary - congratulations. This is certainly one of my favorite community - found quick answers to so many issues, and a lot easier to edit/publish some quick notes than Medium. 

  

Discussão (0)2
Entre ou crie uma conta para continuar
Artigo
· 3 hr atrás 4min de leitura

Scripting com .Net Core 10 e IRIS SDK

Um dos recursos mais recentes do .Net Core 10 com C# 14 são os aplicativos baseados em arquivo. Este recurso permite que você execute código C# em um arquivo .cs simples, sem a necessidade de criar uma solution, um projeto ou qualquer uma das estruturas relacionadas.

Por exemplo, você pode criar um arquivo script.cs usando o bloco de notas com o seguinte conteúdo:

Console.WriteLine(“This is a script in c#.”);

Então, na linha de comando ou no terminal, você executa o comando:

dotnet run script.cs

Há muitas informações sobre este novo recurso do .Net 10. Para trabalhar com o IRIS, podemos usar a opção de adicionar referências de pacotes NuGet diretamente dentro do arquivo. Por exemplo, para adicionar o nuget para InterSystems IRIS, você inclui as seguintes linhas no topo:

#:package InterSystems.Data.IRISClient@2.5.0 

using InterSystems.Data.IRISClient;
using InterSystems.Data.IRISClient.ADO;

Isso permite que o arquivo inclua o pacote NuGet do IRIS e use o IRIS SDK. Por exemplo, abaixo está um arquivo .cs com um script para verificar o status de uma produção de Interoperabilidade do InterSystems:

#:package InterSystems.Data.IRISClient@2.5.0

using InterSystems.Data.IRISClient;
using InterSystems.Data.IRISClient.ADO;

// Este script espera o namespace para conectar
string irisNamespace = string.Empty;
if (args.Length > 0)
{
    irisNamespace = args[0];
}

if (string.IsNullOrEmpty(irisNamespace))
{
    Console.WriteLine("Please indicate the namespace to connect");
    return;
}

// Abre uma conexão com o InterSystems IRIS
IRISConnection conn;
IRIS iris;

try
{
    conn = new IRISConnection();
    conn.ConnectionString = $"Server = 127.0.0.1;Port = 1972; Namespace = {irisNamespace.ToUpper()}; Password = SYS; User ID = _system;";
    conn.Open();
    iris = IRIS.CreateIRIS(conn);
}
catch (Exception ex)
{
    Console.WriteLine($"Cannot connect to the interoperability server. Error message: {ex.Message} ");
    return;
}

try
{

    bool? isInteroperabilityEnabledNamespace = iris.ClassMethodBool("%Library.EnsembleMgr", "IsEnsembleNamespace");
    if (isInteroperabilityEnabledNamespace ?? false)
    {
        // Os valores válidos são especificados na documentação
        //https://docs.intersystems.com/irislatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=ENSLIB&CLASSNAME=Ens.Director#METHOD_GetProductionStatus
        // E os valores numéricos podem ser encontrados no arquivo de inclusão EnsConstants.inc
        Func<decimal, string> GetStateDescription = state => state switch
        {
            0 => "Unknown",
            1 => "Running",
            2 => "Stopped",
            3 => "Suspended",
            4 => "Troubled",
            5 => "Network stopped",
            _ => "Unknown state"
        };
        string currentInteroperabilityProduction = string.Empty;
        decimal currentInteroperabilityProductionState = 0;

        IRISReference currentProductionName = new IRISReference("");
        IRISReference currentProductionState = new IRISReference("");

        var status = iris.ClassMethodObject("Ens.Director", "GetProductionStatus", currentProductionName, currentProductionState, 2, 1);

        if (status.ToString() == "1")
        {
            currentInteroperabilityProduction = currentProductionName.GetValue()?.ToString() ?? "";
            currentInteroperabilityProductionState = currentProductionState.GetDecimal() ?? 0;
        }
        if (string.IsNullOrEmpty(currentInteroperabilityProduction))
        {
            // Caso a produção esteja parada, a chamada a GetProductionStatus não retorna o nome da produção
            // neste caso tentamos obter o nome da produção ativa
            currentInteroperabilityProduction = iris.ClassMethodString("Ens.Director", "GetActiveProductionName");
        }

        Console.WriteLine($"Produção ativa neste namespace: {currentInteroperabilityProduction}");

        Console.WriteLine($"Estado da Produção: {GetStateDescription(currentInteroperabilityProductionState)}");

    }
    else
    {
        Console.WriteLine("O namespace não está habilitado para interoperabilidade");
    }
}
catch (Exception ex)
{
    Console.WriteLine($"Erro ao verificar o estado da produção no namespace{irisNamespace}:{ex.Message}");
}
finally
{
    iris.Dispose();
    conn.Close();
    conn.Dispose();
}

A execução deste arquivo com o parâmetro indicando o namespace no qual você deseja verificar o status da produção irá verificar se há alguma produção no namespace e seu status atual:

PS C:\IrisScripting> dotnet run ScriptTest.cs INTBUS
Produção ativa neste namespace: Integrations BUS
Estado da produção: Running
PS C:\IrisScripting>

Este novo recurso abre uma maneira nova e interessante de executar scripts ou pequenos programas para automatizar tarefas a partir da linha de comando.

Discussão (0)1
Entre ou crie uma conta para continuar
Resumo
· 4 hr atrás

Happy 10th Anniversary to the Developer Community

Dear Developer Community Member,

We'd like to congratulate you on the

🎉 10th Anniversary of the Developer Community! 🎉

This milestone marks ten incredible years of growth, collaboration, and shared discovery. And you have been an important part of that journey. Whether you’ve been part of the Community from the beginning or joined along the way, your presence has helped shape what the Developer Community is today.

Your articles, answers, ideas, projects, and conversations have created a dynamic space where developers learn from each other, tackle challenges together, and explore what can be achieved with InterSystems technologies. Your enthusiasm, expertise, and willingness to support others are what make this community truly special.

Here’s to the past decade and to many more years of building, learning, and innovating together. Thank you for being an essential part of this journey.

Visit the anniversary announcement to celebrate with your fellow members and share your birthday wishes for the Developer Community!

Warmest wishes,
The Developer Community Team

Pergunta
· 6 hr atrás

Buy Ozempic Online -Safe Shipping Guaranteed Worldwide

Buy Ozempic For Weight Loss Online USA,UK,CA - Safe Shipping Guaranteed USA,UK,CA- WhatsApp:+49163 0405954 - Website: www.eazmeds.com - Email: info@eazmeds.com

Eaz Meds USA,UK,CA is a trusted USA,UK,CA-based provider of high-quality wellness, personal care, and lifestyle products. We offer a wide range of solutions including pain relief, focus support, sleep aids, weight-management items, skincare essentials, and more.
We provide fast, discreet delivery across the United Kingdom and Europe, with customer satisfaction as our top priority. Browse our collection today and experience professional service, reliable shipping, and premium products from a supplier you can trust.
Treatments for Pain, ADD / ADHD , Erectile Dysfunction, Sleeping, Weight Loss, Urinary Tract Infection, STI Treatment, Hair loss Treatment, Low Fertility Treatment, Benzodiazepines & Skin Care Product all available at www.eazmeds.com

Discussão (0)1
Entre ou crie uma conta para continuar