├── .dockerignore ├── .gitattributes ├── .github └── workflows │ └── objectscript-quality.yml ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── Dockerfile ├── LICENSE ├── README-JP.md ├── README.md ├── data └── fhir │ ├── Carroll471_O'Hara248_274f5452-2a39-44c4-a7cb-f36de467762e.json │ ├── Frankie174_Jast432_a5b737fb-1f94-4767-802b-1112051f5101.json │ ├── Gabriele201_Rohan584_b0223c9b-0019-42b0-99b8-7d689d7f8414.json │ ├── Kallie862_Frami345_9a0d7938-4f49-43f6-8eea-b22e1bbe1b74.json │ ├── Lean294_Davis923_3e36b31d-3c32-43b4-b016-b46a90c2e50f.json │ ├── Margie619_Hettinger594_29428a22-5f03-492e-83bb-da34bb2a12c9.json │ ├── hospitalInformation1596649672088.json │ └── practitionerInformation1596649672088.json ├── dev.md ├── docker-compose.yml ├── fhirUI ├── FHIRAppDemo.html ├── irisfhir_swagger.json ├── jqFhir.js ├── jquery-3.4.1.min.js └── plotly-latest.min.js ├── iris.script ├── merge.cpf ├── merge_PID_CLINIC.cpf ├── misc ├── postman │ └── IRIS FHIR Template.postman_collection.json └── sql │ └── example.sql ├── module.xml ├── src ├── FHIR │ └── utils.cls ├── User │ └── SQLvar.cls └── fhirtemplate │ └── Setup.cls ├── synthea-loader.bat └── synthea-loader.sh /.dockerignore: -------------------------------------------------------------------------------- 1 | **/.DS_Store 2 | .git -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.sh text eol=lf 2 | *.cls text eol=lf 3 | *.mac text eol=lf 4 | *.int text eol=lf 5 | Dockerfil* text eol=lf -------------------------------------------------------------------------------- /.github/workflows/objectscript-quality.yml: -------------------------------------------------------------------------------- 1 | name: objectscriptquality 2 | on: push 3 | 4 | jobs: 5 | linux: 6 | name: Linux build 7 | runs-on: ubuntu-latest 8 | 9 | steps: 10 | - name: Execute ObjectScript Quality Analysis 11 | run: wget https://raw.githubusercontent.com/litesolutions/objectscriptquality-jenkins-integration/master/iris-community-hook.sh && sh ./iris-community-hook.sh 12 | 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .env 3 | 4 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "objectscript", 6 | "request": "launch", 7 | "name": "ObjectScript Debug Class", 8 | "program": "##class(PackageSample.ObjectScript).Test()", 9 | }, 10 | { 11 | "type": "objectscript", 12 | "request": "attach", 13 | "name": "ObjectScript Attach", 14 | "processId": "${command:PickProcess}", 15 | "system": true 16 | } 17 | ] 18 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | 4 | "Dockerfile*": "dockerfile", 5 | "iris.script": "objectscript" 6 | }, 7 | "objectscript.conn" :{ 8 | "ns": "FHIRSERVER", 9 | "active": true, 10 | "username": "_SYSTEM", 11 | "password": "SYS", 12 | "docker-compose": { 13 | "service": "iris", 14 | "internalPort": 52773 15 | }, 16 | "links": { 17 | "FHIR UI Portal": "http://localhost:${port}/fhir/portal/patientlist.html", 18 | "FHIR UI Demo": "http://localhost:${port}/fhirUI/FHIRAppDemo.html", 19 | "FHIR Swagger": "http://localhost:${port}/swagger-ui/index.html" 20 | } 21 | }, 22 | "sqltools.connections": [ 23 | { 24 | "askForPassword": false, 25 | "connectionMethod": "Server and Port", 26 | "driver": "InterSystems IRIS", 27 | "name": "iris-fhir-template", 28 | "namespace": "FHIRSERVER", 29 | "password": "SYS", 30 | "port": 32783, 31 | "previewLimit": 50, 32 | "server": "localhost", 33 | "showSystem": false, 34 | "username": "_SYSTEM" 35 | } 36 | ] 37 | 38 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | ARG IMAGE=intersystemsdc/irishealth-community:latest 2 | FROM $IMAGE as builder 3 | 4 | WORKDIR /home/irisowner/irisdev 5 | #RUN chown ${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} /opt/irisapp 6 | 7 | # copy all the source into container and run iris. also run a initial script 8 | RUN --mount=type=bind,src=.,dst=. \ 9 | iris start IRIS && \ 10 | iris merge IRIS merge.cpf && \ 11 | iris session IRIS < iris.script && \ 12 | iris stop IRIS quietly 13 | 14 | 15 | RUN old=http://localhost:52773/crud/_spec && \ 16 | new=/fhirUI/irisfhir_swagger.json && \ 17 | sed -i "s|$old|$new|g" /usr/irissys/csp/swagger-ui/index.html 18 | 19 | FROM $IMAGE as final 20 | 21 | ADD --chown=${ISC_PACKAGE_MGRUSER}:${ISC_PACKAGE_IRISGROUP} https://github.com/grongierisc/iris-docker-multi-stage-script/releases/latest/download/copy-data.py /irisdev/app/copy-data.py 22 | 23 | RUN --mount=type=bind,source=/,target=/builder/root,from=builder \ 24 | cp -f /builder/root/usr/irissys/iris.cpf /usr/irissys/iris.cpf && \ 25 | python3 /irisdev/app/copy-data.py -c /usr/irissys/iris.cpf -d /builder/root/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 InterSystems Developer Community 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README-JP.md: -------------------------------------------------------------------------------- 1 | # iris-fhirserver-template について 2 | FHIR サーバとして IRIS for Health Community Edition を使用するための開発テンプレートです。 3 | 4 | 開発テンプレートの中では、FHIR サーバの設定、テストデータのインポート、REST API の使用例を含む簡単な Web ページが用意されます。 5 | 6 | 7 | ## 前提条件 8 | このテンプレートを利用するために、[git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) と [Docker desktop](https://www.docker.com/products/docker-desktop) のインストールが必要です。 9 | 10 | 11 | ## インストール方法 12 | 13 | clone/git pull を使用してローカルディレクトリにリポジトリをダウンロードします。 14 | 15 | ``` 16 | $ git clone https://github.com/intersystems-community/iris-fhir-template.git 17 | ``` 18 | 19 | clone したディレクトリでターミナルを開き、以下実行します。 20 | 21 | ``` 22 | $ docker-compose up -d 23 | ``` 24 | 25 | ## Patient data 26 | このテンプレートでは、[/fhirdata](https://github.com/intersystems-community/iris-fhir-server-template/tree/master/fhirdata) フォルダに5人の患者データのサンプルを用意していて、[docker build](https://github.com/intersystems-community/iris-fhir-server-template/blob/8bd2932b34468f14530a53d3ab5125f9077696bb/iris.script#L26) のときにロードしています。 27 | 28 | また、[synthea-loader.sh](/synthea-loader.sh) を使用して任意数の患者データを生成できます。 29 | ターミナルを開き、git clone で生成されたディレクトリに移動し以下実行します(Windowsで実行する場合は、synthea-loader.bat をご利用ください。)。 30 | 31 | ``` 32 | #./synthea-loader.sh 5 33 | ``` 34 | 35 | 上記実行により、5人の患者データ用ファイルが data/fhir 以下に追加されます。 36 | IRIS のターミナルを開き、FHIRSERVER へ移動します。 37 | 38 | ``` 39 | docker-compose exec iris iris session iris -U FHIRServer 40 | ``` 41 | 42 | FHIRSERVER のプロンプトが表示されたら以下実行します。 43 | 44 | ``` 45 | FHIRSERVER>do ##class(fhirtemplate.Setup).LoadPatientData("/irisdev/app/output/fhir","FHIRSERVER","/fhir/r4") 46 | ``` 47 | 48 | より多くの患者データサンプルを作成されたい場合は、こちら [following project](https://github.com/intersystems-community/irisdemo-base-synthea) をご利用ください。 49 | 50 | 51 | ## FHIR R4 API のテスト方法 52 | 53 | 開発テンプレートが提供する FHIR サーバの Capability Statement をご参照ください。 54 | 以下 URL から FHIR サーバの Capability Statement を参照できます。 55 | 56 | http://localhost:32783/fhir/r4/metadata 57 | 58 | 59 | ## Postman を利用して Capability Statement を参照する 60 | FHIR リソースのメタ情報を取得するには、以下の GET要求を実行します。 61 | 62 | GET http://localhost:32783/fhir/r4/metadata 63 | 64 | Screenshot 2020-08-07 at 17 42 04 65 | 66 | 67 | Postman で以下のGET要求を実行するとリソース ID=1 の患者リソースを取得できます。 68 | 69 | http://localhost:32783/fhir/r4/Patient/1 70 | 71 | Screenshot 2020-08-07 at 17 42 26 72 | 73 | 74 | 75 | ## 簡単な フロントエンドアプリから FHIR API の呼び出しをテストする方法 76 | 77 | Patient と Observation の FHIR リソースを検索し、結果を参照する非常に基本的なフロントエンドアプリは、以下 URL で参照できます。 78 | 79 | http://localhost:32783/csp/user/fhirUI/FHIRAppDemo.html 80 | 81 | VSCode ObjectScript メニューからも開くことができます: 82 | Screenshot 2020-08-07 at 17 34 49 83 | 84 | ページを開くと、貧血の症状を持つ女性患者の検索結果を参照できます。 85 | また、特定の患者IDを指定すると、ヘモグロビン値のグラフを参照できます。 86 | 87 | Screenshot 2020-08-06 at 18 51 22 88 | 89 | 90 | ## 参考情報 91 | [InterSystems IRIS FHIR Documentation](https://docs.intersystems.com/irisforhealth20203/csp/docbook/Doc.View.cls?KEY=HXFHIR) 92 | 93 | [FHIR API](http://hl7.org/fhir/resourcelist.html) 94 | 95 | [Developer Community FHIR section(US版)](https://community.intersystems.com/tags/fhir) 96 | 97 | [Developer Community FHIR section(日本版)](https://jp.community.intersystems.com/tags/fhir) 98 | 99 | 100 | ## コーディングの開始方法(ObjectScript) 101 | このGitリポジトリは、ObjectScript のプラグイン使用して VSCode でコーディングする準備が整っています。 102 | [VSCode](https://code.visualstudio.com/), [Docker](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker) [ObjectScript](https://marketplace.visualstudio.com/items?itemName=daimor.vscode-objectscript) プラグインインストールします。あとは、VSCoed でリポジトリのフォルダを開くだけです。 103 | 104 | /src/cls/PackageSample/ObjectScript.cls を開き何か変更を加えてみてください。Ctrl+Sで保存すると実行中の IRIS docker コンテナでコンパイルされます。 105 | 106 | ![docker_compose](https://user-images.githubusercontent.com/2781759/76656929-0f2e5700-6547-11ea-9cc9-486a5641c51d.gif) 107 | 108 | PackageSample フォルダはサンプルです。ObjectScript 練習用として、編集、削除などお好みで行ってください。 109 | もし、新規でクラスを作成する場合は /src 以下にパッケージ名のフォルダを作成し、その下にクラス名のファイル(例:Classname.cls)を配置してください。 110 | 例) /src/Package/Classname.cls 111 | 112 | ご参考:[Read more about folder setup for InterSystems ObjectScript](https://community.intersystems.com/post/simplified-objectscript-source-folder-structure-package-manager) 113 | 114 | 115 | ## リポジトリの中身について 116 | 117 | ### Dockerfile 118 | 119 | IRIS を起動し、開発テンプレートに必要なファイルのコピー([/src](https://github.com/intersystems-community/iris-fhir-server-template/tree/master/src) 、[/fhirdata](https://github.com/intersystems-community/iris-fhir-server-template/tree/master/fhirdata)、[/fhirUI](https://github.com/intersystems-community/iris-fhir-server-template/tree/master/fhirUI) 、[/iris.script](https://github.com/intersystems-community/iris-fhir-server-template/tree/master/iris.script) )と iris.script の実行を行います。 120 | 121 | 関連する docker-compose.yml を使用して、ポート番号やホストフォルダをマップする場所などの追加パラメータを簡単に設定します。 122 | 123 | 124 | 125 | ### .vscode/settings.json 126 | 127 | [VSCode ObjectScript プラグイン](https://marketplace.visualstudio.com/items?itemName=daimor.vscode-objectscript)を使って VSCode ですぐにコーディングできるようにするための設定ファイルです。 128 | 129 | ### .vscode/launch.json 130 | VSCode ObjectScript でデバッグしたい場合の設定ファイルです。 131 | 132 | 133 | ## トラブルシューティング 134 | 135 | ### ERROR #5001: Error -28 Creating Directory /usr/irissys/mgr/FHIRSERVER/ 136 | このエラーが出る場合、docker の空き容量を使い果たしてしまった可能性があります。以下のコマンドを利用して未使用のイメージ、キャッシュ、コンテナを削除することができます。 137 | (-f オプションを指定しない場合、確認用のプロンプトが出力されます) 138 | 139 | ``` 140 | $ docker system prune -f 141 | ``` 142 | 143 | 上記コマンド実行後、キャッシュを使用しないイメージの再構築を行います。 144 | 145 | ``` 146 | $ docker-compose build --no-cache 147 | ``` 148 | 149 | 上記コマンド実行後、コンテナを開始します。 150 | 151 | ``` 152 | $ docker-compose up -d 153 | ``` 154 | 155 | この他のヒントについては、[dev.md](/dev.md) をご参照ください。 156 | 157 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Gitter](https://img.shields.io/badge/Available%20on-Intersystems%20Open%20Exchange-00b2a9.svg)](https://openexchange.intersystems.com/package/iris-fhir-template) 2 | [![Quality Gate Status](https://community.objectscriptquality.com/api/project_badges/measure?project=intersystems_iris_community%2Firis-fhir-template&metric=alert_status)](https://community.objectscriptquality.com/dashboard?id=intersystems_iris_community%2Firis-fhir-template) 3 | [![Reliability Rating](https://community.objectscriptquality.com/api/project_badges/measure?project=intersystems_iris_community%2Firis-fhir-template&metric=reliability_rating)](https://community.objectscriptquality.com/dashboard?id=intersystems_iris_community%2Firis-fhir-template) 4 | # iris-fhirserver-template 5 | This is the base template for using InterSystems IRIS for Health Community Edition as a FHIR Server 6 | 7 | It setups a FHIR SERVER, imports the test data, demoes REST API usage with a simple web page. 8 | 9 | ## Prerequisites 10 | Make sure you have [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git) and [Docker desktop](https://www.docker.com/products/docker-desktop) installed. 11 | 12 | ## Installation 13 | 14 | ### IPM 15 | 16 | Open IRIS for Health installation with IPM client installed. Call in any namespace: 17 | 18 | ``` 19 | USER>zpm "install fhir-server" 20 | ``` 21 | 22 | This will install FHIR server in FHIRSERVER namespace. 23 | 24 | Or call the following for installing programmatically: 25 | ``` 26 | set sc=$zpm("install fhir-server") 27 | ``` 28 | 29 | 30 | ### Docker (e.g. for dev purposes) 31 | 32 | Clone/git pull the repo into any local directory 33 | 34 | ``` 35 | $ git clone https://github.com/intersystems-community/iris-fhir-template.git 36 | ``` 37 | 38 | Open the terminal in this directory and run: 39 | 40 | ``` 41 | $ docker-compose up -d 42 | ``` 43 | 44 | ## Patient data 45 | The template goes with 5 preloaded patents in [/data/fhir](https://github.com/intersystems-community/iris-fhir-server-template/tree/master/data/fhir) folder which are being loaded during [docker build](https://github.com/intersystems-community/iris-fhir-server-template/blob/8bd2932b34468f14530a53d3ab5125f9077696bb/iris.script#L26) 46 | You can generate more patients doing the following. Open shel terminal in repository folder and call: 47 | ``` 48 | #./synthea-loader.sh 10 49 | ``` 50 | this will create 10 more patients in data/fhir folder. 51 | Then open IRIS terminal in FHIRSERVER namespace with the following command: 52 | ``` 53 | docker-compose exec iris iris session iris -U FHIRServer 54 | ``` 55 | and call the loader method: 56 | ``` 57 | FHIRSERVER>d ##class(fhirtemplate.Setup).LoadPatientData("/data/fhir","FHIRSERVER","/fhir/r4") 58 | ``` 59 | 60 | with using the [following project](https://github.com/intersystems-community/irisdemo-base-synthea) 61 | 62 | ## Testing FHIR R4 API 63 | 64 | Open URL http://localhost:32783/fhir/r4/metadata 65 | you should see the output of fhir resources on this server 66 | 67 | ## Swagger UI 68 | 69 | You can get the Swagger UI and work with it at: 70 | http://localhost:32783/swagger-ui/index.html 71 | 72 | To try it Open /Patient/{id} resource and call for the patient 3. 73 | Here is what you should see: 74 | Image 75 | 76 | ## Testing Postman calls 77 | Get fhir resources metadata 78 | GET call for http://localhost:32783/fhir/r4/metadata 79 | Screenshot 2020-08-07 at 17 42 04 80 | 81 | 82 | Open Postman and make a GET call for the preloaded Patient: 83 | http://localhost:32783/fhir/r4/Patient/1 84 | Screenshot 2020-08-07 at 17 42 26 85 | 86 | 87 | ## Testing FHIR API calls in simple frontend APP 88 | 89 | the very basic frontend app with search and get calls to Patient and Observation FHIR resources could be found here: 90 | http://localhost:32783/fhirUI/FHIRAppDemo.html 91 | or from VSCode ObjectScript menu: 92 | Screenshot 2020-08-07 at 17 34 49 93 | 94 | While open the page you will see search result for female anemic patients and graphs a selected patient's hemoglobin values: 95 | Screenshot 2020-08-06 at 18 51 22 96 | 97 | 98 | ## More sophisticated UI 99 | 100 | The example of a richer UI around the FHIR data can be observed at: 101 | http://localhost:32783/fhir/portal/patientlist.html 102 | 103 | Here is an example screenshot of it: 104 | Image 105 | 106 | 107 | ## Development Resources 108 | [InterSystems IRIS FHIR Documentation](https://docs.intersystems.com/irisforhealth20203/csp/docbook/Doc.View.cls?KEY=HXFHIR) 109 | [FHIR API](http://hl7.org/fhir/resourcelist.html) 110 | [Developer Community FHIR section](https://community.intersystems.com/tags/fhir) 111 | 112 | ## What's inside the repository 113 | 114 | ### Dockerfile 115 | 116 | The simplest dockerfile which starts IRIS and imports Installer.cls and then runs the Installer.setup method, which creates IRISAPP Namespace and imports ObjectScript code from /src folder into it. 117 | Use the related docker-compose.yml to easily setup additional parametes like port number and where you map keys and host folders. 118 | Use .env/ file to adjust the dockerfile being used in docker-compose. 119 | 120 | 121 | ### .vscode/settings.json 122 | 123 | Settings file to let you immedietly code in VSCode with [VSCode ObjectScript plugin](https://marketplace.visualstudio.com/items?itemName=daimor.vscode-objectscript)) 124 | 125 | ### .vscode/launch.json 126 | Config file if you want to debug with VSCode ObjectScript 127 | 128 | 129 | ## Troubleshooting 130 | **ERROR #5001: Error -28 Creating Directory /usr/irissys/mgr/FHIRSERVER/** 131 | If you see this error it probably means that you ran out of space in docker. 132 | you can clean up it with the following command: 133 | ``` 134 | docker system prune -f 135 | ``` 136 | And then start rebuilding image without using cache: 137 | ``` 138 | docker-compose build --no-cache 139 | ``` 140 | and start the container with: 141 | ``` 142 | docker-compose up -d 143 | ``` 144 | 145 | This and other helpful commands you can find in [dev.md](https://github.com/intersystems-community/iris-fhir-template/blob/cd7e0111ff94dcac82377a2aa7df0ce5e0571b5a/dev.md) 146 | -------------------------------------------------------------------------------- /data/fhir/hospitalInformation1596649672088.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "Bundle", 3 | "type": "transaction", 4 | "entry": [ 5 | { 6 | "fullUrl": "urn:uuid:5e765f2b-e908-3888-9fc7-df2cb87beb58", 7 | "resource": { 8 | "resourceType": "Organization", 9 | "id": "5e765f2b-e908-3888-9fc7-df2cb87beb58", 10 | "extension": [ 11 | { 12 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 13 | "valueInteger": 7 14 | }, 15 | { 16 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 17 | "valueInteger": 0 18 | }, 19 | { 20 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 21 | "valueInteger": 0 22 | }, 23 | { 24 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 25 | "valueInteger": 0 26 | } 27 | ], 28 | "identifier": [ 29 | { 30 | "system": "https://github.com/synthetichealth/synthea", 31 | "value": "5e765f2b-e908-3888-9fc7-df2cb87beb58" 32 | } 33 | ], 34 | "active": true, 35 | "type": [ 36 | { 37 | "coding": [ 38 | { 39 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 40 | "code": "prov", 41 | "display": "Healthcare Provider" 42 | } 43 | ], 44 | "text": "Healthcare Provider" 45 | } 46 | ], 47 | "name": "STURDY MEMORIAL HOSPITAL", 48 | "telecom": [ 49 | { 50 | "system": "phone", 51 | "value": "5082225200" 52 | } 53 | ], 54 | "address": [ 55 | { 56 | "line": [ 57 | "211 PARK STREET" 58 | ], 59 | "city": "ATTLEBORO", 60 | "state": "MA", 61 | "postalCode": "02703", 62 | "country": "US" 63 | } 64 | ] 65 | }, 66 | "request": { 67 | "method": "POST", 68 | "url": "Organization" 69 | } 70 | }, 71 | { 72 | "fullUrl": "urn:uuid:8b58cdd1-3d79-3126-8fe0-da2c54d6805c", 73 | "resource": { 74 | "resourceType": "Organization", 75 | "id": "8b58cdd1-3d79-3126-8fe0-da2c54d6805c", 76 | "extension": [ 77 | { 78 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 79 | "valueInteger": 4 80 | }, 81 | { 82 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 83 | "valueInteger": 0 84 | }, 85 | { 86 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 87 | "valueInteger": 0 88 | }, 89 | { 90 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 91 | "valueInteger": 0 92 | } 93 | ], 94 | "identifier": [ 95 | { 96 | "system": "https://github.com/synthetichealth/synthea", 97 | "value": "8b58cdd1-3d79-3126-8fe0-da2c54d6805c" 98 | } 99 | ], 100 | "active": true, 101 | "type": [ 102 | { 103 | "coding": [ 104 | { 105 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 106 | "code": "prov", 107 | "display": "Healthcare Provider" 108 | } 109 | ], 110 | "text": "Healthcare Provider" 111 | } 112 | ], 113 | "name": "CARNEY HOSPITAL", 114 | "telecom": [ 115 | { 116 | "system": "phone", 117 | "value": "6175062000" 118 | } 119 | ], 120 | "address": [ 121 | { 122 | "line": [ 123 | "2100 DORCHESTER AVENUE" 124 | ], 125 | "city": "BOSTON", 126 | "state": "MA", 127 | "postalCode": "02124", 128 | "country": "US" 129 | } 130 | ] 131 | }, 132 | "request": { 133 | "method": "POST", 134 | "url": "Organization" 135 | } 136 | }, 137 | { 138 | "fullUrl": "urn:uuid:ecc51621-0af3-3b35-ac3e-8b1e34022e92", 139 | "resource": { 140 | "resourceType": "Organization", 141 | "id": "ecc51621-0af3-3b35-ac3e-8b1e34022e92", 142 | "extension": [ 143 | { 144 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 145 | "valueInteger": 12 146 | }, 147 | { 148 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 149 | "valueInteger": 0 150 | }, 151 | { 152 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 153 | "valueInteger": 0 154 | }, 155 | { 156 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 157 | "valueInteger": 0 158 | } 159 | ], 160 | "identifier": [ 161 | { 162 | "system": "https://github.com/synthetichealth/synthea", 163 | "value": "ecc51621-0af3-3b35-ac3e-8b1e34022e92" 164 | } 165 | ], 166 | "active": true, 167 | "type": [ 168 | { 169 | "coding": [ 170 | { 171 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 172 | "code": "prov", 173 | "display": "Healthcare Provider" 174 | } 175 | ], 176 | "text": "Healthcare Provider" 177 | } 178 | ], 179 | "name": "SAINT ANNE'S HOSPITAL", 180 | "telecom": [ 181 | { 182 | "system": "phone", 183 | "value": "5086745600" 184 | } 185 | ], 186 | "address": [ 187 | { 188 | "line": [ 189 | "795 MIDDLE STREET" 190 | ], 191 | "city": "FALL RIVER", 192 | "state": "MA", 193 | "postalCode": "02721", 194 | "country": "US" 195 | } 196 | ] 197 | }, 198 | "request": { 199 | "method": "POST", 200 | "url": "Organization" 201 | } 202 | }, 203 | { 204 | "fullUrl": "urn:uuid:23834663-ed53-3da9-b330-d6e1ecb8428e", 205 | "resource": { 206 | "resourceType": "Organization", 207 | "id": "23834663-ed53-3da9-b330-d6e1ecb8428e", 208 | "extension": [ 209 | { 210 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 211 | "valueInteger": 3 212 | }, 213 | { 214 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 215 | "valueInteger": 0 216 | }, 217 | { 218 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 219 | "valueInteger": 0 220 | }, 221 | { 222 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 223 | "valueInteger": 0 224 | } 225 | ], 226 | "identifier": [ 227 | { 228 | "system": "https://github.com/synthetichealth/synthea", 229 | "value": "23834663-ed53-3da9-b330-d6e1ecb8428e" 230 | } 231 | ], 232 | "active": true, 233 | "type": [ 234 | { 235 | "coding": [ 236 | { 237 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 238 | "code": "prov", 239 | "display": "Healthcare Provider" 240 | } 241 | ], 242 | "text": "Healthcare Provider" 243 | } 244 | ], 245 | "name": "SOUTHCOAST HOSPITAL GROUP, INC", 246 | "telecom": [ 247 | { 248 | "system": "phone", 249 | "value": "5086793131" 250 | } 251 | ], 252 | "address": [ 253 | { 254 | "line": [ 255 | "363 HIGHLAND AVENUE" 256 | ], 257 | "city": "FALL RIVER", 258 | "state": "MA", 259 | "postalCode": "02720", 260 | "country": "US" 261 | } 262 | ] 263 | }, 264 | "request": { 265 | "method": "POST", 266 | "url": "Organization" 267 | } 268 | }, 269 | { 270 | "fullUrl": "urn:uuid:7fb56531-86bd-3e4a-8619-4df9942da309", 271 | "resource": { 272 | "resourceType": "Organization", 273 | "id": "7fb56531-86bd-3e4a-8619-4df9942da309", 274 | "extension": [ 275 | { 276 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 277 | "valueInteger": 236 278 | }, 279 | { 280 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 281 | "valueInteger": 0 282 | }, 283 | { 284 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 285 | "valueInteger": 0 286 | }, 287 | { 288 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 289 | "valueInteger": 0 290 | } 291 | ], 292 | "identifier": [ 293 | { 294 | "system": "https://github.com/synthetichealth/synthea", 295 | "value": "7fb56531-86bd-3e4a-8619-4df9942da309" 296 | } 297 | ], 298 | "active": true, 299 | "type": [ 300 | { 301 | "coding": [ 302 | { 303 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 304 | "code": "prov", 305 | "display": "Healthcare Provider" 306 | } 307 | ], 308 | "text": "Healthcare Provider" 309 | } 310 | ], 311 | "name": "BETH ISRAEL DEACONESS HOSPITAL - NEEDHAM", 312 | "telecom": [ 313 | { 314 | "system": "phone", 315 | "value": "7814533002" 316 | } 317 | ], 318 | "address": [ 319 | { 320 | "line": [ 321 | "148 CHESTNUT STREET" 322 | ], 323 | "city": "NEEDHAM", 324 | "state": "MA", 325 | "postalCode": "02494", 326 | "country": "US" 327 | } 328 | ] 329 | }, 330 | "request": { 331 | "method": "POST", 332 | "url": "Organization" 333 | } 334 | }, 335 | { 336 | "fullUrl": "urn:uuid:ac8356a5-78f8-3a63-8a1e-59e832fd54e7", 337 | "resource": { 338 | "resourceType": "Organization", 339 | "id": "ac8356a5-78f8-3a63-8a1e-59e832fd54e7", 340 | "extension": [ 341 | { 342 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 343 | "valueInteger": 35 344 | }, 345 | { 346 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 347 | "valueInteger": 0 348 | }, 349 | { 350 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 351 | "valueInteger": 0 352 | }, 353 | { 354 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 355 | "valueInteger": 0 356 | } 357 | ], 358 | "identifier": [ 359 | { 360 | "system": "https://github.com/synthetichealth/synthea", 361 | "value": "ac8356a5-78f8-3a63-8a1e-59e832fd54e7" 362 | } 363 | ], 364 | "active": true, 365 | "type": [ 366 | { 367 | "coding": [ 368 | { 369 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 370 | "code": "prov", 371 | "display": "Healthcare Provider" 372 | } 373 | ], 374 | "text": "Healthcare Provider" 375 | } 376 | ], 377 | "name": "NASHOBA VALLEY MEDICAL CENTER", 378 | "telecom": [ 379 | { 380 | "system": "phone", 381 | "value": "9787849000" 382 | } 383 | ], 384 | "address": [ 385 | { 386 | "line": [ 387 | "200 GROTON ROAD" 388 | ], 389 | "city": "AYER", 390 | "state": "MA", 391 | "postalCode": "01432", 392 | "country": "US" 393 | } 394 | ] 395 | }, 396 | "request": { 397 | "method": "POST", 398 | "url": "Organization" 399 | } 400 | }, 401 | { 402 | "fullUrl": "urn:uuid:d733d4a9-080d-3593-b910-2366e652b7ea", 403 | "resource": { 404 | "resourceType": "Organization", 405 | "id": "d733d4a9-080d-3593-b910-2366e652b7ea", 406 | "extension": [ 407 | { 408 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 409 | "valueInteger": 46 410 | }, 411 | { 412 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 413 | "valueInteger": 0 414 | }, 415 | { 416 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 417 | "valueInteger": 0 418 | }, 419 | { 420 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 421 | "valueInteger": 0 422 | } 423 | ], 424 | "identifier": [ 425 | { 426 | "system": "https://github.com/synthetichealth/synthea", 427 | "value": "d733d4a9-080d-3593-b910-2366e652b7ea" 428 | } 429 | ], 430 | "active": true, 431 | "type": [ 432 | { 433 | "coding": [ 434 | { 435 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 436 | "code": "prov", 437 | "display": "Healthcare Provider" 438 | } 439 | ], 440 | "text": "Healthcare Provider" 441 | } 442 | ], 443 | "name": "BRIGHAM AND WOMEN'S FAULKNER HOSPITAL", 444 | "telecom": [ 445 | { 446 | "system": "phone", 447 | "value": "6179837000" 448 | } 449 | ], 450 | "address": [ 451 | { 452 | "line": [ 453 | "1153 CENTRE STREET" 454 | ], 455 | "city": "BOSTON", 456 | "state": "MA", 457 | "postalCode": "02130", 458 | "country": "US" 459 | } 460 | ] 461 | }, 462 | "request": { 463 | "method": "POST", 464 | "url": "Organization" 465 | } 466 | }, 467 | { 468 | "fullUrl": "urn:uuid:ff9863d3-3fa3-3861-900e-f00148f5d9c2", 469 | "resource": { 470 | "resourceType": "Organization", 471 | "id": "ff9863d3-3fa3-3861-900e-f00148f5d9c2", 472 | "extension": [ 473 | { 474 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 475 | "valueInteger": 11 476 | }, 477 | { 478 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 479 | "valueInteger": 0 480 | }, 481 | { 482 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 483 | "valueInteger": 0 484 | }, 485 | { 486 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 487 | "valueInteger": 0 488 | } 489 | ], 490 | "identifier": [ 491 | { 492 | "system": "https://github.com/synthetichealth/synthea", 493 | "value": "ff9863d3-3fa3-3861-900e-f00148f5d9c2" 494 | } 495 | ], 496 | "active": true, 497 | "type": [ 498 | { 499 | "coding": [ 500 | { 501 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 502 | "code": "prov", 503 | "display": "Healthcare Provider" 504 | } 505 | ], 506 | "text": "Healthcare Provider" 507 | } 508 | ], 509 | "name": "SHRINERS' HOSPITAL FOR CHILDREN - BOSTON, THE", 510 | "telecom": [ 511 | { 512 | "system": "phone", 513 | "value": "6177223000" 514 | } 515 | ], 516 | "address": [ 517 | { 518 | "line": [ 519 | "51 BLOSSOM STREET" 520 | ], 521 | "city": "BOSTON", 522 | "state": "MA", 523 | "postalCode": "02114", 524 | "country": "US" 525 | } 526 | ] 527 | }, 528 | "request": { 529 | "method": "POST", 530 | "url": "Organization" 531 | } 532 | }, 533 | { 534 | "fullUrl": "urn:uuid:869ba21d-a974-3260-9752-4d1ba8d12f28", 535 | "resource": { 536 | "resourceType": "Organization", 537 | "id": "869ba21d-a974-3260-9752-4d1ba8d12f28", 538 | "extension": [ 539 | { 540 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 541 | "valueInteger": 56 542 | }, 543 | { 544 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 545 | "valueInteger": 256 546 | }, 547 | { 548 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 549 | "valueInteger": 24 550 | }, 551 | { 552 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 553 | "valueInteger": 43 554 | } 555 | ], 556 | "identifier": [ 557 | { 558 | "system": "https://github.com/synthetichealth/synthea", 559 | "value": "869ba21d-a974-3260-9752-4d1ba8d12f28" 560 | } 561 | ], 562 | "active": true, 563 | "type": [ 564 | { 565 | "coding": [ 566 | { 567 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 568 | "code": "prov", 569 | "display": "Healthcare Provider" 570 | } 571 | ], 572 | "text": "Healthcare Provider" 573 | } 574 | ], 575 | "name": "PCP2617", 576 | "telecom": [ 577 | { 578 | "system": "phone", 579 | "value": "781-894-8898" 580 | } 581 | ], 582 | "address": [ 583 | { 584 | "line": [ 585 | "102 WESTLAND RD" 586 | ], 587 | "city": "WESTON", 588 | "state": "MA", 589 | "postalCode": "02493-1341", 590 | "country": "US" 591 | } 592 | ] 593 | }, 594 | "request": { 595 | "method": "POST", 596 | "url": "Organization" 597 | } 598 | }, 599 | { 600 | "fullUrl": "urn:uuid:0de9633c-54dd-39cb-947c-8ab5ecdf93a2", 601 | "resource": { 602 | "resourceType": "Organization", 603 | "id": "0de9633c-54dd-39cb-947c-8ab5ecdf93a2", 604 | "extension": [ 605 | { 606 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 607 | "valueInteger": 55 608 | }, 609 | { 610 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 611 | "valueInteger": 38 612 | }, 613 | { 614 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 615 | "valueInteger": 23 616 | }, 617 | { 618 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 619 | "valueInteger": 15 620 | } 621 | ], 622 | "identifier": [ 623 | { 624 | "system": "https://github.com/synthetichealth/synthea", 625 | "value": "0de9633c-54dd-39cb-947c-8ab5ecdf93a2" 626 | } 627 | ], 628 | "active": true, 629 | "type": [ 630 | { 631 | "coding": [ 632 | { 633 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 634 | "code": "prov", 635 | "display": "Healthcare Provider" 636 | } 637 | ], 638 | "text": "Healthcare Provider" 639 | } 640 | ], 641 | "name": "PCP3874", 642 | "telecom": [ 643 | { 644 | "system": "phone", 645 | "value": "978-425-6666" 646 | } 647 | ], 648 | "address": [ 649 | { 650 | "line": [ 651 | "2 SHAKER RD" 652 | ], 653 | "city": "SHIRLEY", 654 | "state": "MA", 655 | "postalCode": "01464-2561", 656 | "country": "US" 657 | } 658 | ] 659 | }, 660 | "request": { 661 | "method": "POST", 662 | "url": "Organization" 663 | } 664 | }, 665 | { 666 | "fullUrl": "urn:uuid:6c3186b1-3f6f-388c-adcb-e9f5b0f6b0d7", 667 | "resource": { 668 | "resourceType": "Organization", 669 | "id": "6c3186b1-3f6f-388c-adcb-e9f5b0f6b0d7", 670 | "extension": [ 671 | { 672 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 673 | "valueInteger": 20 674 | }, 675 | { 676 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 677 | "valueInteger": 10 678 | }, 679 | { 680 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 681 | "valueInteger": 3 682 | }, 683 | { 684 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 685 | "valueInteger": 4 686 | } 687 | ], 688 | "identifier": [ 689 | { 690 | "system": "https://github.com/synthetichealth/synthea", 691 | "value": "6c3186b1-3f6f-388c-adcb-e9f5b0f6b0d7" 692 | } 693 | ], 694 | "active": true, 695 | "type": [ 696 | { 697 | "coding": [ 698 | { 699 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 700 | "code": "prov", 701 | "display": "Healthcare Provider" 702 | } 703 | ], 704 | "text": "Healthcare Provider" 705 | } 706 | ], 707 | "name": "CHARLES C CALENDA MD INC", 708 | "telecom": [ 709 | { 710 | "system": "phone", 711 | "value": "508-324-1171" 712 | } 713 | ], 714 | "address": [ 715 | { 716 | "line": [ 717 | "440 SWANSEA MALL DR" 718 | ], 719 | "city": "SWANSEA", 720 | "state": "MA", 721 | "postalCode": "02777-4114", 722 | "country": "US" 723 | } 724 | ] 725 | }, 726 | "request": { 727 | "method": "POST", 728 | "url": "Organization" 729 | } 730 | }, 731 | { 732 | "fullUrl": "urn:uuid:0dbd13c7-d59a-3415-8e4b-070d3f356867", 733 | "resource": { 734 | "resourceType": "Organization", 735 | "id": "0dbd13c7-d59a-3415-8e4b-070d3f356867", 736 | "extension": [ 737 | { 738 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 739 | "valueInteger": 30 740 | }, 741 | { 742 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 743 | "valueInteger": 155 744 | }, 745 | { 746 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 747 | "valueInteger": 5 748 | }, 749 | { 750 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 751 | "valueInteger": 12 752 | } 753 | ], 754 | "identifier": [ 755 | { 756 | "system": "https://github.com/synthetichealth/synthea", 757 | "value": "0dbd13c7-d59a-3415-8e4b-070d3f356867" 758 | } 759 | ], 760 | "active": true, 761 | "type": [ 762 | { 763 | "coding": [ 764 | { 765 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 766 | "code": "prov", 767 | "display": "Healthcare Provider" 768 | } 769 | ], 770 | "text": "Healthcare Provider" 771 | } 772 | ], 773 | "name": "STEWARD ST. ELIZABETH'S MEDICAL CENTER OF BOSTON, INC.", 774 | "telecom": [ 775 | { 776 | "system": "phone", 777 | "value": "617-562-5200" 778 | } 779 | ], 780 | "address": [ 781 | { 782 | "line": [ 783 | "77 WARREN ST 1ST FLOOR AND 2ND FLOOR" 784 | ], 785 | "city": "BRIGHTON", 786 | "state": "MA", 787 | "postalCode": "02135-3601", 788 | "country": "US" 789 | } 790 | ] 791 | }, 792 | "request": { 793 | "method": "POST", 794 | "url": "Organization" 795 | } 796 | }, 797 | { 798 | "fullUrl": "urn:uuid:58663821-936b-34cc-9b26-8ec395418f76", 799 | "resource": { 800 | "resourceType": "Organization", 801 | "id": "58663821-936b-34cc-9b26-8ec395418f76", 802 | "extension": [ 803 | { 804 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 805 | "valueInteger": 64 806 | }, 807 | { 808 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 809 | "valueInteger": 264 810 | }, 811 | { 812 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 813 | "valueInteger": 60 814 | }, 815 | { 816 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 817 | "valueInteger": 32 818 | } 819 | ], 820 | "identifier": [ 821 | { 822 | "system": "https://github.com/synthetichealth/synthea", 823 | "value": "58663821-936b-34cc-9b26-8ec395418f76" 824 | } 825 | ], 826 | "active": true, 827 | "type": [ 828 | { 829 | "coding": [ 830 | { 831 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 832 | "code": "prov", 833 | "display": "Healthcare Provider" 834 | } 835 | ], 836 | "text": "Healthcare Provider" 837 | } 838 | ], 839 | "name": "LIFELONG THERAPEUTICS OT PLLC", 840 | "telecom": [ 841 | { 842 | "system": "phone", 843 | "value": "631-278-0665" 844 | } 845 | ], 846 | "address": [ 847 | { 848 | "line": [ 849 | "99 NORUMBEGA RD" 850 | ], 851 | "city": "WESTON", 852 | "state": "MA", 853 | "postalCode": "02493-2482", 854 | "country": "US" 855 | } 856 | ] 857 | }, 858 | "request": { 859 | "method": "POST", 860 | "url": "Organization" 861 | } 862 | }, 863 | { 864 | "fullUrl": "urn:uuid:a441cbca-6d65-33ff-980c-d8e58235b7e5", 865 | "resource": { 866 | "resourceType": "Organization", 867 | "id": "a441cbca-6d65-33ff-980c-d8e58235b7e5", 868 | "extension": [ 869 | { 870 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 871 | "valueInteger": 53 872 | }, 873 | { 874 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 875 | "valueInteger": 30 876 | }, 877 | { 878 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 879 | "valueInteger": 14 880 | }, 881 | { 882 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 883 | "valueInteger": 36 884 | } 885 | ], 886 | "identifier": [ 887 | { 888 | "system": "https://github.com/synthetichealth/synthea", 889 | "value": "a441cbca-6d65-33ff-980c-d8e58235b7e5" 890 | } 891 | ], 892 | "active": true, 893 | "type": [ 894 | { 895 | "coding": [ 896 | { 897 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 898 | "code": "prov", 899 | "display": "Healthcare Provider" 900 | } 901 | ], 902 | "text": "Healthcare Provider" 903 | } 904 | ], 905 | "name": "PRIMA CARE PC", 906 | "telecom": [ 907 | { 908 | "system": "phone", 909 | "value": "508-676-3292" 910 | } 911 | ], 912 | "address": [ 913 | { 914 | "line": [ 915 | "67 SLADE'S FERRY BOULEVARD" 916 | ], 917 | "city": "SOMERSET", 918 | "state": "MA", 919 | "postalCode": "02726-1220", 920 | "country": "US" 921 | } 922 | ] 923 | }, 924 | "request": { 925 | "method": "POST", 926 | "url": "Organization" 927 | } 928 | }, 929 | { 930 | "fullUrl": "urn:uuid:ad933cee-594c-3f13-b6ef-20f89ecd91ff", 931 | "resource": { 932 | "resourceType": "Organization", 933 | "id": "ad933cee-594c-3f13-b6ef-20f89ecd91ff", 934 | "extension": [ 935 | { 936 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 937 | "valueInteger": 1 938 | }, 939 | { 940 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 941 | "valueInteger": 0 942 | }, 943 | { 944 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 945 | "valueInteger": 0 946 | }, 947 | { 948 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 949 | "valueInteger": 0 950 | } 951 | ], 952 | "identifier": [ 953 | { 954 | "system": "https://github.com/synthetichealth/synthea", 955 | "value": "ad933cee-594c-3f13-b6ef-20f89ecd91ff" 956 | } 957 | ], 958 | "active": true, 959 | "type": [ 960 | { 961 | "coding": [ 962 | { 963 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 964 | "code": "prov", 965 | "display": "Healthcare Provider" 966 | } 967 | ], 968 | "text": "Healthcare Provider" 969 | } 970 | ], 971 | "name": "ROUTE 6 WALK IN EMERGENCY OFFICE", 972 | "telecom": [ 973 | { 974 | "system": "phone", 975 | "value": "508-336-4550" 976 | } 977 | ], 978 | "address": [ 979 | { 980 | "line": [ 981 | "1589 FALL RIVER AVENUE" 982 | ], 983 | "city": "SEEKONK", 984 | "state": "MA", 985 | "postalCode": "2771", 986 | "country": "US" 987 | } 988 | ] 989 | }, 990 | "request": { 991 | "method": "POST", 992 | "url": "Organization" 993 | } 994 | }, 995 | { 996 | "fullUrl": "urn:uuid:e3f1676b-9b40-3544-af4e-17a06bbb98bb", 997 | "resource": { 998 | "resourceType": "Organization", 999 | "id": "e3f1676b-9b40-3544-af4e-17a06bbb98bb", 1000 | "extension": [ 1001 | { 1002 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 1003 | "valueInteger": 4 1004 | }, 1005 | { 1006 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 1007 | "valueInteger": 0 1008 | }, 1009 | { 1010 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 1011 | "valueInteger": 0 1012 | }, 1013 | { 1014 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 1015 | "valueInteger": 0 1016 | } 1017 | ], 1018 | "identifier": [ 1019 | { 1020 | "system": "https://github.com/synthetichealth/synthea", 1021 | "value": "e3f1676b-9b40-3544-af4e-17a06bbb98bb" 1022 | } 1023 | ], 1024 | "active": true, 1025 | "type": [ 1026 | { 1027 | "coding": [ 1028 | { 1029 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 1030 | "code": "prov", 1031 | "display": "Healthcare Provider" 1032 | } 1033 | ], 1034 | "text": "Healthcare Provider" 1035 | } 1036 | ], 1037 | "name": "CODMAN SQUARE HEALTH CENTER", 1038 | "telecom": [ 1039 | { 1040 | "system": "phone", 1041 | "value": "617-825-9660" 1042 | } 1043 | ], 1044 | "address": [ 1045 | { 1046 | "line": [ 1047 | "637 WASHINGTON STREET" 1048 | ], 1049 | "city": "DORCHESTER", 1050 | "state": "MA", 1051 | "postalCode": "2124", 1052 | "country": "US" 1053 | } 1054 | ] 1055 | }, 1056 | "request": { 1057 | "method": "POST", 1058 | "url": "Organization" 1059 | } 1060 | }, 1061 | { 1062 | "fullUrl": "urn:uuid:d672f853-e2a5-324e-98fa-c6d5f8dfc255", 1063 | "resource": { 1064 | "resourceType": "Organization", 1065 | "id": "d672f853-e2a5-324e-98fa-c6d5f8dfc255", 1066 | "extension": [ 1067 | { 1068 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 1069 | "valueInteger": 2 1070 | }, 1071 | { 1072 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 1073 | "valueInteger": 0 1074 | }, 1075 | { 1076 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 1077 | "valueInteger": 0 1078 | }, 1079 | { 1080 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 1081 | "valueInteger": 0 1082 | } 1083 | ], 1084 | "identifier": [ 1085 | { 1086 | "system": "https://github.com/synthetichealth/synthea", 1087 | "value": "d672f853-e2a5-324e-98fa-c6d5f8dfc255" 1088 | } 1089 | ], 1090 | "active": true, 1091 | "type": [ 1092 | { 1093 | "coding": [ 1094 | { 1095 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 1096 | "code": "prov", 1097 | "display": "Healthcare Provider" 1098 | } 1099 | ], 1100 | "text": "Healthcare Provider" 1101 | } 1102 | ], 1103 | "name": "WALTHAM URGENT CARE", 1104 | "telecom": [ 1105 | { 1106 | "system": "phone", 1107 | "value": "617-243-5591" 1108 | } 1109 | ], 1110 | "address": [ 1111 | { 1112 | "line": [ 1113 | "9 HOPE AVENUE" 1114 | ], 1115 | "city": "WALTHAM", 1116 | "state": "MA", 1117 | "postalCode": "2453", 1118 | "country": "US" 1119 | } 1120 | ] 1121 | }, 1122 | "request": { 1123 | "method": "POST", 1124 | "url": "Organization" 1125 | } 1126 | }, 1127 | { 1128 | "fullUrl": "urn:uuid:1aedcb45-c507-3ad0-9010-6583d264ae72", 1129 | "resource": { 1130 | "resourceType": "Organization", 1131 | "id": "1aedcb45-c507-3ad0-9010-6583d264ae72", 1132 | "extension": [ 1133 | { 1134 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 1135 | "valueInteger": 1 1136 | }, 1137 | { 1138 | "url": "http://synthetichealth.github.io/synthea/utilization-procedures-extension", 1139 | "valueInteger": 0 1140 | }, 1141 | { 1142 | "url": "http://synthetichealth.github.io/synthea/utilization-labs-extension", 1143 | "valueInteger": 0 1144 | }, 1145 | { 1146 | "url": "http://synthetichealth.github.io/synthea/utilization-prescriptions-extension", 1147 | "valueInteger": 0 1148 | } 1149 | ], 1150 | "identifier": [ 1151 | { 1152 | "system": "https://github.com/synthetichealth/synthea", 1153 | "value": "1aedcb45-c507-3ad0-9010-6583d264ae72" 1154 | } 1155 | ], 1156 | "active": true, 1157 | "type": [ 1158 | { 1159 | "coding": [ 1160 | { 1161 | "system": "http://terminology.hl7.org/CodeSystem/organization-type", 1162 | "code": "prov", 1163 | "display": "Healthcare Provider" 1164 | } 1165 | ], 1166 | "text": "Healthcare Provider" 1167 | } 1168 | ], 1169 | "name": "PRIMA CARE / SOMERSET SWANSEA WALK IN CARE CENTER", 1170 | "telecom": [ 1171 | { 1172 | "system": "phone", 1173 | "value": "508-678-5631" 1174 | } 1175 | ], 1176 | "address": [ 1177 | { 1178 | "line": [ 1179 | "67 GRAND ARMY OF THE REPUBLIC HIGHWAY" 1180 | ], 1181 | "city": "SOMERSET", 1182 | "state": "MA", 1183 | "postalCode": "2726", 1184 | "country": "US" 1185 | } 1186 | ] 1187 | }, 1188 | "request": { 1189 | "method": "POST", 1190 | "url": "Organization" 1191 | } 1192 | } 1193 | ] 1194 | } 1195 | -------------------------------------------------------------------------------- /data/fhir/practitionerInformation1596649672088.json: -------------------------------------------------------------------------------- 1 | { 2 | "resourceType": "Bundle", 3 | "type": "transaction", 4 | "entry": [ 5 | { 6 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000000014", 7 | "resource": { 8 | "resourceType": "Practitioner", 9 | "id": "00000173-bfbc-8987-0000-000000000014", 10 | "extension": [ 11 | { 12 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 13 | "valueInteger": 7 14 | } 15 | ], 16 | "identifier": [ 17 | { 18 | "system": "http://hl7.org/fhir/sid/us-npi", 19 | "value": "20" 20 | } 21 | ], 22 | "active": true, 23 | "name": [ 24 | { 25 | "family": "Kemmer137", 26 | "given": [ 27 | "Xenia801" 28 | ], 29 | "prefix": [ 30 | "Dr." 31 | ] 32 | } 33 | ], 34 | "telecom": [ 35 | { 36 | "system": "email", 37 | "value": "Xenia801.Kemmer137@example.com", 38 | "use": "work" 39 | } 40 | ], 41 | "address": [ 42 | { 43 | "line": [ 44 | "211 PARK STREET" 45 | ], 46 | "city": "ATTLEBORO", 47 | "state": "MA", 48 | "postalCode": "02703", 49 | "country": "US" 50 | } 51 | ], 52 | "gender": "female" 53 | }, 54 | "request": { 55 | "method": "POST", 56 | "url": "Practitioner" 57 | } 58 | }, 59 | { 60 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000000050", 61 | "resource": { 62 | "resourceType": "Practitioner", 63 | "id": "00000173-bfbc-8987-0000-000000000050", 64 | "extension": [ 65 | { 66 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 67 | "valueInteger": 4 68 | } 69 | ], 70 | "identifier": [ 71 | { 72 | "system": "http://hl7.org/fhir/sid/us-npi", 73 | "value": "80" 74 | } 75 | ], 76 | "active": true, 77 | "name": [ 78 | { 79 | "family": "Sosa986", 80 | "given": [ 81 | "Agustín529" 82 | ], 83 | "prefix": [ 84 | "Dr." 85 | ] 86 | } 87 | ], 88 | "telecom": [ 89 | { 90 | "system": "email", 91 | "value": "Agustín529.Sosa986@example.com", 92 | "use": "work" 93 | } 94 | ], 95 | "address": [ 96 | { 97 | "line": [ 98 | "2100 DORCHESTER AVENUE" 99 | ], 100 | "city": "BOSTON", 101 | "state": "MA", 102 | "postalCode": "02124", 103 | "country": "US" 104 | } 105 | ], 106 | "gender": "male" 107 | }, 108 | "request": { 109 | "method": "POST", 110 | "url": "Practitioner" 111 | } 112 | }, 113 | { 114 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000000064", 115 | "resource": { 116 | "resourceType": "Practitioner", 117 | "id": "00000173-bfbc-8987-0000-000000000064", 118 | "extension": [ 119 | { 120 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 121 | "valueInteger": 12 122 | } 123 | ], 124 | "identifier": [ 125 | { 126 | "system": "http://hl7.org/fhir/sid/us-npi", 127 | "value": "100" 128 | } 129 | ], 130 | "active": true, 131 | "name": [ 132 | { 133 | "family": "Hermann103", 134 | "given": [ 135 | "Gaston250" 136 | ], 137 | "prefix": [ 138 | "Dr." 139 | ] 140 | } 141 | ], 142 | "telecom": [ 143 | { 144 | "system": "email", 145 | "value": "Gaston250.Hermann103@example.com", 146 | "use": "work" 147 | } 148 | ], 149 | "address": [ 150 | { 151 | "line": [ 152 | "795 MIDDLE STREET" 153 | ], 154 | "city": "FALL RIVER", 155 | "state": "MA", 156 | "postalCode": "02721", 157 | "country": "US" 158 | } 159 | ], 160 | "gender": "male" 161 | }, 162 | "request": { 163 | "method": "POST", 164 | "url": "Practitioner" 165 | } 166 | }, 167 | { 168 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-00000000012c", 169 | "resource": { 170 | "resourceType": "Practitioner", 171 | "id": "00000173-bfbc-8987-0000-00000000012c", 172 | "extension": [ 173 | { 174 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 175 | "valueInteger": 3 176 | } 177 | ], 178 | "identifier": [ 179 | { 180 | "system": "http://hl7.org/fhir/sid/us-npi", 181 | "value": "300" 182 | } 183 | ], 184 | "active": true, 185 | "name": [ 186 | { 187 | "family": "Fadel536", 188 | "given": [ 189 | "Ammie189" 190 | ], 191 | "prefix": [ 192 | "Dr." 193 | ] 194 | } 195 | ], 196 | "telecom": [ 197 | { 198 | "system": "email", 199 | "value": "Ammie189.Fadel536@example.com", 200 | "use": "work" 201 | } 202 | ], 203 | "address": [ 204 | { 205 | "line": [ 206 | "363 HIGHLAND AVENUE" 207 | ], 208 | "city": "FALL RIVER", 209 | "state": "MA", 210 | "postalCode": "02720", 211 | "country": "US" 212 | } 213 | ], 214 | "gender": "female" 215 | }, 216 | "request": { 217 | "method": "POST", 218 | "url": "Practitioner" 219 | } 220 | }, 221 | { 222 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000000154", 223 | "resource": { 224 | "resourceType": "Practitioner", 225 | "id": "00000173-bfbc-8987-0000-000000000154", 226 | "extension": [ 227 | { 228 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 229 | "valueInteger": 236 230 | } 231 | ], 232 | "identifier": [ 233 | { 234 | "system": "http://hl7.org/fhir/sid/us-npi", 235 | "value": "340" 236 | } 237 | ], 238 | "active": true, 239 | "name": [ 240 | { 241 | "family": "Rogahn59", 242 | "given": [ 243 | "Julius90" 244 | ], 245 | "prefix": [ 246 | "Dr." 247 | ] 248 | } 249 | ], 250 | "telecom": [ 251 | { 252 | "system": "email", 253 | "value": "Julius90.Rogahn59@example.com", 254 | "use": "work" 255 | } 256 | ], 257 | "address": [ 258 | { 259 | "line": [ 260 | "148 CHESTNUT STREET" 261 | ], 262 | "city": "NEEDHAM", 263 | "state": "MA", 264 | "postalCode": "02494", 265 | "country": "US" 266 | } 267 | ], 268 | "gender": "male" 269 | }, 270 | "request": { 271 | "method": "POST", 272 | "url": "Practitioner" 273 | } 274 | }, 275 | { 276 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000000190", 277 | "resource": { 278 | "resourceType": "Practitioner", 279 | "id": "00000173-bfbc-8987-0000-000000000190", 280 | "extension": [ 281 | { 282 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 283 | "valueInteger": 35 284 | } 285 | ], 286 | "identifier": [ 287 | { 288 | "system": "http://hl7.org/fhir/sid/us-npi", 289 | "value": "400" 290 | } 291 | ], 292 | "active": true, 293 | "name": [ 294 | { 295 | "family": "Stanton715", 296 | "given": [ 297 | "Danica886" 298 | ], 299 | "prefix": [ 300 | "Dr." 301 | ] 302 | } 303 | ], 304 | "telecom": [ 305 | { 306 | "system": "email", 307 | "value": "Danica886.Stanton715@example.com", 308 | "use": "work" 309 | } 310 | ], 311 | "address": [ 312 | { 313 | "line": [ 314 | "200 GROTON ROAD" 315 | ], 316 | "city": "AYER", 317 | "state": "MA", 318 | "postalCode": "01432", 319 | "country": "US" 320 | } 321 | ], 322 | "gender": "female" 323 | }, 324 | "request": { 325 | "method": "POST", 326 | "url": "Practitioner" 327 | } 328 | }, 329 | { 330 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-0000000001e0", 331 | "resource": { 332 | "resourceType": "Practitioner", 333 | "id": "00000173-bfbc-8987-0000-0000000001e0", 334 | "extension": [ 335 | { 336 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 337 | "valueInteger": 46 338 | } 339 | ], 340 | "identifier": [ 341 | { 342 | "system": "http://hl7.org/fhir/sid/us-npi", 343 | "value": "480" 344 | } 345 | ], 346 | "active": true, 347 | "name": [ 348 | { 349 | "family": "Thompson596", 350 | "given": [ 351 | "Ethelyn789" 352 | ], 353 | "prefix": [ 354 | "Dr." 355 | ] 356 | } 357 | ], 358 | "telecom": [ 359 | { 360 | "system": "email", 361 | "value": "Ethelyn789.Thompson596@example.com", 362 | "use": "work" 363 | } 364 | ], 365 | "address": [ 366 | { 367 | "line": [ 368 | "1153 CENTRE STREET" 369 | ], 370 | "city": "BOSTON", 371 | "state": "MA", 372 | "postalCode": "02130", 373 | "country": "US" 374 | } 375 | ], 376 | "gender": "female" 377 | }, 378 | "request": { 379 | "method": "POST", 380 | "url": "Practitioner" 381 | } 382 | }, 383 | { 384 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-00000000026c", 385 | "resource": { 386 | "resourceType": "Practitioner", 387 | "id": "00000173-bfbc-8987-0000-00000000026c", 388 | "extension": [ 389 | { 390 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 391 | "valueInteger": 11 392 | } 393 | ], 394 | "identifier": [ 395 | { 396 | "system": "http://hl7.org/fhir/sid/us-npi", 397 | "value": "620" 398 | } 399 | ], 400 | "active": true, 401 | "name": [ 402 | { 403 | "family": "Gaylord332", 404 | "given": [ 405 | "Fiona703" 406 | ], 407 | "prefix": [ 408 | "Dr." 409 | ] 410 | } 411 | ], 412 | "telecom": [ 413 | { 414 | "system": "email", 415 | "value": "Fiona703.Gaylord332@example.com", 416 | "use": "work" 417 | } 418 | ], 419 | "address": [ 420 | { 421 | "line": [ 422 | "51 BLOSSOM STREET" 423 | ], 424 | "city": "BOSTON", 425 | "state": "MA", 426 | "postalCode": "02114", 427 | "country": "US" 428 | } 429 | ], 430 | "gender": "female" 431 | }, 432 | "request": { 433 | "method": "POST", 434 | "url": "Practitioner" 435 | } 436 | }, 437 | { 438 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-00000000094c", 439 | "resource": { 440 | "resourceType": "Practitioner", 441 | "id": "00000173-bfbc-8987-0000-00000000094c", 442 | "extension": [ 443 | { 444 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 445 | "valueInteger": 56 446 | } 447 | ], 448 | "identifier": [ 449 | { 450 | "system": "http://hl7.org/fhir/sid/us-npi", 451 | "value": "2380" 452 | } 453 | ], 454 | "active": true, 455 | "name": [ 456 | { 457 | "family": "O'Hara248", 458 | "given": [ 459 | "Bradford382" 460 | ], 461 | "prefix": [ 462 | "Dr." 463 | ] 464 | } 465 | ], 466 | "telecom": [ 467 | { 468 | "system": "email", 469 | "value": "Bradford382.O'Hara248@example.com", 470 | "use": "work" 471 | } 472 | ], 473 | "address": [ 474 | { 475 | "line": [ 476 | "102 WESTLAND RD" 477 | ], 478 | "city": "WESTON", 479 | "state": "MA", 480 | "postalCode": "02493-1341", 481 | "country": "US" 482 | } 483 | ], 484 | "gender": "male" 485 | }, 486 | "request": { 487 | "method": "POST", 488 | "url": "Practitioner" 489 | } 490 | }, 491 | { 492 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000000c08", 493 | "resource": { 494 | "resourceType": "Practitioner", 495 | "id": "00000173-bfbc-8987-0000-000000000c08", 496 | "extension": [ 497 | { 498 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 499 | "valueInteger": 55 500 | } 501 | ], 502 | "identifier": [ 503 | { 504 | "system": "http://hl7.org/fhir/sid/us-npi", 505 | "value": "3080" 506 | } 507 | ], 508 | "active": true, 509 | "name": [ 510 | { 511 | "family": "Kihn564", 512 | "given": [ 513 | "Linn541" 514 | ], 515 | "prefix": [ 516 | "Dr." 517 | ] 518 | } 519 | ], 520 | "telecom": [ 521 | { 522 | "system": "email", 523 | "value": "Linn541.Kihn564@example.com", 524 | "use": "work" 525 | } 526 | ], 527 | "address": [ 528 | { 529 | "line": [ 530 | "2 SHAKER RD" 531 | ], 532 | "city": "SHIRLEY", 533 | "state": "MA", 534 | "postalCode": "01464-2561", 535 | "country": "US" 536 | } 537 | ], 538 | "gender": "female" 539 | }, 540 | "request": { 541 | "method": "POST", 542 | "url": "Practitioner" 543 | } 544 | }, 545 | { 546 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000009e84", 547 | "resource": { 548 | "resourceType": "Practitioner", 549 | "id": "00000173-bfbc-8987-0000-000000009e84", 550 | "extension": [ 551 | { 552 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 553 | "valueInteger": 20 554 | } 555 | ], 556 | "identifier": [ 557 | { 558 | "system": "http://hl7.org/fhir/sid/us-npi", 559 | "value": "40580" 560 | } 561 | ], 562 | "active": true, 563 | "name": [ 564 | { 565 | "family": "Nicolas769", 566 | "given": [ 567 | "Emilia403" 568 | ], 569 | "prefix": [ 570 | "Dr." 571 | ] 572 | } 573 | ], 574 | "telecom": [ 575 | { 576 | "system": "email", 577 | "value": "Emilia403.Nicolas769@example.com", 578 | "use": "work" 579 | } 580 | ], 581 | "address": [ 582 | { 583 | "line": [ 584 | "440 SWANSEA MALL DR" 585 | ], 586 | "city": "SWANSEA", 587 | "state": "MA", 588 | "postalCode": "02777-4114", 589 | "country": "US" 590 | } 591 | ], 592 | "gender": "female" 593 | }, 594 | "request": { 595 | "method": "POST", 596 | "url": "Practitioner" 597 | } 598 | }, 599 | { 600 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-00000000dfd4", 601 | "resource": { 602 | "resourceType": "Practitioner", 603 | "id": "00000173-bfbc-8987-0000-00000000dfd4", 604 | "extension": [ 605 | { 606 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 607 | "valueInteger": 30 608 | } 609 | ], 610 | "identifier": [ 611 | { 612 | "system": "http://hl7.org/fhir/sid/us-npi", 613 | "value": "57300" 614 | } 615 | ], 616 | "active": true, 617 | "name": [ 618 | { 619 | "family": "Zboncak558", 620 | "given": [ 621 | "Denny560" 622 | ], 623 | "prefix": [ 624 | "Dr." 625 | ] 626 | } 627 | ], 628 | "telecom": [ 629 | { 630 | "system": "email", 631 | "value": "Denny560.Zboncak558@example.com", 632 | "use": "work" 633 | } 634 | ], 635 | "address": [ 636 | { 637 | "line": [ 638 | "77 WARREN ST 1ST FLOOR AND 2ND FLOOR" 639 | ], 640 | "city": "BRIGHTON", 641 | "state": "MA", 642 | "postalCode": "02135-3601", 643 | "country": "US" 644 | } 645 | ], 646 | "gender": "male" 647 | }, 648 | "request": { 649 | "method": "POST", 650 | "url": "Practitioner" 651 | } 652 | }, 653 | { 654 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000010554", 655 | "resource": { 656 | "resourceType": "Practitioner", 657 | "id": "00000173-bfbc-8987-0000-000000010554", 658 | "extension": [ 659 | { 660 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 661 | "valueInteger": 64 662 | } 663 | ], 664 | "identifier": [ 665 | { 666 | "system": "http://hl7.org/fhir/sid/us-npi", 667 | "value": "66900" 668 | } 669 | ], 670 | "active": true, 671 | "name": [ 672 | { 673 | "family": "Altenwerth646", 674 | "given": [ 675 | "Jason347" 676 | ], 677 | "prefix": [ 678 | "Dr." 679 | ] 680 | } 681 | ], 682 | "telecom": [ 683 | { 684 | "system": "email", 685 | "value": "Jason347.Altenwerth646@example.com", 686 | "use": "work" 687 | } 688 | ], 689 | "address": [ 690 | { 691 | "line": [ 692 | "99 NORUMBEGA RD" 693 | ], 694 | "city": "WESTON", 695 | "state": "MA", 696 | "postalCode": "02493-2482", 697 | "country": "US" 698 | } 699 | ], 700 | "gender": "male" 701 | }, 702 | "request": { 703 | "method": "POST", 704 | "url": "Practitioner" 705 | } 706 | }, 707 | { 708 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000010b94", 709 | "resource": { 710 | "resourceType": "Practitioner", 711 | "id": "00000173-bfbc-8987-0000-000000010b94", 712 | "extension": [ 713 | { 714 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 715 | "valueInteger": 53 716 | } 717 | ], 718 | "identifier": [ 719 | { 720 | "system": "http://hl7.org/fhir/sid/us-npi", 721 | "value": "68500" 722 | } 723 | ], 724 | "active": true, 725 | "name": [ 726 | { 727 | "family": "Thompson596", 728 | "given": [ 729 | "Merideth332" 730 | ], 731 | "prefix": [ 732 | "Dr." 733 | ] 734 | } 735 | ], 736 | "telecom": [ 737 | { 738 | "system": "email", 739 | "value": "Merideth332.Thompson596@example.com", 740 | "use": "work" 741 | } 742 | ], 743 | "address": [ 744 | { 745 | "line": [ 746 | "67 SLADE'S FERRY BOULEVARD" 747 | ], 748 | "city": "SOMERSET", 749 | "state": "MA", 750 | "postalCode": "02726-1220", 751 | "country": "US" 752 | } 753 | ], 754 | "gender": "female" 755 | }, 756 | "request": { 757 | "method": "POST", 758 | "url": "Practitioner" 759 | } 760 | }, 761 | { 762 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000016c42", 763 | "resource": { 764 | "resourceType": "Practitioner", 765 | "id": "00000173-bfbc-8987-0000-000000016c42", 766 | "extension": [ 767 | { 768 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 769 | "valueInteger": 1 770 | } 771 | ], 772 | "identifier": [ 773 | { 774 | "system": "http://hl7.org/fhir/sid/us-npi", 775 | "value": "93250" 776 | } 777 | ], 778 | "active": true, 779 | "name": [ 780 | { 781 | "family": "Sosa986", 782 | "given": [ 783 | "Agustín529" 784 | ], 785 | "prefix": [ 786 | "Dr." 787 | ] 788 | } 789 | ], 790 | "telecom": [ 791 | { 792 | "system": "email", 793 | "value": "Agustín529.Sosa986@example.com", 794 | "use": "work" 795 | } 796 | ], 797 | "address": [ 798 | { 799 | "line": [ 800 | "1589 FALL RIVER AVENUE" 801 | ], 802 | "city": "SEEKONK", 803 | "state": "MA", 804 | "postalCode": "2771", 805 | "country": "US" 806 | } 807 | ], 808 | "gender": "male" 809 | }, 810 | "request": { 811 | "method": "POST", 812 | "url": "Practitioner" 813 | } 814 | }, 815 | { 816 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000016cb0", 817 | "resource": { 818 | "resourceType": "Practitioner", 819 | "id": "00000173-bfbc-8987-0000-000000016cb0", 820 | "extension": [ 821 | { 822 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 823 | "valueInteger": 4 824 | } 825 | ], 826 | "identifier": [ 827 | { 828 | "system": "http://hl7.org/fhir/sid/us-npi", 829 | "value": "93360" 830 | } 831 | ], 832 | "active": true, 833 | "name": [ 834 | { 835 | "family": "Huel628", 836 | "given": [ 837 | "Derek111" 838 | ], 839 | "prefix": [ 840 | "Dr." 841 | ] 842 | } 843 | ], 844 | "telecom": [ 845 | { 846 | "system": "email", 847 | "value": "Derek111.Huel628@example.com", 848 | "use": "work" 849 | } 850 | ], 851 | "address": [ 852 | { 853 | "line": [ 854 | "637 WASHINGTON STREET" 855 | ], 856 | "city": "DORCHESTER", 857 | "state": "MA", 858 | "postalCode": "2124", 859 | "country": "US" 860 | } 861 | ], 862 | "gender": "male" 863 | }, 864 | "request": { 865 | "method": "POST", 866 | "url": "Practitioner" 867 | } 868 | }, 869 | { 870 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000016d00", 871 | "resource": { 872 | "resourceType": "Practitioner", 873 | "id": "00000173-bfbc-8987-0000-000000016d00", 874 | "extension": [ 875 | { 876 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 877 | "valueInteger": 2 878 | } 879 | ], 880 | "identifier": [ 881 | { 882 | "system": "http://hl7.org/fhir/sid/us-npi", 883 | "value": "93440" 884 | } 885 | ], 886 | "active": true, 887 | "name": [ 888 | { 889 | "family": "Spencer878", 890 | "given": [ 891 | "Randell912" 892 | ], 893 | "prefix": [ 894 | "Dr." 895 | ] 896 | } 897 | ], 898 | "telecom": [ 899 | { 900 | "system": "email", 901 | "value": "Randell912.Spencer878@example.com", 902 | "use": "work" 903 | } 904 | ], 905 | "address": [ 906 | { 907 | "line": [ 908 | "9 HOPE AVENUE" 909 | ], 910 | "city": "WALTHAM", 911 | "state": "MA", 912 | "postalCode": "2453", 913 | "country": "US" 914 | } 915 | ], 916 | "gender": "male" 917 | }, 918 | "request": { 919 | "method": "POST", 920 | "url": "Practitioner" 921 | } 922 | }, 923 | { 924 | "fullUrl": "urn:uuid:00000173-bfbc-8987-0000-000000016d96", 925 | "resource": { 926 | "resourceType": "Practitioner", 927 | "id": "00000173-bfbc-8987-0000-000000016d96", 928 | "extension": [ 929 | { 930 | "url": "http://synthetichealth.github.io/synthea/utilization-encounters-extension", 931 | "valueInteger": 1 932 | } 933 | ], 934 | "identifier": [ 935 | { 936 | "system": "http://hl7.org/fhir/sid/us-npi", 937 | "value": "93590" 938 | } 939 | ], 940 | "active": true, 941 | "name": [ 942 | { 943 | "family": "Davis923", 944 | "given": [ 945 | "Darryl392" 946 | ], 947 | "prefix": [ 948 | "Dr." 949 | ] 950 | } 951 | ], 952 | "telecom": [ 953 | { 954 | "system": "email", 955 | "value": "Darryl392.Davis923@example.com", 956 | "use": "work" 957 | } 958 | ], 959 | "address": [ 960 | { 961 | "line": [ 962 | "67 GRAND ARMY OF THE REPUBLIC HIGHWAY" 963 | ], 964 | "city": "SOMERSET", 965 | "state": "MA", 966 | "postalCode": "2726", 967 | "country": "US" 968 | } 969 | ], 970 | "gender": "male" 971 | }, 972 | "request": { 973 | "method": "POST", 974 | "url": "Practitioner" 975 | } 976 | } 977 | ] 978 | } 979 | -------------------------------------------------------------------------------- /dev.md: -------------------------------------------------------------------------------- 1 | # useful commands 2 | ## clean up docker 3 | ``` 4 | docker system prune -f 5 | ``` 6 | 7 | ## build container with no cache 8 | ``` 9 | docker compose build --no-cache --progress=plain 10 | ``` 11 | 12 | ## start container 13 | ``` 14 | docker compose up -d 15 | ``` 16 | 17 | ## open terminal to docker 18 | ``` 19 | docker compose exec iris iris session iris -U FHIRServer 20 | ``` 21 | 22 | ## FHIR Namespace setup 23 | 24 | Do ##class(HS.Util.Installer.Foundation).Install(namespace) 25 | 26 | 27 | ## fhir server configuration setup 28 | ``` 29 | do ##class(HS.FHIRServer.ConsoleSetup).Setup() 30 | ``` 31 | 32 | ## load fhir resources 33 | ``` 34 | zw ##class(HS.FHIRServer.Tools.DataLoader).SubmitResourceFiles("/irisdev/app/output/fhir/", "FHIRServer", "/fhir/r4") 35 | 36 | kill ^%ISCLOG 37 | 38 | kill ^ISCLOG 39 | 40 | set ^%ISCLOG=3 41 | 42 | 43 | 44 | http://localhost:32783/fhirUI/irisfhir.json 45 | http://localhost:32783/fhirUI/irisfhir_swagger.json 46 | 47 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | 2 | services: 3 | iris: 4 | build: 5 | context: . 6 | dockerfile: Dockerfile 7 | restart: always 8 | hostname: fhir-template 9 | container_name: fhir-template 10 | # command: --check-caps false 11 | ports: 12 | - 32782:1972 13 | - 32783:52773 14 | - 32784:53773 15 | command: 16 | - -a 17 | - iris session iris -U%SYS '##class(Security.Users).UnExpireUserPasswords("*")' 18 | - --check-caps false 19 | volumes: 20 | - ./data:/data 21 | - ./fhirUI:/usr/irissys/csp/fhirUI 22 | - ./:/home/irisowner/irisdev -------------------------------------------------------------------------------- /fhirUI/FHIRAppDemo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | GS2019 FHIR App 6 | 7 | 8 | 9 | 20 | 21 | 22 | 23 |

