Skip to content

Commit 673fa33

Browse files
committed
FHIR IG scaffold
1 parent 22d1dd2 commit 673fa33

File tree

16 files changed

+1086
-0
lines changed

16 files changed

+1086
-0
lines changed

.github/workflows/build_deploy.yml

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
name: Build and Deploy static content to Pages with Docker
2+
3+
on:
4+
# Runs on pushes targeting the default branch
5+
push:
6+
branches: ["main"]
7+
8+
# Allows you to run this workflow manually from the Actions tab
9+
workflow_dispatch:
10+
11+
12+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13+
permissions:
14+
id-token: write
15+
contents: read
16+
packages: write
17+
pages: write
18+
19+
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
20+
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
21+
concurrency:
22+
group: "pages"
23+
cancel-in-progress: false
24+
25+
26+
jobs:
27+
build:
28+
environment:
29+
name: github-pages
30+
url: ${{ steps.deployment.outputs.page_url }}
31+
services:
32+
registry:
33+
image: registry:2
34+
ports:
35+
- 5000:5000
36+
runs-on: ubuntu-latest
37+
steps:
38+
- name: Set up QEMU
39+
uses: docker/setup-qemu-action@v3
40+
- name: Set up Docker Buildx
41+
uses: docker/setup-buildx-action@v3
42+
with:
43+
driver-opts: network=host
44+
- name: Build and push to local registry
45+
uses: docker/build-push-action@v6
46+
with:
47+
push: true
48+
tags: localhost:5000/nuts-foundation/publisher:latest
49+
- name: Checkout
50+
uses: actions/checkout@v4
51+
- name: Setup Pages
52+
uses: actions/configure-pages@v5
53+
- name: Build
54+
run: |
55+
mkdir -p ./output
56+
docker run --name=scp --rm -v ./input:/app/input -v ./output:/app/output localhost:5000/nuts-foundation/publisher:latest
57+
- name: Upload artifact
58+
uses: actions/upload-pages-artifact@v3
59+
with:
60+
# Upload entire repository
61+
path: './output'
62+
- name: Deploy to GitHub Pages
63+
id: deployment
64+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
temp/
2+
*-temp*
3+
template/
4+
input-cache/
5+
.~lock*
6+
*.jar
7+
*.dtmp
8+
*.bkp
9+
.idea
10+
.DS_Store
11+
fsh-generated/
12+
output/

Dockerfile

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
FROM openjdk:24-jdk-bookworm
2+
LABEL maintainer="[email protected]"
3+
4+
# Install native compilation dependencies.
5+
RUN apt-get update -y && apt-get upgrade -y
6+
RUN apt-get install -y gcc g++ make apt-utils
7+
8+
# Install Node from NodeSource.
9+
RUN curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
10+
RUN apt-get install -y nodejs
11+
12+
# Install Jekyll for Ubuntu/Debian: https://jekyllrb.com/docs/installation/ubuntu/
13+
RUN apt-get install -y ruby-full build-essential zlib1g-dev
14+
RUN gem install -N jekyll bundler
15+
16+
RUN mkdir /app
17+
WORKDIR /app
18+
19+
# Install the FHIR Shorthand transfiler:
20+
RUN npm i -g fsh-sushi
21+
22+
# Download the IG publisher.
23+
COPY ./_updatePublisher.sh .
24+
RUN bash ./_updatePublisher.sh -y
25+
RUN chmod +x *.sh *.bat
26+
27+
ADD ig.ini .
28+
ADD sushi-config.yaml .
29+
30+
CMD ["bash", "_genonce.sh"]

