Skip to content

Commit b8d98d7

Browse files
authored
Add new example for Smartbox (#6)
* Add new example * Deleted depending on .env * Finally deleted .env from docker-compose.yaml
1 parent ca03dd9 commit b8d98d7

8 files changed

+631
-0
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ A collection of examples on top of Aidbox FHIR platform
1616
- [Aidbox Notify via Custom Resources](aidbox-notify-via-custom-resources/)
1717
- [Topic-Based Subscription to Kafka](aidbox-subscriptions-to-kafka/)
1818
- [SMART App Launch with Aidbox and Keycloak](smart-app-launch/)
19+
- [SMART App Launch with Smartbox and Keycloak](smart-app-launch-smartbox/)
1920
- [IPS $summary implementation](ips-ig/)
2021
- [IPS Chile $summary implementation](ips-ig-cl/)
2122
- [IPS $summary implementation with FHIR Topic-Based Subscriptions](ips-subscriptions/)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
FROM docker.io/library/node:22
2+
3+
RUN git clone https://github.com/smart-on-fhir/growth-chart-app.git /app
4+
5+
WORKDIR /app
6+
7+
RUN npm install
8+
9+
EXPOSE 9000
10+
11+
CMD ["npm", "run", "start"]

smart-app-launch-smartbox/README.md

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Example: SMART App Launch using Smartbox and Keycloak
2+
3+
This example showcases the Smart App EHR and Patient [launch flows](https://hl7.org/fhir/smart-app-launch/app-launch.html).
4+
5+
## Components
6+
7+
1. Smartbox FHIR server with SMART-on-FHIR support.
8+
2. [Keycloak](https://www.keycloak.org/)\
9+
Identity and Access Management solution that integrates with Aidbox through the [IdentityProvider](https://docs.aidbox.app/modules/security-and-access-control/set-up-external-identity-provider) resource.
10+
3. [Growth Chart Smart App](https://github.com/smart-on-fhir/growth-chart-app)\
11+
A SMART pediatric web application that displays patient growth charts based on their observations.
12+
4. **Demo Launcher Page**\
13+
A web page that emulates EHR patient context selection.
14+
15+
## Prerequisites
16+
17+
* [Docker](https://www.docker.com/)
18+
* Cloned repository: [Github: Aidbox/examples](https://github.com/Aidbox/examples/tree/main)
19+
* Working directory: `smart-app-launch-smartbox`
20+
21+
To clone the repository and navigate to the `smart-app-launch-smartbox` directory, run:
22+
23+
```sh
24+
git clone [email protected]:Aidbox/examples.git && cd examples/smart-app-launch-smartbox
25+
```
26+
27+
Edit a `docker-compose.yaml` file and paste there your license keys.
28+
29+
```yaml
30+
# docker-compose.yaml
31+
...
32+
services:
33+
portal:
34+
environment:
35+
AIDBOX_LICENSE: <YOUR_PORTAL_LICENSE>
36+
...
37+
sandbox:
38+
environment:
39+
AIDBOX_LICENSE: <YOUR_SANDBOX_LICENSE>
40+
```
41+
42+
## Step 1: Run Demo Components
43+
44+
Start all the demo components by running:
45+
46+
```sh
47+
docker compose up
48+
```
49+
50+
Wait until all components are pulled and started. The components are accessible at:
51+
52+
* Aidbox - [http://localhost:8888](http://localhost:8888)
53+
* Keycloak - [http://localhost:7777](http://localhost:7777)
54+
* Growth Chart - [http://localhost:9000](http://localhost:9000)
55+
* Demo Launcher Page - [http://localhost:7070/launcher.html](http://localhost:7070/launcher.html)
56+
57+
## Step 2: Open launcher Page
58+
59+
Open the [Demo Launcher Page](http://localhost:7070/launcher.html).
60+
61+
* **Left Side:** A list of patients retrieved from Aidbox, simulating EHR patient context selection.
62+
* **Right Side:** A Patient Standalone Launch with a pre-selected patient context, simulating a launch directly from the SMART App.
63+
64+
## Step 3: Perform EHR Launch
65+
66+
**3.1** Select a patient from the list on the left side and click the `Launch Growth Chart App` button to start the launch process.\
67+
**3.2** On the Aidbox login screen, click the `Sign in with Keycloak` button.\
68+
**3.3** Log in to Keycloak with username `patient` and password `password`\
69+
**3.4** On the consent screen, allow all requested scopes.\
70+
**3.5** View the patient's data in the Growth Chart app.
71+
72+
## Step 4: Perform Patient Standalone Launch
73+
74+
**4.1** Go back to the [Demo Launcher](http://localhost:7070/launcher.html)\
75+
**4.2** On the right side of the screen, click the **Launch Growth Chart App** button under Patient Standalone Launch.\
76+
**4.2** On the consent screen, allow all requested scopes.\
77+
**4.3** View the patient's data in the Growth Chart app.
78+
79+
## EHR Launch Interaction Diagram
80+
81+
```mermaid
82+
sequenceDiagram
83+
actor Customer as User
84+
participant EHR as EHR <br> (Demo Launcher)
85+
participant Aidbox as Aidbox
86+
participant Keycloak as Keycloak
87+
participant Smart App as Growth Chart <br> (SMART App)
88+
Note right of EHR: Communicates with Aidbox <br> using HTTP basic auth
89+
Customer ->> EHR: Launch Smart App
90+
activate EHR
91+
EHR ->> Smart App: Launch context
92+
deactivate EHR
93+
activate Smart App
94+
Smart App ->> Aidbox: Redirect to /auth/login?response_type=code&client_id....
95+
deactivate Smart App
96+
activate Aidbox
97+
Aidbox ->> Keycloak: Redirect to Keycloak Login page
98+
deactivate Aidbox
99+
activate Keycloak
100+
Note right of Keycloak: Login with Keycloak credentials
101+
Keycloak ->> Aidbox: Response with code
102+
deactivate Keycloak
103+
activate Aidbox
104+
Aidbox ->> Keycloak: Request to exchange code to token
105+
deactivate Aidbox
106+
activate Keycloak
107+
Keycloak ->> Aidbox: Return token
108+
deactivate Keycloak
109+
activate Aidbox
110+
Aidbox ->> Keycloak: Request user info
111+
deactivate Aidbox
112+
activate Keycloak
113+
Keycloak ->> Aidbox: Return user info
114+
deactivate Keycloak
115+
activate Aidbox
116+
Aidbox ->> Aidbox: Create User resource in Aidbox
117+
Aidbox ->> Customer: Show the Grant screen
118+
deactivate Aidbox
119+
activate Customer
120+
Customer ->> Aidbox: Allow requested scopes
121+
deactivate Customer
122+
activate Aidbox
123+
Aidbox ->> Aidbox: Check granted permissions
124+
Aidbox ->> Smart App: Redirect with code
125+
deactivate Aidbox
126+
activate Smart App
127+
Smart App ->> Aidbox: Request /auth/token <br> to exchange code to token
128+
deactivate Smart App
129+
activate Aidbox
130+
Aidbox ->> Smart App: Return token
131+
deactivate Aidbox
132+
activate Smart App
133+
Smart App ->> Aidbox: Request /Observation and /Patient/<pt-id> with token
134+
deactivate Smart App
135+
activate Aidbox
136+
Aidbox ->> Aidbox: Validate scopes from token
137+
Aidbox ->> Smart App: Return Observations and Patient
138+
deactivate Aidbox
139+
activate Smart App
140+
Smart App ->> Customer: Show patient's data
141+
deactivate Smart App
142+
```

smart-app-launch-smartbox/aidbox.json

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
{
2+
"type": "batch",
3+
"entry": [
4+
{
5+
"request": {
6+
"method": "PUT",
7+
"url": "/Client/growth_chart"
8+
},
9+
"resource": {
10+
"resourceType": "Client",
11+
"id": "growth_chart",
12+
"auth": {
13+
"authorization_code": {
14+
"redirect_uri": "http://localhost:9000/",
15+
"refresh_token": true,
16+
"token_format": "jwt",
17+
"access_token_expiration": 3600000
18+
}
19+
},
20+
"smart": {
21+
"launch_uri": "http://localhost:9000/launch.html"
22+
},
23+
"type": "smart-app",
24+
"secret": "quOfCRS7ty1RMUQq",
25+
"grant_types": [
26+
"authorization_code"
27+
]
28+
}
29+
},
30+
{
31+
"request": {
32+
"method": "PUT",
33+
"url": "/Client/ehr"
34+
},
35+
"resource": {
36+
"id": "ehr",
37+
"secret": "verysecret",
38+
"grant_types": [
39+
"basic"
40+
],
41+
"resourceType": "Client"
42+
}
43+
},
44+
{
45+
"request": {
46+
"method": "PUT",
47+
"url": "/AccessPolicy/demo-clients-allow"
48+
},
49+
"resource": {
50+
"id": "demo-clients-allow",
51+
"link": [
52+
{
53+
"id": "ehr",
54+
"resourceType": "Client"
55+
},
56+
{
57+
"id": "growth_chart",
58+
"resourceType": "Client"
59+
}
60+
],
61+
"engine": "allow",
62+
"resourceType": "AccessPolicy"
63+
}
64+
},
65+
{
66+
"request": {
67+
"method": "PUT",
68+
"url": "/IdentityProvider/keycloak"
69+
},
70+
"resource": {
71+
"resourceType": "IdentityProvider",
72+
"scopes": [
73+
"profile",
74+
"openid"
75+
],
76+
"system": "keycloak",
77+
"userinfo_endpoint": "http://localhost:7777/realms/patients/protocol/openid-connect/userinfo",
78+
"authorize_endpoint": "http://localhost:7777/realms/patients/protocol/openid-connect/auth",
79+
"client": {
80+
"id": "aidbox",
81+
"secret": "HOuPXmduHfTjhtW0eqAeMsHZJbRNVc8x"
82+
},
83+
"title": "Keycloak",
84+
"active": true,
85+
"id": "keycloak",
86+
"token_endpoint": "http://keycloak:7777/realms/patients/protocol/openid-connect/token",
87+
"userinfo-source": "id-token"
88+
}
89+
},
90+
91+
{
92+
"request": {
93+
"method": "POST",
94+
"url": "/Patient/$load"
95+
},
96+
"resource": {
97+
"source": "https://storage.googleapis.com/aidbox-public/synthea/v2/100/fhir/Patient.ndjson.gz"
98+
}
99+
},
100+
{
101+
"request": {
102+
"method": "POST",
103+
"url": "/Observation/$load"
104+
},
105+
"resource": {
106+
"source": "https://storage.googleapis.com/aidbox-public/synthea/v2/100/fhir/Observation.ndjson.gz"
107+
}
108+
}
109+
]
110+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
2+
version: '3.7'
3+
4+
volumes:
5+
aidbox_pg_data: {}
6+
services:
7+
aidbox-db:
8+
image: healthsamurai/aidboxdb:14.5
9+
volumes:
10+
- aidbox_pg_data:/data:delegated
11+
environment:
12+
PGDATA: /data
13+
POSTGRES_USER: postgres
14+
POSTGRES_PASSWORD: postgres
15+
POSTGRES_DB: postgres
16+
17+
portal:
18+
image: healthsamurai/smartbox:2412
19+
depends_on: ["aidbox-db"]
20+
links:
21+
- "aidbox-db:database"
22+
- "sandbox:sandbox"
23+
ports:
24+
- "8888:8888"
25+
volumes:
26+
- ./aidbox.json:/tmp/aidbox.json
27+
environment:
28+
BOX_INIT_BUNDLE: file:///tmp/aidbox.json
29+
PGHOST: "database"
30+
PGDATABASE: "portal"
31+
BOX_AUTH_LOGIN__REDIRECT: "/admin/portal"
32+
BOX_PROJECT_ENTRYPOINT: "smartbox.portal/box"
33+
AIDBOX_LICENSE:
34+
AIDBOX_BASE_URL: "http://localhost:8888"
35+
BOX_SMARTBOX_SANDBOX__URL: "http://sandbox:8888"
36+
BOX_SMARTBOX_SANDBOX__BASIC: "root:secret"
37+
PGPORT: 5432
38+
PGHOSTPORT: 5437
39+
PGUSER: postgres
40+
PGPASSWORD: postgres
41+
AIDBOX_PORT: 8888
42+
43+
44+
sandbox:
45+
image: healthsamurai/smartbox:2412
46+
depends_on: ["aidbox-db"]
47+
links:
48+
- "aidbox-db:database"
49+
ports:
50+
- "9999:8888"
51+
environment:
52+
PGHOST: "database"
53+
PGDATABASE: "sandbox"
54+
BOX_AUTH_LOGIN__REDIRECT: "/"
55+
BOX_PROJECT_ENTRYPOINT: "smartbox.dev-portal/box"
56+
AIDBOX_LICENSE:
57+
AIDBOX_BASE_URL: "http://localhost:9999"
58+
PGPORT: 5432
59+
PGHOSTPORT: 5437
60+
PGUSER: postgres
61+
PGPASSWORD: postgres
62+
AIDBOX_PORT: 8888
63+
64+
growth_chart:
65+
build:
66+
context: .
67+
dockerfile: ./Dockerfile.growthchart
68+
ports:
69+
- 9000:9000
70+
71+
keycloak:
72+
image: quay.io/keycloak/keycloak:26.0.6
73+
volumes:
74+
- ./keycloak.json:/opt/keycloak/data/import/keycloak.json
75+
ports:
76+
- 7777:7777
77+
environment:
78+
KC_HTTP_PORT: 7777
79+
KC_BOOTSTRAP_ADMIN_USERNAME: admin
80+
KC_BOOTSTRAP_ADMIN_PASSWORD: admin
81+
command: start-dev --import-realm
82+
83+
launcher:
84+
image: nginx:alpine
85+
ports:
86+
- "7070:80"
87+
volumes:
88+
- ./launcher.html:/usr/share/nginx/html/launcher.html:r
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Subproject commit ca9fe72a412762b17d33a382650923bf85a262bf

0 commit comments

Comments
 (0)