Patients with Anemia

24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
NameID
32 |
33 |
Patient ID:
34 |

Hemoglobin in Blood (g/dL)

35 |
36 | 37 | 133 | 134 | -------------------------------------------------------------------------------- /fhirUI/jqFhir.js: -------------------------------------------------------------------------------- 1 | (function webpackUniversalModuleDefinition(root, factory) { 2 | if(typeof exports === 'object' && typeof module === 'object') 3 | module.exports = factory(); 4 | else if(typeof define === 'function' && define.amd) 5 | define([], factory); 6 | else if(typeof exports === 'object') 7 | exports["fhir"] = factory(); 8 | else 9 | root["fhir"] = factory(); 10 | })(this, function() { 11 | return /******/ (function(modules) { // webpackBootstrap 12 | /******/ // The module cache 13 | /******/ var installedModules = {}; 14 | 15 | /******/ // The require function 16 | /******/ function __webpack_require__(moduleId) { 17 | 18 | /******/ // Check if module is in cache 19 | /******/ if(installedModules[moduleId]) 20 | /******/ return installedModules[moduleId].exports; 21 | 22 | /******/ // Create a new module (and put it into the cache) 23 | /******/ var module = installedModules[moduleId] = { 24 | /******/ exports: {}, 25 | /******/ id: moduleId, 26 | /******/ loaded: false 27 | /******/ }; 28 | 29 | /******/ // Execute the module function 30 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); 31 | 32 | /******/ // Flag the module as loaded 33 | /******/ module.loaded = true; 34 | 35 | /******/ // Return the exports of the module 36 | /******/ return module.exports; 37 | /******/ } 38 | 39 | 40 | /******/ // expose the modules object (__webpack_modules__) 41 | /******/ __webpack_require__.m = modules; 42 | 43 | /******/ // expose the module cache 44 | /******/ __webpack_require__.c = installedModules; 45 | 46 | /******/ // __webpack_public_path__ 47 | /******/ __webpack_require__.p = ""; 48 | 49 | /******/ // Load entry module and return exports 50 | /******/ return __webpack_require__(0); 51 | /******/ }) 52 | /************************************************************************/ 53 | /******/ ([ 54 | /* 0 */ 55 | /***/ (function(module, exports, __webpack_require__) { 56 | 57 | (function() { 58 | var mkFhir = __webpack_require__(1); 59 | var jquery = window['_jQuery'] || window['jQuery']; 60 | 61 | var defer = function(){ 62 | pr = jquery.Deferred(); 63 | pr.promise = pr.promise(); 64 | return pr; 65 | }; 66 | var adapter = { 67 | defer: defer, 68 | http: function(args) { 69 | var ret = jquery.Deferred(); 70 | var opts = { 71 | type: args.method, 72 | url: args.url, 73 | headers: args.headers, 74 | dataType: "json", 75 | contentType: "application/json", 76 | data: args.data || args.params, 77 | withCredentials: args.credentials === 'include', 78 | }; 79 | jquery.ajax(opts) 80 | .done(function(data, status, xhr) {ret.resolve({data: data, status: status, headers: xhr.getResponseHeader, config: args});}) 81 | .fail(function(err) {ret.reject({error: err, data: err, config: args});}); 82 | return ret.promise(); 83 | } 84 | }; 85 | 86 | var fhir = function(config) { 87 | return mkFhir(config, adapter); 88 | }; 89 | fhir.defer = defer; 90 | module.exports = fhir; 91 | 92 | }).call(this); 93 | 94 | 95 | /***/ }), 96 | /* 1 */ 97 | /***/ (function(module, exports, __webpack_require__) { 98 | 99 | (function() { 100 | var utils = __webpack_require__(2); 101 | var M = __webpack_require__(5); 102 | var query = __webpack_require__(6); 103 | var auth = __webpack_require__(7); 104 | var transport = __webpack_require__(9); 105 | var errors = __webpack_require__(10); 106 | var config = __webpack_require__(11); 107 | var bundle = __webpack_require__(12); 108 | var pt = __webpack_require__(13); 109 | var refs = __webpack_require__(14); 110 | var url = __webpack_require__(15); 111 | var decorate = __webpack_require__(16); 112 | 113 | var cache = {}; 114 | 115 | 116 | var fhir = function(cfg, adapter){ 117 | var Middleware = M.Middleware; 118 | var $$Attr = M.$$Attr; 119 | 120 | var $$Method = function(m){ return $$Attr('method', m);}; 121 | var $$Header = function(h,v) {return $$Attr('headers.' + h, v);}; 122 | 123 | var $Errors = Middleware(errors); 124 | var Defaults = Middleware(config(cfg, adapter)) 125 | .and($Errors) 126 | .and(auth.$Basic) 127 | .and(auth.$Bearer) 128 | .and(auth.$Credentials) 129 | .and(transport.$JsonData) 130 | .and($$Header('Accept', (cfg.headers && cfg.headers['Accept']) ? cfg.headers['Accept'] : 'application/json')) 131 | .and($$Header('Content-Type', (cfg.headers && cfg.headers['Content-Type']) ? cfg.headers['Content-Type'] : 'application/json')); 132 | 133 | var GET = Defaults.and($$Method('GET')); 134 | var POST = Defaults.and($$Method('POST')); 135 | var PUT = Defaults.and($$Method('PUT')); 136 | var DELETE = Defaults.and($$Method('DELETE')); 137 | var PATCH = Defaults.and($$Method('PATCH')); 138 | 139 | var http = transport.Http(cfg, adapter); 140 | 141 | var Path = url.Path; 142 | var BaseUrl = Path(cfg.baseUrl); 143 | var resourceTypePath = BaseUrl.slash(":type || :resource.resourceType"); 144 | var searchPath = resourceTypePath; 145 | var resourceTypeHxPath = resourceTypePath.slash("_history"); 146 | var resourcePath = resourceTypePath.slash(":id || :resource.id"); 147 | var resourceHxPath = resourcePath.slash("_history"); 148 | var vreadPath = resourcePath.slash(":versionId || :resource.meta.versionId"); 149 | var metaTarget = BaseUrl.slash(":target.resourceType || :target.type").slash(":target.id").slash(':target.versionId'); 150 | 151 | var ReturnHeader = $$Header('Prefer', 'return=representation'); 152 | 153 | var $Paging = Middleware(query.$Paging); 154 | 155 | return decorate({ 156 | conformance: GET.and(BaseUrl.slash("metadata")).end(http), 157 | document: POST.and(BaseUrl.slash("Document")).end(http), 158 | profile: GET.and(BaseUrl.slash("Profile").slash(":type")).end(http), 159 | transaction: POST.and(BaseUrl).end(http), 160 | history: GET.and(BaseUrl.slash("_history")).and($Paging).end(http), 161 | typeHistory: GET.and(resourceTypeHxPath).and($Paging).end(http), 162 | resourceHistory: GET.and(resourceHxPath).and($Paging).end(http), 163 | read: GET.and(pt.$WithPatient).and(resourcePath).end(http), 164 | vread: GET.and(vreadPath).end(http), 165 | "delete": DELETE.and(resourcePath).and(ReturnHeader).end(http), 166 | create: POST.and(resourceTypePath).and(ReturnHeader).end(http), 167 | validate: POST.and(resourceTypePath.slash("_validate")).end(http), 168 | meta: { 169 | add: POST.and(metaTarget.slash("$meta-add")).end(http), 170 | delete: POST.and(metaTarget.slash("$meta-delete")).end(http), 171 | read: GET.and(metaTarget.slash("$meta")).end(http) 172 | }, 173 | search: GET.and(resourceTypePath).and(pt.$WithPatient).and(query.$SearchParams).and($Paging).end(http), 174 | update: PUT.and(resourcePath).and(ReturnHeader).end(http), 175 | conditionalUpdate: PUT.and(resourceTypePath).and(query.$SearchParams).and(ReturnHeader).end(http), 176 | nextPage: GET.and(bundle.$$BundleLinkUrl("next")).end(http), 177 | // For previous page, bundle.link.relation can either have 'previous' or 'prev' values 178 | prevPage: GET.and(bundle.$$BundleLinkUrl("previous")).and(bundle.$$BundleLinkUrl("prev")).end(http), 179 | getBundleByUrl: GET.and(Path(":url")).end(http), 180 | resolve: GET.and(refs.resolve).end(http), 181 | patch: PATCH.and(resourcePath).and($$Header('Content-Type', 'application/json-patch+json')).end(http) 182 | }, adapter); 183 | }; 184 | module.exports = fhir; 185 | }).call(this); 186 | 187 | 188 | /***/ }), 189 | /* 2 */ 190 | /***/ (function(module, exports, __webpack_require__) { 191 | 192 | (function() { 193 | var merge = __webpack_require__(3); 194 | 195 | var RTRIM = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g; 196 | 197 | var trim = function(text) { 198 | return text ? text.toString().replace(RTRIM, "") : ""; 199 | }; 200 | 201 | exports.trim = trim; 202 | 203 | var addKey = function(acc, str) { 204 | var pair, val; 205 | if (!str) { 206 | return null; 207 | } 208 | pair = str.split("=").map(trim); 209 | val = pair[1].replace(/(^"|"$)/g, ''); 210 | if (val) { 211 | acc[pair[0]] = val; 212 | } 213 | return acc; 214 | }; 215 | 216 | var type = function(obj) { 217 | var classToType; 218 | if (obj == null && obj === undefined) { 219 | return String(obj); 220 | } 221 | classToType = { 222 | '[object Boolean]': 'boolean', 223 | '[object Number]': 'number', 224 | '[object String]': 'string', 225 | '[object Function]': 'function', 226 | '[object Array]': 'array', 227 | '[object Date]': 'date', 228 | '[object RegExp]': 'regexp', 229 | '[object Object]': 'object' 230 | }; 231 | return classToType[Object.prototype.toString.call(obj)]; 232 | }; 233 | 234 | exports.type = type; 235 | 236 | var assertArray = function(a) { 237 | if (type(a) !== 'array') { 238 | throw 'not array'; 239 | } 240 | return a; 241 | }; 242 | 243 | exports.assertArray = assertArray; 244 | 245 | var assertObject = function(a) { 246 | if (type(a) !== 'object') { 247 | throw 'not object'; 248 | } 249 | return a; 250 | }; 251 | 252 | exports.assertObject = assertObject; 253 | 254 | var reduceMap = function(m, fn, acc) { 255 | var k, v; 256 | acc || (acc = []); 257 | assertObject(m); 258 | return ((function() { 259 | var results; 260 | results = []; 261 | for (k in m) { 262 | v = m[k]; 263 | results.push([k, v]); 264 | } 265 | return results; 266 | })()).reduce(fn, acc); 267 | }; 268 | 269 | exports.reduceMap = reduceMap; 270 | 271 | var identity = function(x) {return x;}; 272 | 273 | exports.identity = identity; 274 | 275 | var argsArray = function() { 276 | return Array.prototype.slice.call(arguments) 277 | }; 278 | 279 | exports.argsArray = argsArray; 280 | 281 | var mergeLists = function() { 282 | var reduce; 283 | reduce = function(merged, nextMap) { 284 | var k, ret, v; 285 | ret = merge(true, merged); 286 | for (k in nextMap) { 287 | v = nextMap[k]; 288 | ret[k] = (ret[k] || []).concat(v); 289 | } 290 | return ret; 291 | }; 292 | return argsArray.apply(null, arguments).reduce(reduce, {}); 293 | }; 294 | 295 | exports.mergeLists = mergeLists; 296 | 297 | var absoluteUrl = function(baseUrl, ref) { 298 | if (!ref.match(/https?:\/\/./)) { 299 | return baseUrl + "/" + ref; 300 | } else { 301 | return ref; 302 | } 303 | }; 304 | 305 | exports.absoluteUrl = absoluteUrl; 306 | 307 | var relativeUrl = function(baseUrl, ref) { 308 | if (ref.slice(ref, baseUrl.length + 1) === baseUrl + "/") { 309 | return ref.slice(baseUrl.length + 1); 310 | } else { 311 | return ref; 312 | } 313 | }; 314 | 315 | exports.relativeUrl = relativeUrl; 316 | 317 | exports.resourceIdToUrl = function(id, baseUrl, type) { 318 | baseUrl = baseUrl.replace(/\/$/, ''); 319 | id = id.replace(/^\//, ''); 320 | if (id.indexOf('/') < 0) { 321 | return baseUrl + "/" + type + "/" + id; 322 | } else if (id.indexOf(baseUrl) !== 0) { 323 | return baseUrl + "/" + id; 324 | } else { 325 | return id; 326 | } 327 | }; 328 | 329 | var walk = function(inner, outer, data, context) { 330 | var keysToMap, remapped; 331 | switch (type(data)) { 332 | case 'array': 333 | return outer(data.map(function(item) { 334 | return inner(item, [data, context]); 335 | }), context); 336 | case 'object': 337 | keysToMap = function(acc, arg) { 338 | var k, v; 339 | k = arg[0], v = arg[1]; 340 | acc[k] = inner(v, [data].concat(context)); 341 | return acc; 342 | }; 343 | remapped = reduceMap(data, keysToMap, {}); 344 | return outer(remapped, context); 345 | default: 346 | return outer(data, context); 347 | } 348 | }; 349 | 350 | exports.walk = walk; 351 | 352 | var postwalk = function(f, data, context) { 353 | if (!data) { 354 | return function(data, context) { 355 | return postwalk(f, data, context); 356 | }; 357 | } else { 358 | return walk(postwalk(f), f, data, context); 359 | } 360 | }; 361 | 362 | exports.postwalk = postwalk; 363 | 364 | }).call(this); 365 | 366 | 367 | /***/ }), 368 | /* 3 */ 369 | /***/ (function(module, exports, __webpack_require__) { 370 | 371 | /* WEBPACK VAR INJECTION */(function(module) {/*! 372 | * @name JavaScript/NodeJS Merge v1.2.1 373 | * @author yeikos 374 | * @repository https://github.com/yeikos/js.merge 375 | 376 | * Copyright 2014 yeikos - MIT license 377 | * https://raw.github.com/yeikos/js.merge/master/LICENSE 378 | */ 379 | 380 | ;(function(isNode) { 381 | 382 | /** 383 | * Merge one or more objects 384 | * @param bool? clone 385 | * @param mixed,... arguments 386 | * @return object 387 | */ 388 | 389 | var Public = function(clone) { 390 | 391 | return merge(clone === true, false, arguments); 392 | 393 | }, publicName = 'merge'; 394 | 395 | /** 396 | * Merge two or more objects recursively 397 | * @param bool? clone 398 | * @param mixed,... arguments 399 | * @return object 400 | */ 401 | 402 | Public.recursive = function(clone) { 403 | 404 | return merge(clone === true, true, arguments); 405 | 406 | }; 407 | 408 | /** 409 | * Clone the input removing any reference 410 | * @param mixed input 411 | * @return mixed 412 | */ 413 | 414 | Public.clone = function(input) { 415 | 416 | var output = input, 417 | type = typeOf(input), 418 | index, size; 419 | 420 | if (type === 'array') { 421 | 422 | output = []; 423 | size = input.length; 424 | 425 | for (index=0;index -1 ){ 909 | return credentials; 910 | } 911 | })); 912 | 913 | }).call(this); 914 | 915 | 916 | /***/ }), 917 | /* 8 */ 918 | /***/ (function(module, exports, __webpack_require__) { 919 | 920 | ;(function () { 921 | 922 | var object = true ? exports : this; // #8: web workers 923 | var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; 924 | 925 | function InvalidCharacterError(message) { 926 | this.message = message; 927 | } 928 | InvalidCharacterError.prototype = new Error; 929 | InvalidCharacterError.prototype.name = 'InvalidCharacterError'; 930 | 931 | // encoder 932 | // [https://gist.github.com/999166] by [https://github.com/nignag] 933 | object.btoa || ( 934 | object.btoa = function (input) { 935 | var str = String(input); 936 | for ( 937 | // initialize result and counter 938 | var block, charCode, idx = 0, map = chars, output = ''; 939 | // if the next str index does not exist: 940 | // change the mapping table to "=" 941 | // check if d has no fractional digits 942 | str.charAt(idx | 0) || (map = '=', idx % 1); 943 | // "8 - idx % 1 * 8" generates the sequence 2, 4, 6, 8 944 | output += map.charAt(63 & block >> 8 - idx % 1 * 8) 945 | ) { 946 | charCode = str.charCodeAt(idx += 3/4); 947 | if (charCode > 0xFF) { 948 | throw new InvalidCharacterError("'btoa' failed: The string to be encoded contains characters outside of the Latin1 range."); 949 | } 950 | block = block << 8 | charCode; 951 | } 952 | return output; 953 | }); 954 | 955 | // decoder 956 | // [https://gist.github.com/1020396] by [https://github.com/atk] 957 | object.atob || ( 958 | object.atob = function (input) { 959 | var str = String(input).replace(/=+$/, ''); 960 | if (str.length % 4 == 1) { 961 | throw new InvalidCharacterError("'atob' failed: The string to be decoded is not correctly encoded."); 962 | } 963 | for ( 964 | // initialize result and counters 965 | var bc = 0, bs, buffer, idx = 0, output = ''; 966 | // get next character 967 | buffer = str.charAt(idx++); 968 | // character found in table? initialize bit storage and add its ascii value; 969 | ~buffer && (bs = bc % 4 ? bs * 64 + buffer : buffer, 970 | // and if not first of each 4 characters, 971 | // convert the first 8 bits to one ascii character 972 | bc++ % 4) ? output += String.fromCharCode(255 & bs >> (-2 * bc & 6)) : 0 973 | ) { 974 | // try to find character in table (0-63, not found => -1) 975 | buffer = chars.indexOf(buffer); 976 | } 977 | return output; 978 | }); 979 | 980 | }()); 981 | 982 | 983 | /***/ }), 984 | /* 9 */ 985 | /***/ (function(module, exports, __webpack_require__) { 986 | 987 | (function() { 988 | var utils = __webpack_require__(2); 989 | 990 | exports.Http = function(cfg, adapter){ 991 | return function(args){ 992 | if(args.debug){ 993 | console.log("\nDEBUG (request):", args.method, args.url, args); 994 | } 995 | var promise = (args.http || adapter.http || cfg.http)(args); 996 | if (args.debug && promise && promise.then){ 997 | promise.then(function(x){ console.log("\nDEBUG: (responce)", x);}); 998 | } 999 | return promise; 1000 | }; 1001 | }; 1002 | 1003 | var toJson = function(x){ 1004 | return (utils.type(x) == 'object' || utils.type(x) == 'array') ? JSON.stringify(x) : x; 1005 | }; 1006 | 1007 | exports.$JsonData = function(h){ 1008 | return function(args){ 1009 | var data = args.bundle || args.data || args.resource; 1010 | if(data){ 1011 | args.data = toJson(data); 1012 | } 1013 | return h(args); 1014 | }; 1015 | }; 1016 | 1017 | }).call(this); 1018 | 1019 | 1020 | /***/ }), 1021 | /* 10 */ 1022 | /***/ (function(module, exports) { 1023 | 1024 | module.exports = function(h){ 1025 | return function(args){ 1026 | try{ 1027 | return h(args); 1028 | }catch(e){ 1029 | if(args.debug){ 1030 | console.log("\nDEBUG: (ERROR in middleware)"); 1031 | console.log(e.message); 1032 | console.log(e.stack); 1033 | } 1034 | if(!args.defer) { 1035 | console.log("\nDEBUG: (ERROR in middleware)"); 1036 | console.log(e.message); 1037 | console.log(e.stack); 1038 | throw new Error("I need adapter.defer"); 1039 | } 1040 | var deff = args.defer(); 1041 | deff.reject(e); 1042 | return deff.promise; 1043 | } 1044 | }; 1045 | }; 1046 | 1047 | 1048 | /***/ }), 1049 | /* 11 */ 1050 | /***/ (function(module, exports) { 1051 | 1052 | (function() { 1053 | var copyAttr = function(from, to, attr){ 1054 | var v = from[attr]; 1055 | if(v && !to[attr]) {to[attr] = v;} 1056 | return from; 1057 | }; 1058 | 1059 | module.exports = function(cfg, adapter){ 1060 | return function(h){ 1061 | return function(args){ 1062 | copyAttr(cfg, args, 'baseUrl'); 1063 | copyAttr(cfg, args, 'cache'); 1064 | copyAttr(cfg, args, 'auth'); 1065 | copyAttr(cfg, args, 'patient'); 1066 | copyAttr(cfg, args, 'debug'); 1067 | copyAttr(cfg, args, 'credentials'); 1068 | copyAttr(cfg, args, 'headers'); 1069 | copyAttr(cfg, args, 'agentOptions'); 1070 | copyAttr(adapter, args, 'defer'); 1071 | copyAttr(adapter, args, 'http'); 1072 | return h(args); 1073 | }; 1074 | }; 1075 | }; 1076 | }).call(this); 1077 | 1078 | 1079 | /***/ }), 1080 | /* 12 */ 1081 | /***/ (function(module, exports) { 1082 | 1083 | exports.$$BundleLinkUrl = function(rel){ 1084 | return function(h) { 1085 | return function(args){ 1086 | var matched = function(x){return x.relation && x.relation === rel;}; 1087 | var res = args.bundle && (args.bundle.link || []).filter(matched)[0]; 1088 | if(res && res.url){ 1089 | args.url = res.url; 1090 | args.data = null; 1091 | } 1092 | return h(args); 1093 | }; 1094 | }; 1095 | }; 1096 | 1097 | 1098 | /***/ }), 1099 | /* 13 */ 1100 | /***/ (function(module, exports, __webpack_require__) { 1101 | 1102 | (function() { 1103 | var mw = __webpack_require__(5); 1104 | 1105 | // List of resources with 'patient' or 'subject' properties (as of FHIR DSTU2 1.0.0) 1106 | var targets = [ 1107 | "Account", 1108 | "AllergyIntolerance", 1109 | "BodySite", 1110 | "CarePlan", 1111 | "Claim", 1112 | "ClinicalImpression", 1113 | "Communication", 1114 | "CommunicationRequest", 1115 | "Composition", 1116 | "Condition", 1117 | "Contract", 1118 | "DetectedIssue", 1119 | "Device", 1120 | "DeviceUseRequest", 1121 | "DeviceUseStatement", 1122 | "DiagnosticOrder", 1123 | "DiagnosticReport", 1124 | "DocumentManifest", 1125 | "DocumentReference", 1126 | "Encounter", 1127 | "EnrollmentRequest", 1128 | "EpisodeOfCare", 1129 | "FamilyMemberHistory", 1130 | "Flag", 1131 | "Goal", 1132 | "ImagingObjectSelection", 1133 | "ImagingStudy", 1134 | "Immunization", 1135 | "ImmunizationRecommendation", 1136 | "List", 1137 | "Media", 1138 | "MedicationAdministration", 1139 | "MedicationDispense", 1140 | "MedicationOrder", 1141 | "MedicationStatement", 1142 | "NutritionOrder", 1143 | "Observation", 1144 | "Order", 1145 | "Procedure", 1146 | "ProcedureRequest", 1147 | "QuestionnaireResponse", 1148 | "ReferralRequest", 1149 | "RelatedPerson", 1150 | "RiskAssessment", 1151 | "Specimen", 1152 | "SupplyDelivery", 1153 | "SupplyRequest", 1154 | "VisionPrescription" 1155 | ]; 1156 | 1157 | exports.$WithPatient = mw.$$Simple(function(args){ 1158 | var type = args.type; 1159 | if (args.patient) { 1160 | if (type === "Patient") { 1161 | args.query = args.query || {}; 1162 | args.query["_id"] = args.patient; 1163 | args["id"] = args.patient; 1164 | } else if (targets.indexOf(type) >= 0){ 1165 | args.query = args.query || {}; 1166 | args.query["patient"] = args.patient; 1167 | } 1168 | } 1169 | return args; 1170 | }); 1171 | }).call(this); 1172 | 1173 | 1174 | /***/ }), 1175 | /* 14 */ 1176 | /***/ (function(module, exports, __webpack_require__) { 1177 | 1178 | (function() { 1179 | var utils = __webpack_require__(2); 1180 | 1181 | var CONTAINED = /^#(.*)/; 1182 | var resolveContained = function(ref, resource) { 1183 | var cid = ref.match(CONTAINED)[1]; 1184 | var ret = (resource.contained || []).filter(function(r){ 1185 | return (r.id || r._id) == cid; 1186 | })[0]; 1187 | return (ret && {content: ret}) || null; 1188 | }; 1189 | 1190 | var sync = function(arg) { 1191 | var cache = arg.cache; 1192 | var reference = arg.reference; 1193 | var bundle = arg.bundle; 1194 | var ref = reference; 1195 | if (!ref.reference) {return null;} 1196 | if (ref.reference.match(CONTAINED)) {return resolveContained(ref.reference, arg.resource);} 1197 | var abs = utils.absoluteUrl(arg.baseUrl, ref.reference); 1198 | var bundled = ((bundle && bundle.entry) || []).filter( function(e){ 1199 | return e.id === abs; 1200 | })[0]; 1201 | return bundled || (cache != null ? cache[abs] : void 0) || null; 1202 | }; 1203 | 1204 | var resolve = function(h){ 1205 | return function(args) { 1206 | var cacheMatched = sync(args); 1207 | var ref = args.reference; 1208 | var def = args.defer(); 1209 | if (cacheMatched) { 1210 | if(!args.defer){ throw new Error("I need promise constructor 'adapter.defer' in adapter"); } 1211 | def.resolve(cacheMatched); 1212 | return def.promise; 1213 | } 1214 | if (!ref) { 1215 | throw new Error("No reference found"); 1216 | } 1217 | if (ref && ref.reference.match(CONTAINED)) { 1218 | throw new Error("Contained resource not found"); 1219 | } 1220 | args.url = utils.absoluteUrl(args.baseUrl, ref.reference); 1221 | args.data = null; 1222 | return h(args); 1223 | }; 1224 | }; 1225 | 1226 | module.exports.sync = sync; 1227 | module.exports.resolve = resolve; 1228 | 1229 | }).call(this); 1230 | 1231 | 1232 | /***/ }), 1233 | /* 15 */ 1234 | /***/ (function(module, exports, __webpack_require__) { 1235 | 1236 | (function() { 1237 | var utils = __webpack_require__(2); 1238 | var core = __webpack_require__(5); 1239 | 1240 | var id = function(x){return x;}; 1241 | var constantly = function(x){return function(){return x;};}; 1242 | 1243 | var get_in = function(obj, path){ 1244 | return path.split('.').reduce(function(acc,x){ 1245 | if(x === 'versionId' && acc[x]){ return '_history/'+ acc[x] } 1246 | if(acc == null || acc == undefined) { return null; } 1247 | return acc[x]; 1248 | }, obj); 1249 | }; 1250 | 1251 | var evalPropsExpr = function(exp, args){ 1252 | var exps = exp.split('||').map(function(x){return x.trim().substring(1);}); 1253 | for(var i = 0; i < exps.length; i++){ 1254 | var res = get_in(args, exps[i]); 1255 | if(res){ return res; } 1256 | } 1257 | return null; 1258 | }; 1259 | 1260 | var evalExpr = function(exp, args){ 1261 | if (exp.indexOf(":") == 0){ 1262 | return evalPropsExpr(exp, args); 1263 | } else { 1264 | return exp; 1265 | } 1266 | }; 1267 | 1268 | var buildPathPart = function(pth, args){ 1269 | var k = evalExpr(pth.trim(), args); 1270 | if((k==null || k === undefined) && pth.includes('target.versionId') == false){ throw new Error("Parameter "+pth+" is required: " + JSON.stringify(args)); } 1271 | return k; 1272 | }; 1273 | 1274 | // path chaining function 1275 | // which return haldler wrapper: (h, cfg)->(args -> promise) 1276 | // it's chainable Path("baseUrl").slash(":type").slash(":id").slash("_history")(id, {})({id: 5, type: 'Patient'}) 1277 | // and composable p0 = Path("baseUrl); p1 = p0.slash("path) 1278 | var Path = function(tkn, chain){ 1279 | //Chainable 1280 | var new_chain = function(args){ 1281 | if(chain && tkn.includes('target.versionId') && !args.target.versionId){ 1282 | return chain(args); 1283 | } 1284 | return ((chain && (chain(args) + "/")) || "") + buildPathPart(tkn, args); 1285 | }; 1286 | var ch = core.Attribute('url', new_chain); 1287 | ch.slash = function(tkn){ 1288 | return Path(tkn, new_chain); 1289 | }; 1290 | return ch; 1291 | }; 1292 | 1293 | exports.Path = Path; 1294 | }).call(this); 1295 | 1296 | 1297 | /***/ }), 1298 | /* 16 */ 1299 | /***/ (function(module, exports) { 1300 | 1301 | (function() { 1302 | var fhirAPI; 1303 | var adapter; 1304 | 1305 | function getNext (bundle, process) { 1306 | var i; 1307 | var d = bundle.data.entry || []; 1308 | var entries = []; 1309 | for (i = 0; i < d.length; i++) { 1310 | entries.push(d[i].resource); 1311 | } 1312 | process(entries); 1313 | var def = adapter.defer(); 1314 | fhirAPI.nextPage({bundle:bundle.data}).then(function (r) { 1315 | getNext(r, process).then(function (t) { 1316 | def.resolve(); 1317 | }); 1318 | }, function(err) {def.resolve()}); 1319 | return def.promise; 1320 | } 1321 | 1322 | function drain (searchParams, process, done, fail) { 1323 | var ret = adapter.defer(); 1324 | 1325 | fhirAPI.search(searchParams).then(function(data){ 1326 | getNext(data, process).then(function() { 1327 | done(); 1328 | }, function(err) { 1329 | fail(err); 1330 | }); 1331 | }, function(err) { 1332 | fail(err); 1333 | }); 1334 | }; 1335 | 1336 | function fetchAll (searchParams){ 1337 | var ret = adapter.defer(); 1338 | var results = []; 1339 | 1340 | drain( 1341 | searchParams, 1342 | function(entries) { 1343 | entries.forEach(function(entry) { 1344 | results.push(entry); 1345 | }); 1346 | }, 1347 | function () { 1348 | ret.resolve(results); 1349 | }, 1350 | function (err) { 1351 | ret.reject(err); 1352 | } 1353 | ); 1354 | 1355 | return ret.promise; 1356 | }; 1357 | 1358 | function fetchAllWithReferences (searchParams, resolveParams) { 1359 | var ret = adapter.defer(); 1360 | 1361 | fhirAPI.search(searchParams) // TODO: THIS IS NOT CORRECT (need fetchAll, but it does not return a bundle yet) 1362 | .then(function(results){ 1363 | 1364 | var resolvedReferences = {}; 1365 | 1366 | var queue = [function() {ret.resolve(results, resolvedReferences);}]; 1367 | 1368 | function enqueue (bundle,resource,reference) { 1369 | queue.push(function() {resolveReference(bundle,resource,reference)}); 1370 | } 1371 | 1372 | function next() { 1373 | (queue.pop())(); 1374 | } 1375 | 1376 | function resolveReference (bundle,resource,reference) { 1377 | var referenceID = reference.reference; 1378 | fhirAPI.resolve({'bundle': bundle, 'resource': resource, 'reference':reference}).then(function(res){ 1379 | var referencedObject = res.data || res.content; 1380 | resolvedReferences[referenceID] = referencedObject; 1381 | next(); 1382 | }); 1383 | } 1384 | 1385 | var bundle = results.data; 1386 | 1387 | bundle.entry && bundle.entry.forEach(function(element){ 1388 | var resource = element.resource; 1389 | var type = resource.resourceType; 1390 | resolveParams && resolveParams.forEach(function(resolveParam){ 1391 | var param = resolveParam.split('.'); 1392 | var targetType = param[0]; 1393 | var targetElement = param[1]; 1394 | var reference = resource[targetElement]; 1395 | if (type === targetType && reference) { 1396 | var referenceID = reference.reference; 1397 | if (!resolvedReferences[referenceID]) { 1398 | enqueue(bundle,resource,reference); 1399 | } 1400 | } 1401 | }); 1402 | }); 1403 | 1404 | next(); 1405 | 1406 | }, function(){ 1407 | ret.reject("Could not fetch search results"); 1408 | }); 1409 | 1410 | return ret.promise; 1411 | }; 1412 | 1413 | function decorate (client, newAdapter) { 1414 | fhirAPI = client; 1415 | adapter = newAdapter; 1416 | client["drain"] = drain; 1417 | client["fetchAll"] = fetchAll; 1418 | client["fetchAllWithReferences"] = fetchAllWithReferences; 1419 | return client; 1420 | } 1421 | 1422 | module.exports = decorate; 1423 | }).call(this); 1424 | 1425 | /***/ }) 1426 | /******/ ]) 1427 | }); 1428 | ; -------------------------------------------------------------------------------- /iris.script: -------------------------------------------------------------------------------- 1 | zn "USER" 2 | zpm "install fhir-portal" 3 | zpm "install swagger-ui" 4 | zpm "load /home/irisowner/irisdev/ -v" 5 | #; Use FHIR.utils.install 6 | #; to add new FHIR servers 7 | #; zn "USER" 8 | #; do ##class(FHIR.utils).install("PID") 9 | #; do ##class(FHIR.utils).install("CLINIC") 10 | halt -------------------------------------------------------------------------------- /merge.cpf: -------------------------------------------------------------------------------- 1 | [Actions] 2 | # Service CallIn 3 | ModifyService:Name=%Service_CallIn,Enabled=1,AutheEnabled=48 4 | 5 | # %ALL 6 | CreateNamespace:Name=%ALL,Globals=%DEFAULTDB,Routines=%DEFAULTDB 7 | CreateMapPackage:Namespace=%ALL,Name=User,Database=USER 8 | 9 | # FHIRSERVER 10 | CreateResource:Name=%DB_FHIRSERVER_DATA,Description="FHIRSERVER_DATA database" 11 | CreateDatabase:Name=FHIRSERVER_DATA,Directory=/usr/irissys/mgr/FHIRSERVER_DATA 12 | CreateResource:Name=%DB_FHIRSERVER_CODE,Description="FHIRSERVER_CODE database" 13 | CreateDatabase:Name=FHIRSERVER_CODE,Directory=/usr/irissys/mgr/FHIRSERVER_CODE 14 | CreateNamespace:Name=FHIRSERVER,Globals=FHIRSERVER_DATA,Routines=FHIRSERVER_CODE,Interop=1 -------------------------------------------------------------------------------- /merge_PID_CLINIC.cpf: -------------------------------------------------------------------------------- 1 | [Actions] 2 | # Service CallIn 3 | ModifyService:Name=%Service_CallIn,Enabled=1,AutheEnabled=48 4 | 5 | # %ALL 6 | CreateNamespace:Name=%ALL,Globals=%DEFAULTDB,Routines=%DEFAULTDB 7 | CreateMapPackage:Namespace=%ALL,Name=User.SQLvar,Database=USER 8 | 9 | # FHIRSERVER 10 | CreateResource:Name=%DB_FHIRSERVER_DATA,Description="FHIRSERVER_DATA database" 11 | CreateDatabase:Name=FHIRSERVER_DATA,Directory=/usr/irissys/mgr/FHIRSERVER_DATA 12 | CreateResource:Name=%DB_FHIRSERVER_CODE,Description="FHIRSERVER_CODE database" 13 | CreateDatabase:Name=FHIRSERVER_CODE,Directory=/usr/irissys/mgr/FHIRSERVER_CODE 14 | CreateNamespace:Name=FHIRSERVER,Globals=FHIRSERVER_DATA,Routines=FHIRSERVER_CODE,Interop=1 15 | 16 | # CLINIC 17 | CreateResource:Name=%DB_CLINIC_DATA,Description="CLINIC_DATA database" 18 | CreateDatabase:Name=CLINIC_DATA,Directory=/usr/irissys/mgr/CLINIC_DATA 19 | CreateResource:Name=%DB_CLINIC_CODE,Description="CLINIC_CODE database" 20 | CreateDatabase:Name=CLINIC_CODE,Directory=/usr/irissys/mgr/CLINIC_CODE 21 | CreateNamespace:Name=CLINIC,Globals=CLINIC_DATA,Routines=CLINIC_CODE,Interop=1 22 | 23 | # PID 24 | CreateResource:Name=%DB_PID_DATA,Description="PID_DATA database" 25 | CreateDatabase:Name=PID_DATA,Directory=/usr/irissys/mgr/PID_DATA 26 | CreateResource:Name=%DB_PID_CODE,Description="PID_CODE database" 27 | CreateDatabase:Name=PID_CODE,Directory=/usr/irissys/mgr/PID_CODE 28 | CreateNamespace:Name=PID,Globals=PID_DATA,Routines=PID_CODE,Interop=1 -------------------------------------------------------------------------------- /misc/postman/IRIS FHIR Template.postman_collection.json: -------------------------------------------------------------------------------- 1 | { 2 | "info": { 3 | "_postman_id": "60b9ec4b-312d-4ba9-a6ea-153e59193441", 4 | "name": "IRIS FHIR Template", 5 | "schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json" 6 | }, 7 | "item": [ 8 | { 9 | "name": "Patient", 10 | "item": [ 11 | { 12 | "name": "Get All Patient", 13 | "request": { 14 | "method": "GET", 15 | "header": [], 16 | "url": { 17 | "raw": "http://localhost:32783/fhir/r4/Patient", 18 | "protocol": "http", 19 | "host": [ 20 | "localhost" 21 | ], 22 | "port": "32783", 23 | "path": [ 24 | "fhir", 25 | "r4", 26 | "Patient" 27 | ] 28 | } 29 | }, 30 | "response": [] 31 | }, 32 | { 33 | "name": "Get All Patient 1 $everything", 34 | "request": { 35 | "method": "GET", 36 | "header": [], 37 | "url": { 38 | "raw": "http://localhost:32783/fhir/r4/Patient/1/$everything", 39 | "protocol": "http", 40 | "host": [ 41 | "localhost" 42 | ], 43 | "port": "32783", 44 | "path": [ 45 | "fhir", 46 | "r4", 47 | "Patient", 48 | "1", 49 | "$everything" 50 | ] 51 | } 52 | }, 53 | "response": [] 54 | } 55 | ], 56 | "protocolProfileBehavior": {} 57 | }, 58 | { 59 | "name": "Appointment", 60 | "item": [ 61 | { 62 | "name": "Get Fhir Appointment Patient/1", 63 | "request": { 64 | "method": "GET", 65 | "header": [], 66 | "url": { 67 | "raw": "http://localhost:32783/fhir/r4/Appointment?actor=Patient/1", 68 | "protocol": "http", 69 | "host": [ 70 | "localhost" 71 | ], 72 | "port": "32783", 73 | "path": [ 74 | "fhir", 75 | "r4", 76 | "Appointment" 77 | ], 78 | "query": [ 79 | { 80 | "key": "actor", 81 | "value": "Patient/1" 82 | } 83 | ] 84 | } 85 | }, 86 | "response": [] 87 | }, 88 | { 89 | "name": "Post Fhir Appointment Patient/1", 90 | "request": { 91 | "method": "POST", 92 | "header": [ 93 | { 94 | "key": "Content-Type", 95 | "value": "application/json+fhir", 96 | "type": "text" 97 | } 98 | ], 99 | "body": { 100 | "mode": "raw", 101 | "raw": "{\n \"resourceType\": \"Appointment\",\n \"text\": {\n \"status\": \"generated\",\n \"div\": \"
Brian MRI results discussion
\"\n },\n \"status\": \"booked\",\n \"serviceCategory\": [\n {\n \"coding\": [\n {\n \"system\": \"http://example.org/service-category\",\n \"code\": \"gp\",\n \"display\": \"General Practice\"\n }\n ]\n }\n ],\n \"serviceType\": [\n {\n \"coding\": [\n {\n \"code\": \"52\",\n \"display\": \"General Discussion\"\n }\n ]\n }\n ],\n \"specialty\": [\n {\n \"coding\": [\n {\n \"system\": \"http://snomed.info/sct\",\n \"code\": \"394814009\",\n \"display\": \"General practice\"\n }\n ]\n }\n ],\n \"appointmentType\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0276\",\n \"code\": \"FOLLOWUP\",\n \"display\": \"A follow up visit from a previous appointment\"\n }\n ]\n },\n \"reasonReference\": [\n {\n \"reference\": \"Condition/example\",\n \"display\": \"Severe burn of left ear\"\n }\n ],\n \"priority\": 5,\n \"description\": \"Discussion on the results of your recent MRI\",\n \"start\": \"2013-12-10T09:00:00Z\",\n \"end\": \"2013-12-10T11:00:00Z\",\n \"created\": \"2013-10-10\",\n \"comment\": \"Further expand on the results of the MRI and determine the next actions that may be appropriate.\",\n \"basedOn\": [\n {\n \"reference\": \"ServiceRequest/myringotomy\"\n }\n ],\n \"participant\": [\n {\n \"actor\": {\n \"reference\": \"Patient/1\",\n \"display\": \"O'Hara248 Carroll471\"\n },\n \"required\": \"required\",\n \"status\": \"accepted\"\n },\n {\n \"type\": [\n {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v3-ParticipationType\",\n \"code\": \"ATND\"\n }\n ]\n }\n ],\n \"actor\": {\n \"reference\": \"Practitioner/example\",\n \"display\": \"Dr Adam Careful\"\n },\n \"required\": \"required\",\n \"status\": \"accepted\"\n },\n {\n \"actor\": {\n \"reference\": \"Location/1\",\n \"display\": \"South Wing, second floor\"\n },\n \"required\": \"required\",\n \"status\": \"accepted\"\n }\n ]\n}" 102 | }, 103 | "url": { 104 | "raw": "http://localhost:32783/fhir/r4/Appointment", 105 | "protocol": "http", 106 | "host": [ 107 | "localhost" 108 | ], 109 | "port": "32783", 110 | "path": [ 111 | "fhir", 112 | "r4", 113 | "Appointment" 114 | ] 115 | } 116 | }, 117 | "response": [] 118 | }, 119 | { 120 | "name": "Put Fhir Appointment Patient/1", 121 | "request": { 122 | "method": "PUT", 123 | "header": [ 124 | { 125 | "key": "Content-Type", 126 | "value": "application/json+fhir", 127 | "type": "text" 128 | } 129 | ], 130 | "body": { 131 | "mode": "raw", 132 | "raw": "{\n \"resourceType\": \"Appointment\",\n \"id\": \"1983\",\n \"text\": {\n \"status\": \"generated\",\n \"div\": \"
Brian MRI results discussion
\"\n },\n \"status\": \"booked\",\n \"serviceCategory\": [\n {\n \"coding\": [\n {\n \"system\": \"http://example.org/service-category\",\n \"code\": \"gp\",\n \"display\": \"General Practice\"\n }\n ]\n }\n ],\n \"serviceType\": [\n {\n \"coding\": [\n {\n \"code\": \"52\",\n \"display\": \"General Discussion\"\n }\n ]\n }\n ],\n \"specialty\": [\n {\n \"coding\": [\n {\n \"system\": \"http://snomed.info/sct\",\n \"code\": \"394814009\",\n \"display\": \"General practice\"\n }\n ]\n }\n ],\n \"appointmentType\": {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v2-0276\",\n \"code\": \"FOLLOWUP\",\n \"display\": \"A follow up visit from a previous appointment\"\n }\n ]\n },\n \"reasonReference\": [\n {\n \"reference\": \"Condition/example\",\n \"display\": \"Severe burn of left ear\"\n }\n ],\n \"priority\": 5,\n \"description\": \"Discussion on the results of your recent MRI\",\n \"start\": \"2013-11-10T09:00:00Z\",\n \"end\": \"2013-11-10T11:00:00Z\",\n \"created\": \"2013-10-10\",\n \"comment\": \"No comment\",\n \"basedOn\": [\n {\n \"reference\": \"ServiceRequest/myringotomy\"\n }\n ],\n \"participant\": [\n {\n \"actor\": {\n \"reference\": \"Patient/1\",\n \"display\": \"O'Hara248 Carroll471\"\n },\n \"required\": \"required\",\n \"status\": \"accepted\"\n },\n {\n \"type\": [\n {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/v3-ParticipationType\",\n \"code\": \"ATND\"\n }\n ]\n }\n ],\n \"actor\": {\n \"reference\": \"Practitioner/example\",\n \"display\": \"Dr Adam Careful\"\n },\n \"required\": \"required\",\n \"status\": \"accepted\"\n },\n {\n \"actor\": {\n \"reference\": \"Location/1\",\n \"display\": \"South Wing, second floor\"\n },\n \"required\": \"required\",\n \"status\": \"accepted\"\n }\n ]\n}" 133 | }, 134 | "url": { 135 | "raw": "http://localhost:32783/fhir/r4/Appointment/1983", 136 | "protocol": "http", 137 | "host": [ 138 | "localhost" 139 | ], 140 | "port": "32783", 141 | "path": [ 142 | "fhir", 143 | "r4", 144 | "Appointment", 145 | "1983" 146 | ] 147 | } 148 | }, 149 | "response": [] 150 | } 151 | ], 152 | "protocolProfileBehavior": {} 153 | }, 154 | { 155 | "name": "Observation", 156 | "item": [ 157 | { 158 | "name": "Get Observation Patient/1", 159 | "protocolProfileBehavior": { 160 | "disableBodyPruning": true 161 | }, 162 | "request": { 163 | "method": "GET", 164 | "header": [ 165 | { 166 | "key": "Content-Type", 167 | "value": "application/json+fhir", 168 | "type": "text" 169 | } 170 | ], 171 | "body": { 172 | "mode": "raw", 173 | "raw": "{\n\n \"resource\": {\n \"resourceType\": \"Observation\",\n\n \"status\": \"final\",\n \"category\": [\n {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/observation-category\",\n \"code\": \"laboratory\",\n \"display\": \"laboratory\"\n }\n ]\n }\n ],\n \"code\": {\n \"coding\": [\n {\n \"system\": \"http://loinc.org\",\n \"code\": \"718-7\",\n \"display\": \"Hemoglobin [Mass/volume] in Blood\"\n }\n ],\n \"text\": \"Hemoglobin [Mass/volume] in Blood\"\n },\n \"subject\": {\n \"reference\": \"urn:uuid:274f5452-2a39-44c4-a7cb-f36de467762e\"\n },\n \"encounter\": {\n \"reference\": \"urn:uuid:05c5e1db-4a49-46e1-838d-fc0b7f379bf6\"\n },\n \"effectiveDateTime\": \"2011-07-24T15:32:17+00:00\",\n \"issued\": \"2019-07-24T15:32:17.188+00:00\",\n \"valueQuantity\": {\n \"value\": 15.277,\n \"unit\": \"g/dL\",\n \"system\": \"http://unitsofmeasure.org\",\n \"code\": \"g/dL\"\n }\n },\n \"request\": {\n \"method\": \"POST\",\n \"url\": \"Observation\"\n }\n }", 174 | "options": { 175 | "raw": { 176 | "language": "json" 177 | } 178 | } 179 | }, 180 | "url": { 181 | "raw": "http://localhost:32783/fhir/r4/Observation?patient=1&code=718-7&_sort=date", 182 | "protocol": "http", 183 | "host": [ 184 | "localhost" 185 | ], 186 | "port": "32783", 187 | "path": [ 188 | "fhir", 189 | "r4", 190 | "Observation" 191 | ], 192 | "query": [ 193 | { 194 | "key": "patient", 195 | "value": "1" 196 | }, 197 | { 198 | "key": "code", 199 | "value": "718-7" 200 | }, 201 | { 202 | "key": "_sort", 203 | "value": "date" 204 | } 205 | ] 206 | } 207 | }, 208 | "response": [] 209 | }, 210 | { 211 | "name": "Post Observation Patient/1", 212 | "request": { 213 | "method": "POST", 214 | "header": [ 215 | { 216 | "key": "Content-Type", 217 | "value": "application/json+fhir", 218 | "type": "text" 219 | } 220 | ], 221 | "body": { 222 | "mode": "raw", 223 | "raw": "{\n\n \"resourceType\": \"Observation\",\n\n \"status\": \"final\",\n \"category\": [\n {\n \"coding\": [\n {\n \"system\": \"http://terminology.hl7.org/CodeSystem/observation-category\",\n \"code\": \"laboratory\",\n \"display\": \"laboratory\"\n }\n ]\n }\n ],\n \"code\": {\n \"coding\": [\n {\n \"system\": \"http://loinc.org\",\n \"code\": \"718-7\",\n \"display\": \"Hemoglobin [Mass/volume] in Blood\"\n }\n ],\n \"text\": \"Hemoglobin [Mass/volume] in Blood\"\n },\n \"subject\": {\n \"reference\": \"Patient/1\"\n },\n \"effectiveDateTime\": \"2014-01-24T15:32:17+00:00\",\n \"issued\": \"2014-01-24T15:32:17.188+00:00\",\n \"valueQuantity\": {\n \"value\": 10.277,\n \"unit\": \"g/dL\",\n \"system\": \"http://unitsofmeasure.org\",\n \"code\": \"g/dL\"\n }\n\n }", 224 | "options": { 225 | "raw": { 226 | "language": "json" 227 | } 228 | } 229 | }, 230 | "url": { 231 | "raw": "http://localhost:32783/fhir/r4/Observation", 232 | "protocol": "http", 233 | "host": [ 234 | "localhost" 235 | ], 236 | "port": "32783", 237 | "path": [ 238 | "fhir", 239 | "r4", 240 | "Observation" 241 | ] 242 | } 243 | }, 244 | "response": [] 245 | } 246 | ], 247 | "protocolProfileBehavior": {} 248 | }, 249 | { 250 | "name": "Get Metadata", 251 | "request": { 252 | "method": "GET", 253 | "header": [], 254 | "url": { 255 | "raw": "http://localhost:32783/fhir/r4/metadata", 256 | "protocol": "http", 257 | "host": [ 258 | "localhost" 259 | ], 260 | "port": "32783", 261 | "path": [ 262 | "fhir", 263 | "r4", 264 | "metadata" 265 | ] 266 | } 267 | }, 268 | "response": [] 269 | } 270 | ], 271 | "protocolProfileBehavior": {} 272 | } -------------------------------------------------------------------------------- /misc/sql/example.sql: -------------------------------------------------------------------------------- 1 | /* Select all Patients */ 2 | SELECT 3 | * 4 | FROM HSFHIR_X0001_S.Patient; 5 | /* Select all Observation of Patient/4 */ 6 | SELECT 7 | * FROM HSFHIR_X0001_S.Observation 8 | where patient = 'Patient/4'; 9 | /* Select all Observation of Patient/4 with lonic code 718-7 (Hemoglobin [Mass/volume] in Blood)*/ 10 | SELECT 11 | * 12 | FROM HSFHIR_X0001_S.Observation 13 | where patient = 'Patient/4' and code [ '718-7'; 14 | 15 | /* Get detail of the Observation/81 */ 16 | SELECT 17 | * 18 | FROM HSFHIR_X0001_R.Rsrc where Key = 'Observation/81'; 19 | 20 | /* Get valueQuantity of the Observation/81 */ 21 | SELECT 22 | ID 23 | , Key 24 | , ResourceString 25 | , GetJSON(ResourceString,'valueQuantity') as valueQuantity 26 | FROM HSFHIR_X0001_R.Rsrc where Key = 'Observation/81'; 27 | 28 | /* Get value of valueQuantity of the Observation/81 */ 29 | SELECT 30 | ID 31 | , Key 32 | , ResourceString 33 | , GetJSON(ResourceString,'valueQuantity') as valueQuantity 34 | , GetProp(GetJSON(ResourceString,'valueQuantity'),'value') as value 35 | FROM HSFHIR_X0001_R.Rsrc where Key = 'Observation/81'; 36 | 37 | /* An complexe example */ 38 | SELECT 39 | ID, Key, ResourceString 40 | , GetJSON(ResourceString,'code') as code 41 | , GetJSON(GetJSON(ResourceString,'code'),'coding') as coding 42 | , GetAtJSON(GetJSON(GetJSON(ResourceString,'code'),'coding'),0) as coding1 43 | , GetJSON(GetAtJSON(GetJSON(GetJSON(ResourceString,'code'),'coding'),0),'display') as display 44 | , GetProp(GetJSON(GetAtJSON(GetJSON(GetJSON(ResourceString,'code'),'coding'),0),'display'),'display') as value 45 | FROM HSFHIR_X0001_R.Rsrc where Key = 'Observation/81'; -------------------------------------------------------------------------------- /module.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fhir-server 6 | 1.3.4 7 | InterSystems FHIR Server with a demo frontend 8 | FHIR,Server 9 | module 10 | 11 | 12 | 13 | 14 | src 15 | 16 | 17 | ${name} 18 | ${Webapp} 19 | ${AddTestData} 20 | 21 | 22 | 23 | 24 | 25 | 26 | 34 | 35 | You can change the default settings 36 | Name - to alter created/modified namespace (now/default FHIRSERVER) 37 | AddTestData - import some test data to the FHIR server, otherwise don't 38 | Webapp - provide the name for the web application to expose R4 API. /fhir/r4 is by default 39 | USER>zpm "install fhir-server -Dzpm.name=ALTERFHIRSERVER -Dzpm.Webapp=/fhir/r7 -Dzpm.AddTestData=0" 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /src/FHIR/utils.cls: -------------------------------------------------------------------------------- 1 | Class FHIR.utils 2 | { 3 | 4 | ClassMethod install(NAMESPACE As %String = "FHIRDEMO") As %Status 5 | { 6 | set sc = $$$OK 7 | set ns = $NAMESPACE 8 | zn "HSLIB" 9 | Set appKey = "/"_$zcvt(NAMESPACE,"l")_"/fhir/r4" 10 | Set strategyClass = "HS.FHIRServer.Storage.Json.InteractionsStrategy" 11 | Set metadataConfigKey = "HL7v40" 12 | 13 | //Install a Foundation namespace and change to it 14 | // https://docs.intersystems.com/irisforhealthlatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=HSSYS&CLASSNAME=HS.Util.Installer.Foundation#Install 15 | Do ##class(HS.Util.Installer.Foundation).Install(NAMESPACE) 16 | 17 | zn NAMESPACE 18 | 19 | // Install elements that are required for a FHIR-enabled namespace 20 | // https://docs.intersystems.com/irisforhealthlatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=HSSYS&CLASSNAME=HS.FHIRServer.Installer#InstallNamespace 21 | Do ##class(HS.FHIRServer.Installer).InstallNamespace() 22 | 23 | // Install an instance of a FHIR Service into the current namespace 24 | // https://docs.intersystems.com/irisforhealthlatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=HSSYS&CLASSNAME=HS.FHIRServer.Installer#InstallInstance 25 | Do ##class(HS.FHIRServer.Installer).InstallInstance(appKey, strategyClass, metadataConfigKey) 26 | #; do ##class(Ens.Director).StopProduction() 27 | 28 | #; zw $classmethod("Ens.Director", "SetAutoStart", NAMESPACE_"PKG.FoundationProduction", 0) 29 | 30 | #; set cspConfig = ##class(HS.Util.RESTCSPConfig).URLIndexOpen(appKey) 31 | #; set cspConfig.ServiceConfigName = "HS.FHIRServer.Interop.Service" 32 | #; set cspConfig.AllowUnauthenticatedAccess = 1 33 | #; zw cspConfig.%Save() 34 | 35 | #; set strategy = ##class(HS.FHIRServer.API.InteractionsStrategy).GetStrategyForEndpoint(appKey) 36 | #; set config = strategy.GetServiceConfigData() 37 | #; set config.DebugMode = 4 38 | #; do strategy.SaveServiceConfigData(config) 39 | zn ns 40 | return sc 41 | } 42 | 43 | ClassMethod uninstall(NAMESPACE As %String = "FHIRDEMO") As %Status 44 | { 45 | set sc = $$$OK 46 | set ns = $NAMESPACE 47 | 48 | zn "HSLIB" 49 | set appKey = "/"_$zcvt(NAMESPACE,"l")_"/fhir/r4" 50 | 51 | //Uninstall a Foundation namespace and change to it 52 | /// https://docs.intersystems.com/irisforhealthlatest/csp/documatic/%25CSP.Documatic.cls?LIBRARY=HSSYS&CLASSNAME=HS.Util.Installer.Foundation#UnInstall 53 | Do ##class(HS.Util.Installer.Foundation).UnInstall(NAMESPACE) 54 | 55 | zn NAMESPACE 56 | 57 | #; // Uninstall an instance of a FHIR Service into the current namespace 58 | Do ##class(HS.FHIRServer.Installer).UninstallInstance(appKey) 59 | 60 | zn ns 61 | return sc 62 | } 63 | 64 | /// Delete all resources from the FHIR Server 65 | ClassMethod purge(pServiceName As %String = "/fhirhl7v2demo/fhir/r4") As %Status 66 | { 67 | Try { 68 | set sc = $$$OK 69 | set strategy = ##class(HS.FHIRServer.API.InteractionsStrategy).GetStrategyForEndpoint(pServiceName) 70 | set options("deleteDataOnly") = 1 71 | do strategy.Delete(.options) 72 | } 73 | Catch ex { 74 | set sc=ex.AsStatus() 75 | } 76 | 77 | return sc 78 | } 79 | 80 | /// Load resources in the FHIR Server 81 | ClassMethod load(pInputDirectory As %String = "/data/fhir/", pServiceType As %String = "FHIRServer", pServiceName As %String = "/fhir/r4", pDisplayProgress As %Boolean = 1) As %Status 82 | { 83 | Try { 84 | set sc = $$$OK 85 | set sc = ##class(HS.FHIRServer.Tools.DataLoader).SubmitResourceFiles(pInputDirectory, pServiceType, pServiceName, pDisplayProgress) 86 | } 87 | Catch ex { 88 | set tSC=ex.AsStatus() 89 | } 90 | return sc 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /src/User/SQLvar.cls: -------------------------------------------------------------------------------- 1 | Class User.SQLvar 2 | { 3 | 4 | ClassMethod GetJSON(json As %String, name As %String) As %String(MAXLEN="") [ SqlName = GetJSON, SqlProc ] 5 | { 6 | 7 | quit:(json="") "" 8 | 9 | set dyna = {}.%FromJSON(json) 10 | 11 | set result = dyna.%Get(name) 12 | 13 | quit $s(result'="":$s(($classname(result)="%Library.DynamicObject")||($classname(result)="%Library.DynamicArray"):result.%ToJSON(),1:{}.%Set(name,result,dyna.%GetTypeOf(name)).%ToJSON()),1:"") 14 | } 15 | 16 | ClassMethod GetProp(json As %String, prop As %String) As %String(MAXLEN="") [ SqlName = GetProp, SqlProc ] 17 | { 18 | quit:(json="") "" 19 | 20 | set dyna = {}.%FromJSON(json) 21 | 22 | Quit dyna.%Get(prop) 23 | } 24 | 25 | ClassMethod GetAtJSON(json As %String, position As %Integer) As %String(MAXLEN="") [ SqlName = GetAtJSON, SqlProc ] 26 | { 27 | quit:(json="") "" 28 | 29 | set dyna = [].%FromJSON(json) 30 | 31 | set i = 0 32 | set iterator = dyna.%GetIterator() 33 | 34 | while iterator.%GetNext(.key, .result) { 35 | quit:(i=position) 36 | do $Increment(i) 37 | } 38 | 39 | Quit $s(result'="":$s(($classname(result)="%Library.DynamicObject")||($classname(result)="%Library.DynamicArray"):result.%ToJSON(),1:{}.%Set(key,result,dyna.%GetTypeOf(key)).%ToJSON()),1:"") 40 | } 41 | 42 | /// Return JSON array resulting from FHIRPath query 43 | ClassMethod GetFHIRPath(json As %String, path As %String, mdSetKey As %String = "HL7v40") As %String(MAXLEN="") [ SqlName = GetFHIRPath, SqlProc ] 44 | { 45 | if (json = "") quit "" 46 | 47 | #dim fpAPI As HS.FHIRPath.API = ##class(HS.FHIRPath.API).getInstance(mdSetKey) 48 | #dim node As HS.FHIRPath.Node = fpAPI.parse(path) 49 | 50 | #dim array As %DynamicArray = fpAPI.evaluateToJson({}.%FromJSON(json), node) 51 | //#dim array As %DynamicArray = $$%EvaluatePath^%DocDB.Document(json, path) 52 | if (array = "") quit "" 53 | 54 | quit array.%ToJSON() 55 | } 56 | 57 | /// Return just one result, either JSON object/array or a single value. 58 | /// resourceType argument is used to distinguish arrays from non-arrays. 59 | ClassMethod GetFHIRPathOne(json As %String, path As %String, resourceType As %String, mdSetKey As %String = "HL7v40") As %String(MAXLEN="") [ SqlName = GetFHIRPathOne, SqlProc ] 60 | { 61 | if (json = "") quit "" 62 | 63 | #dim fpAPI As HS.FHIRPath.API = ##class(HS.FHIRPath.API).getInstance(mdSetKey) 64 | #dim node As HS.FHIRPath.Node = fpAPI.parse(path) 65 | 66 | #dim array As %DynamicArray = fpAPI.evaluateToJson({}.%FromJSON(json), node) 67 | //#dim array As %DynamicArray = $$%EvaluatePath^%DocDB.Document(json, path) 68 | if (array = "") quit "" 69 | 70 | do fpAPI.getPathAndType(resourceType, node, .contextPath, .fhirType) 71 | 72 | #dim result = array 73 | if (($get(fhirType("ar")) = $$$NO) || ($extract($zstrip(path, ">W"), *) = "]")) 74 | { 75 | set result = array.%Get(0) 76 | } 77 | 78 | quit $case($isObject(result), $$$YES:/*result.%ClassName(1) _ ":" _ */result.%ToJSON(), :result) 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/fhirtemplate/Setup.cls: -------------------------------------------------------------------------------- 1 | Class fhirtemplate.Setup 2 | { 3 | 4 | ClassMethod SetupFHIRServer(ns="FHIRSERVER",appKey="/fhir/r4",testLoad=1) As %Status 5 | { 6 | set st=$$$OK 7 | Write !,"=== Initialization with parameters: Namespace: "_ns_", Webapp: "_appKey_", AddTestData: "_testLoad,! 8 | zn "HSLIB" 9 | set namespace=ns 10 | ;Set appKey = "/fhir/r4" 11 | Set strategyClass = "HS.FHIRServer.Storage.Json.InteractionsStrategy" 12 | set metadataPackages = $lb("hl7.fhir.r4.core@4.0.1") 13 | Set metadataConfigKey = "HL7v40" 14 | ;set importdir="/opt/irisapp/src" 15 | 16 | //Install a Foundation namespace and change to it 17 | //Do ##class(HS.HC.Util.Installer).InstallFoundation(namespace) 18 | Do ##class(HS.Util.Installer.Foundation).Install(namespace) 19 | 20 | zn namespace 21 | 22 | // Install elements that are required for a FHIR-enabled namespace 23 | do ##class(HS.FHIRServer.Installer).InstallNamespace() 24 | 25 | // Install an instance of a FHIR Service into the current namespace 26 | if '##class(HS.FHIRServer.ServiceAdmin).EndpointExists(appKey) { 27 | do ##class(HS.FHIRServer.Installer).InstallInstance(appKey, strategyClass, metadataPackages) 28 | } 29 | 30 | set strategy = ##class(HS.FHIRServer.API.InteractionsStrategy).GetStrategyForEndpoint(appKey) 31 | set config = strategy.GetServiceConfigData() 32 | set config.DebugMode = 4 33 | do strategy.SaveServiceConfigData(config) 34 | 35 | if testLoad { 36 | set dir=$System.Util.ManagerDirectory()_"test-data-fhir" 37 | write !," ====== Load test data in "_ns_" from "_dir 38 | set st=##class(HS.FHIRServer.Tools.DataLoader).SubmitResourceFiles(dir, "FHIRServer", appKey) 39 | if 'st write $System.Status.GetErrorText(st) 40 | } 41 | quit st 42 | } 43 | 44 | ClassMethod LoadPatientData(path, namespace, appKey) As %Status 45 | { 46 | quit ##class(HS.FHIRServer.Tools.DataLoader).SubmitResourceFiles(path, namespace, appKey) 47 | } 48 | 49 | ClassMethod AddApp(ns={$namespace}) As %Status 50 | { 51 | set namespace=ns 52 | zn "%SYS" 53 | set webName = "/fhirUI" 54 | set webProperties("NameSpace") = namespace 55 | set webProperties("Enabled") = 1 56 | set webProperties("Path") = "/irisdev/app/fhirUI" 57 | set webProperties("AutheEnabled") = 64 58 | set webProperties("ServeFiles")=2 59 | set webProperties("Recurse")=1 60 | quit ##class(Security.Applications).Create(webName, .webProperties) 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /synthea-loader.bat: -------------------------------------------------------------------------------- 1 | rd -q output 2 | set numberOfPatients=10 3 | if not "%1"=="" ( 4 | set numberOfPatients=%1 5 | ) 6 | 7 | docker run --rm -v %~dp0\output:/output --name synthea-docker intersystemsdc/irisdemo-base-synthea:version-1.3.4 -p %numberOfPatients% -------------------------------------------------------------------------------- /synthea-loader.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | rm -rf output 4 | 5 | if [ -z "$1" ]; 6 | then 7 | numberOfPatients=10 8 | else 9 | numberOfPatients=$1 10 | #numberOfPatients=10 11 | fi 12 | 13 | docker run --rm -v $PWD/output:/output --name synthea-docker intersystemsdc/irisdemo-base-synthea:version-1.3.4 -p $numberOfPatients 14 | 15 | --------------------------------------------------------------------------------