ig.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[IG]
2+
ig = fsh-generated/resources/ImplementationGuide-fhir.scp.json
3+
template = fhir.base.template#current
4+
; template = ihe.fhir.template
5+
# For more template examples: https://raw.githubusercontent.com/FHIR/sample-ig/master/ig.ini
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@startuml care-services-use-case-1
2+
3+
skinparam roundcorner 20
4+
skinparam defaultFontName Arial
5+
hide footbox
6+
7+
!pragma teoz true
8+
9+
actor Patient as "Vera"
10+
actor Doctor as "Dr. West"
11+
participant EHR as "EHR (Care Services Selective Consumer)"
12+
participant CSD as "Care Service Directory"
13+
14+
activate Patient
15+
activate Doctor
16+
Patient -> Doctor: My knee hurts
17+
Doctor -> Doctor: diagnosis = torn ACL
18+
activate EHR
19+
Doctor -> EHR: use EHR's custom query tool \nsearch for orthopedic surgeons, \nwithin 30km of Vera's home
20+
activate CSD
21+
EHR-> CSD: Find Matching Care Services request
22+
CSD -> EHR: Find Matching Care Services response\ncontaining PractitionerRole list
23+
deactivate CSD
24+
EHR -> EHR: Resolve References
25+
EHR -> Doctor : Review results\nwith office address, hours of operation
26+
Doctor -> Patient: Review and discuss options
27+
deactivate Patient
28+
Doctor -> EHR: create Referral
29+
deactivate Doctor
30+
deactivate EHR
31+
@enduml
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
@startuml care-services-use-case-2
2+
3+
skinparam roundcorner 20
4+
skinparam defaultFontName Arial
5+
hide footbox
6+
7+
!pragma teoz true
8+
9+
actor Doctor as "Dr. West"
10+
participant EHR as "EHR"
11+
participant CSD as "Care Service Directory"
12+
participant EHR2 as "Orthopedic Clinic"
13+
14+
15+
activate Doctor
16+
activate EHR
17+
group create referral
18+
Doctor -> EHR: create referral for Dr. East\n at Orthopedic Clinic
19+
end
20+
activate CSD
21+
EHR -> CSD: Find PractitonerRole of Dr. East\n including Endpoints
22+
EHR -> EHR: Check for SCP notification Endpoints
23+
EHR -> CSD: If no endpoint found: find Organization of PractitonerRole\n including Endpoint
24+
EHR -> EHR: Check for SCP notification Endpoints
25+
loop If no endpoint found and\nOrganization is part of parent Organization
26+
EHR -> CSD: Find parent Organization of Organization\n including Endpoints
27+
EHR -> EHR: Check for SCP notification Endpoints
28+
end
29+
deactivate CSD
30+
EHR -> EHR2: Post **notification** to SCP notification Endpoint\nof Orthopedic Clinic with referral ID
31+
group referral response
32+
EHR2 -> EHR: Respond to referral
33+
& EHR -> Doctor: Handle referral response
34+
end
35+
36+
deactivate Doctor
37+
deactivate EHR
38+
@enduml

input/pagecontent/authorization.md

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
### The authorization model
2+
3+
<!-- The Shared Care Planning (SCP) authorization model is based on the authority of the Care Plan Service (CPS). This service maintains the Care Plan and is responsible for all the due diligence that is required to build up the required trust for all Care Plan Contributors (CPC) in the network.
4+
5+
### Scope of the care plan
6+
7+
#### Bound to the patient
8+
A Care Plan is bound to a patient, and no more than one patient. A Care Plan (CP) has one single Care Team (CT). Therefore, in CSP the terms Care Plan and Care Team are somewhat interchangeable.
9+
10+
#### Owned by the Plan Service (CPS)
11+
A Care Plan is created by the Care Plan Service as the owner of a CarePlan. As the care network of the Patient grows, more organization become part of the Care Team
12+
```asciidoc
13+
┌───────┐
14+
│Patient│
15+
└───┬───┘
16+
17+
18+
┌───┴────┐
19+
│CarePlan┼───────────┬────────┐
20+
└───┬────┘ │ │
21+
│CPS │CPC │CPC
22+
│ │ │
23+
┌────────┴─────────┐ ┌────┴───┐ ┌──┴───┐
24+
│General Practioner│ │Hospital│ │Physio│
25+
└──────────────────┘ └────────┘ └──────┘
26+
```
27+
### A single context of care
28+
A Care Plan is bound to one single context, in the sense that, CSP assumes that all members of the CT are always allowed to access all relevant data. In the case they are not allowed to access all relevant data, they should not be part of the CT. This that case, a different CP should be created. If a patient is referred to another organization that should not have access to all relevant data of the patient, another (nested) CP should be created.
29+
30+
```AsciiDoc
31+
┌───────┐
32+
┌───────┼Patient│
33+
│ └───┬───┘
34+
│ │
35+
│ │
36+
│ ┌───┴────┐
37+
│ │CarePlan┼───────────┬────────┐
38+
│ └───┬────┘ │ │
39+
│ │CPS │CPC │CPC
40+
│ │ │ │
41+
│ ┌────────┴─────────┐ ┌────┴───┐ ┌──┴───┐
42+
│ │General Practioner│ │Hospital│ │Physio│
43+
│ └──────────────────┘ └────┬───┘ └──────┘
44+
│ │
45+
│ │CPS
46+
│ │
47+
│ ┌───────┴───────┐
48+
└────────────────────┼Nested CarePlan│
49+
└───────┬───────┘
50+
51+
│CPC
52+
┌──────┴──────┐
53+
│Mental health│
54+
│care provider│
55+
└─────────────┘
56+
```
57+
58+
### Model of Patients' consent
59+
New members can only be added to the Care Team of the Care Plan by with explicit consent of the Patient. This responsibility lies with the Care Plan Service. The CPS must be able to contact the Patient and handle the proces of requesting consent. The same goes for Care Plan Contributors that enter a Care Team with existing data; those must verify with the Patient that the existing data is being shared within the context of the Care Plan and Care Team.
60+
61+
### Methods of Patients' consent
62+
The methods of consent must be either in physical interaction with the Patient (at the desk), by physical channels such as mail or with digital methods such as e-mail or SMS notifications to digital consent forms protected by contemporary authentication methods that are already in place.
63+
64+
#### (Lack of) cryptographic consent
65+
In the current authentication landscape of the Netherlands, cryptographic proof of end-user consent is not in sight on the short term. The solution we propose is based on a) consent of the user and b) the due-diligence of the CPS and the CPC in some cases. We choose not to put the emphasis on capturing proof of consent with cryptographic methods, knowing that such technology will eventually become part of the EU Digital Identity Wallet infrastructure signing function.
66+
67+
### Authentication of Organizations
68+
Organizations are authenticated by their X509 Certificate, that is used to sign a X509Credential. This ensures the identity of the health care organizations in Shared Care Planning.
69+
70+
71+
### CPS Responsibilities
72+
The Care Plan Service (SCP) has the role of maintaining the Care Plan and acts as gatekeeper for the Care Plan and Care Team for the Patient. The SCP may only add members to the Care Team with the explicit consent of the user. The CPS may keep track of the consent using the FHIR Consent resources, but is not required to do so.
73+
74+
### CPC Responsibilities
75+
The Care Plan Contributor (CPC) only needs to get consent of the Patient when it links pre-existing data of the Patient to the context of the CarePlan. In that case, the CPC must contact the Patient and is required to get consent for sharing the data.
76+
77+
### The CPS expansion and consent flow
78+
79+
The core flow of consent works a follows:
80+
* A Task is created for a new CPC and that CPC is notified about the Task. Both the CPS or CPC roles can do this. The CPC can either be the initiator of recipient of the Task.
81+
* The CPC either accepts or rejects the Task without knowing the patient.
82+
* The CPS is notified about the accepted Task.
83+
* The CPS contacts the Patient about the new CPC and gets consent on expanding the Care Team.
84+
* The CPS expands the Care Team and notifies the new CPC about the updated CareTeam.
85+
* The new CPC now can fetch the details of the Patient.
86+
* (optional) The CPC can determine the pre-existing data about the patient exists in the system and that this data will be shared within the context of the Care Team. In that case, consent of the patient must be acquired.
87+
88+
#### A more complicated example
89+
{::nomarkdown}
90+
{% include authorization.svg %}
91+
{:/}
92+
93+
The provided **sequence diagram** illustrates the process of adding three external systems (*OLVG*, *Geboortezorg*, and *Fysio*) to a patient's care team. The interactions are handled by the control system (*Huisarts*) and involve patient approval at various stages.
94+
95+
---
96+
97+
## Key Components in the Diagram:
98+
99+
1. **Actors and Entities:**
100+
- **Patient:** The individual whose care team is being managed.
101+
- **Huisarts (CPS):** A CPS responsible for the care team management.
102+
- **OLVG (CPC):** An CPC being added to the care team.
103+
- **Geboortezorg (CPC):** Another CPC being added.
104+
- **Fysio (CPC):** A third CPC being added to the care team.
105+
106+
2. **Groups:**
107+
Each step in the process is organized into groups that represent the task of adding a organization to the care team (*OLVG*, *Geboortezorg*, and *Fysio*).
108+
109+
---
110+
111+
## Process Steps:
112+
113+
### Step 1: Adding **"OLVG"** to the CareTeam
114+
- **Huisarts (CPS) initiates a task** with the *OLVG* system (**CPC**).
115+
- *OLVG* accepts the task and **notifies the Huisarts (CPS)**.
116+
- **The Huisarts (CPS) consults the patient** for approval by sending an consent request.
117+
- Upon patient consent:
118+
- **The Huisarts (CPS) updates the care team** to include *OLVG*.
119+
- **The Huisarts (CPS) notifies the OLVG system** of the update.
120+
- *OLVG* then **fetches the patient's details**.
121+
122+
---
123+
124+
### Step 2: Adding **"Geboortezorg"** to the CareTeam
125+
- A new addition starts from *OLVG* (**CPC**), which triggers a task for *Geboortezorg* (**CPC**).
126+
- *Geboortezorg* accepts the task, notifies *OLVG*, and *OLVG* subsequently **notifies the Huisarts (CPS)**.
127+
- **The Huisarts (CPS) consults the patient** for their consent.
128+
- Upon patient consent:
129+
- **Huisarts (CPS) updates the care team** to include *Geboortezorg*.
130+
- Notifications are sent to both *OLVG* and *Geboortezorg*.
131+
- *Geboortezorg* **fetches the patient's details** at the Huisarts (CPS).
132+
- If the patient has **existing data**, an additional **consent is required** from the patient. Upon consent, the existing data is handled accordingly.
133+
134+
---
135+
136+
### Step 3: The patient goes to the **Fysio** and names **OLVG**
137+
- *Fysio* (**CPC**) triggers a task for *OLVG* (**CPC**).
138+
- *OLVG* accepts the task, sets the `basedOn` value of the Task to the Care Plan of the CPS and **notifies the Huisarts (CPS)**.
139+
- **The Huisarts (CPS) consults the patient** for consent.
140+
- Upon patient consent:
141+
- **The Huisarts (CPS) updates the care team** to include *Fysio*.
142+
- The Huisarts (CPS) sends **notifications to all involved systems** (*OLVG*, *Geboortezorg*, and *Fysio*).
143+
- *Fysio* fetches **the patient's details** from the Huisarts (CPS).
144+
- Additionally:
145+
- *Fysio* requests **data from *OLVG***.
146+
- *OLVG* performs an **internal check (CareTeam)** and shares the required **data back to *Fysio***.
147+
148+
149+
### Main advantages of this approach
150+
#### Distributed
151+
As soon as an organization gets assigned a task that is part of SCP, the task refers to the Care Plan with the `basedOn` value. The Care Plan becomes discoverable and the roles in the SCP are implicitly determined by the ownership of the Care Plan. The CPS is the organization hosting the FHIR resource, all the other members are CPC in the Care Plan.
152+
153+
#### Specific
154+
Consent is acquired on adding an organization or existing data to a care plan, and not at forehand. -->

0 commit comments

Comments
 (0)