Appearance
Medical Workflows
1. Getting Started
Here you will learn how to create clinical content for dot.base, e.g. your individual questionnaire. For this, you will build a FHIR resource - but don't worry, we will explain everything step by step.
We start with the Terminology (1) and continue by setting up a GitHub project (2) before you create your first MiniProject (3) and save it (4). Last, but not least we'll show you how to upload and view your MiniProject in dot.base (5).
1.1 Document Templates vs Section Templates
First, let's clarify two important terms, which we will frequently use: document templates
and section templates
. The screenshot below shows a document (blue) that contains multiple sections (red). Document templates
and section templates
are blueprints for these documents and sections respectively.
Let's have a closer look at the section "Procedere". The corresponding section template will contain two things: (1) The section template title which in this case is "Procedere". (2) The definition of three inputs: a single line text input with the title "Geplante diagnostische Verfahren", a single line text input with the title "Geplante therapeutische Verfahren" and a date input with the title "Nächster Termin".
The document template corresponding to the screenshot above contains two things: (1) The document template title which is not visible above but used to choose the type of document a user wants to create. (2) The references to three section templates: the "Aktuelle Anamnese", "Medication" and "Procedere" section templates.
Separating document templates from section templates gives us a modular structure. This enables section templates to be reused for multiple document templates.
1.2 Project Setup
Now that the terminology is out of the way, we'll set up the development environment to create document and section templates. Don't worry, it's straight forward and we've documented everything with screenshots 😉.
1.2.1 GitHub Account
You need a GitHub Account. On the GitHub landingpage you can either create a new account or login.
1.2.2 Fork our samples repository
Find our dot.base samples repository. Now you are going to create your own copy (fork) of our dot.base samples repository by forking it. No worries, just follow the steps below or watch this helpful introduction video How to fork in GitHub:
Click the arrow right next to the button (1)Fork
in the top right corner > the plus for (2)Create a new fork
.
Change the (1) Repository name
(i.g. to the name of the questionnaire you want to create) or leave it called samples
> Click (2) Create fork
.
Check, whether underneath YOUR_GITHUB_USERNAME/GIVEN_REPOSITORY_TITL
is stated that this repository is (1) forked from dot-base/samples
.
Well done, you have successfully forked a repository, which you can now work on locally!
1.2.3 Open the online VSCode Editor
Open the repository in the Online VSCode Editor by simply pressing .
on your keyboard. If that does not work you can also copy this URL into your browser (replace the stuff in caps): https://github.dev/YOUR_GITHUB_USERNAME/GIVEN_REPOSITORY_TITLE
. Inside the repository, open the (1) README.md
file. It contains important information on the samples' repository structure and how to use it. Read it.
Congrats, you are set-up and ready to create some templates 🎉.
1.3 Create your first MiniProject with document and section templates
Let's start creating your first document and section templates before diving deeper into the material of the other chapters. For now, open the directories /1-creating-clinical-content/1-mini-project
, where you will find two *.json files containing the document template and the section template of your MiniProject.
The files should looke like this:
section-template.json
Â
Â
Â
Â
Â
Â
{
"resourceType": "Questionnaire",
"url": "https://dotbase.org/fhir/Questionnaire/SECTION-TEMPLATE-ID",
"id": "parkinson-questionnaire-SECTION-TEMPLATE-ID",
"name": "SECTION-TEMPLATE-ID",
"title": "SECTION-TEMPLATE-TEXT",
"status": "active",
"subjectType": ["Patient"],
"publisher": "Charité – Universitätsmedizin Berlin",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/document-summary-template",
"valueMarkdown": "no markdown yet"
}
],
"item": [
{
"linkId": "explanation-group",
"type": "group",
"item": [
{
"linkId": "explanation",
"text": "SECTION-TEMPLATE-TEXT",
"type": "display"
}
]
},
{
"linkId": "date-pickers-1",
"text": "Date Pickers",
"type": "group",
"item": [
{
"linkId": "day-picker",
"text": "SECTION-TEMPLATE-TEXT",
"type": "date",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "day"
}
]
}
}
]
}
]
}
document-template.json
Â
Â
Â
Â
Â
Â
Â
{
"resourceType": "PlanDefinition",
"url": "https://dotbase.org/fhir/PlanDefinition/DOCUMENT-TEMPLATE-ID",
"title": "DOCUMENT-TEMPLATE-TITLE",
"id": "parkinson-plandefinition-DOCUMENT-TEMPLATE-ID",
"description": "DOCUMENT-TEMPLATE-DESCRIPTION",
"status": "active",
"publisher": "Charité – Universitätsmedizin Berlin",
"action": [
{
"title": "DOCUMENT-TEMPLATE-TITLE",
"code": [
{
"coding": [
{
"system": "https://dotbase.org/fhir/CodeSystem/section-template-type",
"code": "questionnaire",
"display": "Questionnaire"
}
]
}
],
"definitionCanonical": "https://dotbase.org/fhir/Questionnaire/SECTION-TEMPLATE-ID",
"_definitionCanonical": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/definition-canonical-reference",
"valueReference": {
"reference": "Questionnaire/SECTION-TEMPLATE-ID"
}
}
]
}
}
],
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/document-template-maintainer",
"valueReference": {
"reference": "Organization/dotbase-organization-mainorganization"
}
}
],
"topic": {
"coding": [
{
"system": "https://dotbase.org/fhir/CodeSystem/document-template-type",
"code": "document"
}
]
}
}
Both files are ready to be downloaded and used on our demo instance. If you know what you are doing and want to customize the files right now, replace the strings in capital letters in all files and customize away. Otherwise, just continue with the next step 😉.
1.4 Upload your project
Now watch your MiniProject come to life. Therefore you will upload your document template and section template into the dot.base demo instance.
1.4.1 Login to dot.base demo instance
Open a browser (we recommend a chromium based browser like Edge or Chrome). (1) Navigate to https://demo.dotbase.org/, type in (2) username
, (3) password
and click (4) Go
to login.
1.4.2 Enable experimental features
Click (1) Extras
> (2) Browser tools
> (3) Tools for web developers
.
Click (1) Web Storage
, (2) Local Storage
, (3) https://demo.dotbase.org/
and finally the (4)+
button to add a new entry.
Double click the "Key" column of the new entry and name it (5) experimental_features
. Double click the "Value" column of the new entry and type (6) true
.
Reload the webpage. Now you should notice a sign in the lower right corner saying (7) Experimental features enabled
. Click (8) x
to close the developer tools window.
1.4.3 Upload your project using the FHIR Ressource Manager
Click (1) FHIR Ressource Manager
.
(1) Drag and Drop
your prior downloaded files document-template.json
and section-template.json
one by one. Start with the section-template.json
. Click the button (2) An den Server schicken
to upload the files. Check, whether you see your code under (3) Antwort:
without any error messages. If error messages occur, you have to edit your files, download them from your editor and upload them again.
1.4.4 Test your project
After every upload in the FHIR Ressource Manager, you need to refresh the website. Do that by using your browser reload button.
Disclaimer: all patients, that you can see in this screenshot, are randomly generated and don´t exist.
Click (1) Home
> (2) Alle Patient:innen durchsuchen
> any (3) patient record
.
Click (1) Neues Dokument
. Choose your questionnaire, e.g. (2) REPLACEME-TITLE
.
Fill out your own questionnare and test whether it works as expected. Also test whether you are able to save your questionnaire.
This is it. Congratulations on your first questionnaire 🎉!
2. Section Templates
As you may remeber, we use section templates in order to build your individual questionnaires. For a section template you need to build a FHIR ressource called Questionnaire
. In this chapter we'll guide you through the creation of section templates.
TIP
Before you continue, please make sure you have read the README.md
in our samples repository and the overview chapter of this documentation.
2.1 Mandatory steps of section template creation
Check your local samples repository and open the directories /1-creating-clinical-content/2-example-without-choices
. Inside you'll find a file section-template.json
, which you open in the VSCode Editor by pressing the button .
on your keyboard. This questionnaire contains an excerpt of input types. Now you only have to modify the highlighted lines by replacing the strings, written in capital letters.
section-template.json
Â
Â
Â
Â
Â
{
"resourceType": "Questionnaire",
"url": "https://dotbase.org/fhir/Questionnaire/SECTION-TEMPLATE-ID",
"id": "SECTION-TEMPLATE-ID",
"name": "SECTION-TEMPLATE-ID",
"title": "SECTION-TEMPLATE-TITLE",
"description": "SECTION-TEMPLATE-DESCRIPTION",
"status": "active",
"subjectType": ["Patient"],
"publisher": "Charité – Universitätsmedizin Berlin",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/document-summary-template",
"valueMarkdown": "# Booleans\n- The value of boolean 1 is {{boolean-1}}.\n{{#if boolean-1}}- This line is rendered because boolean 1 is true.{{/if}}{{#unless boolean-1}}* This line is rendered because boolean 1 is false.{{/unless}}\n-The value of attachment 1 is {{attachment-1}}"
}
],
"item": [
{
"linkId": "boolean-group",
"text": "Booleans",
"type": "group",
"item": [
{
"linkId": "boolean-1",
"text": "Boolean 1",
"code": [
{
"system": "https://snomed.info/sct",
"code": "372073000"
}
],
"type": "boolean"
}
]
},
{
"linkId": "decimals",
"text": "Decimals",
"type": "group",
"item": [
{
"linkId": "decimal-1",
"text": "Stepsize 0.1, Unit mm",
"type": "decimal",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-unit",
"valueCoding": {
"system": "https://unitsofmeasure.org",
"code": "mm"
}
},
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-step-size",
"valueDecimal": 0.1
}
]
}
]
},
{
"linkId": "integers",
"text": "Integers",
"type": "group",
"item": [
{
"linkId": "integer-1",
"text": "Stepsize 1, Unit mm",
"type": "integer",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-unit",
"valueCoding": {
"system": "https://unitsofmeasure.org",
"code": "mm"
}
},
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-step-size",
"valueDecimal": 1
}
]
}
]
},
{
"linkId": "date-pickers-1",
"text": "Date Pickers",
"type": "group",
"item": [
{
"linkId": "day-picker",
"text": "Day Picker",
"type": "date",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "day"
}
]
}
},
{
"linkId": "month-picker",
"text": "Month Picker",
"type": "date",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "month"
}
]
}
}
]
},
{
"linkId": "date-time-group-1",
"text": "Date and Time Pickers",
"type": "group",
"item": [
{
"linkId": "date-time-1",
"text": "Date and Time 1",
"type": "dateTime"
}
]
},
{
"linkId": "time-group",
"text": "Time Pickers",
"type": "group",
"item": [
{
"linkId": "time-1",
"text": "Time 1",
"type": "time"
}
]
},
{
"linkId": "string-group",
"text": "Single-line Texts",
"type": "group",
"item": [
{
"linkId": "string-1",
"text": "String 1",
"type": "string"
}
]
},
{
"linkId": "text-group",
"text": "Multi-line Texts",
"type": "group",
"item": [
{
"linkId": "text-1",
"text": "Text 1",
"type": "text"
}
]
},
{
"linkId": "url-group",
"text": "Urls",
"type": "group",
"item": [
{
"linkId": "url-1",
"text": "Url 1",
"type": "url"
}
]
},
{
"linkId": "attachment-group",
"text": "Attachments",
"type": "group",
"repeats": true,
"item": [
{
"linkId": "attachment-1",
"text": "Attachment 1",
"type": "attachment"
},
{
"linkId": "multi-attachment",
"text": "Multiple File Attachment",
"type": "attachment",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "multiple-attachment"
}
]
}
}
]
},
{
"linkId": "repeating-group",
"text": "Repeating Groups",
"type": "group",
"repeats": true,
"item": [
{
"linkId": "repeating-boolean-1",
"text": "Boolean",
"type": "boolean"
},
{
"linkId": "repeating-url-1",
"text": "Url",
"type": "url"
},
{
"linkId": "repeating-date-time",
"text": "Date and Time",
"type": "dateTime"
}
]
}
]
}
2.1.1 Writing the markdown
Writing the markdown is a mandatory part of your section template. The markdown is declared in a field called "valueMarkdown". In our example above this can be found in line 14
.
line 14 in section-template.json
We recommend to open VSCode Editor, create a new file and paste the markdown text above. We only need this file for this step and it can be deleted afterwards. Now, detangle the markdown text by adding a newline after each \n
.
TIP
VSCode has a build-in search and replace function (CTRL + h) which you can utilize to do that tedious task for you.
After detangling your file should look like this:
detangled markdown
To create the markdown text for each question, fill in the REPLACEME
and the text of each question that you have created earlier. Once you have created a markdown line for all questions, delete all the newlines, which you created in the first step. Your markdown text should be one long line of text again. Copy and paste your markdown sentence back into your section template file.
2.2 Optional steps of section template creation
In these two subchapters you learn how to create advanced section templates. In subchapter 2.1 you learn how to create Value Sets
, which you need in case your questionnaire contains advanced input types like choices
. In subchapter 2.2 we present how to calculate a score
, assuming that your questionnaire consists only of numeric input elements.
2.2.1 Value Sets
Value Sets are necessary if you use choices
as input types in your questionnaire because that's where the answers to your choices are stored. In your samples repository, you find a directory called /1-creating-clinical-content/2-example-all-input-types
, which includes the files document-template.json
, section-template.json
, and two Value Sets valueset-long.json
and valueset-short.json
.
The section-template.json
file contains all input types, that you can use to build section templates in dot.base, so it´s worth checking out! As you can see from the highlighted lines below, these Value Sets valueset-long.json
and valueset-short.json
are linked several times. This means, that if you change the IDs of the Value Sets in the following step, you must also change the references to them in the section-template.json
.
section-template.json containing all input types
Â
Â
Â
Â
Â
Â
Â
Â
{
"resourceType": "Questionnaire",
"url": "https://dotbase.org/fhir/Questionnaire/all-input-types-SECTION-TEMPLATE-ID",
"id": "all-input-types-SECTION-TEMPLATE-ID",
"name": "all-input-types-SECTION-TEMPLATE-ID",
"title": "all-input-types-SECTION-TEMPLATE-TITLE",
"description": "all-input-types-SECTION-TEMPLATE-DESCRIPTION",
"status": "active",
"subjectType": ["Patient"],
"publisher": "Charité – Universitätsmedizin Berlin",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/document-summary-template",
"valueMarkdown": "# Booleans\n- The value of boolean 1 is {{boolean-1}}.\n{{#if boolean-1}}- This line is rendered because boolean 1 is true.{{/if}}{{#unless boolean-1}}* This line is rendered because boolean 1 is false.{{/unless}}\n\n# Choices\n{{#if multiple-choice}}- Multiple Choice answers:{{#each multiple-choice}}\n - {{this.display}}{{/each}}{{/if}}\n-The value of attachment 1 is {{attachment-1}} viewer: {{#viewer attachment-1}}{{/viewer}}"
}
],
"item": [
{
"linkId": "boolean-group",
"text": "Booleans",
"type": "group",
"item": [
{
"linkId": "boolean-1",
"text": "Boolean 1",
"code": [
{
"system": "https://snomed.info/sct",
"code": "372073000"
}
],
"type": "boolean"
},
{
"linkId": "boolean-2",
"text": "Boolean 2",
"code": [
{
"system": "https://snomed.info/sct",
"code": "372073000"
}
],
"type": "boolean"
},
{
"linkId": "boolean-3",
"text": "Boolean 3",
"code": [
{
"system": "https://snomed.info/sct",
"code": "372073000"
}
],
"type": "boolean"
},
{
"linkId": "boolean-4",
"text": "Boolean 4",
"code": [
{
"system": "https://snomed.info/sct",
"code": "372073000"
}
],
"type": "boolean"
},
{
"linkId": "boolean-5",
"text": "Boolean 5",
"code": [
{
"system": "https://snomed.info/sct",
"code": "372073000"
}
],
"type": "boolean"
},
{
"linkId": "boolean-6",
"text": "Boolean 6",
"code": [
{
"system": "https://snomed.info/sct",
"code": "372073000"
}
],
"type": "boolean"
}
]
},
{
"linkId": "choices",
"text": "Choices",
"type": "group",
"item": [
{
"linkId": "choice-radio-button",
"text": "Choice - Radio Button",
"code": [
{
"system": "https://snomed.info/sct",
"code": "372073000"
}
],
"type": "choice",
"answerValueSet": "https://dotbase.org/fhir/ValueSet/all-input-types-VALUE-SET-SHORT-ID"
},
{
"linkId": "open-choice-radio-button",
"text": "Open Choice - Radio Button",
"code": [
{
"system": "https://snomed.info/sct",
"code": "119235005"
}
],
"type": "open-choice",
"answerValueSet": "https://dotbase.org/fhir/ValueSet/all-input-types-VALUE-SET-SHORT-ID"
},
{
"linkId": "annotated-choice-radio-button",
"text": "Annotated Choice - Radio Button",
"code": [
{
"system": "https://snomed.info/sct",
"code": "119235005"
}
],
"repeats": true,
"type": "open-choice",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "annotated-choice"
}
]
},
"answerValueSet": "https://dotbase.org/fhir/ValueSet/all-input-types-VALUE-SET-SHORT-ID"
},
{
"linkId": "choice-select",
"text": "Choice - Select",
"code": [
{
"system": "https://snomed.info/sct",
"code": "360091001"
}
],
"type": "choice",
"answerValueSet": "https://dotbase.org/fhir/ValueSet/all-input-types-VALUE-SET-LONG-ID"
},
{
"linkId": "open-choice-select",
"text": "Open Choice - Select",
"code": [
{
"system": "https://snomed.info/sct",
"code": "25937001"
}
],
"type": "open-choice",
"answerValueSet": "https://dotbase.org/fhir/ValueSet/all-input-types-VALUE-SET-LONG-ID"
},
{
"linkId": "annotated-choice-select",
"text": "Annotated Choice - Select",
"code": [
{
"system": "https://snomed.info/sct",
"code": "25937001"
}
],
"repeats": true,
"type": "open-choice",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "annotated-choice"
}
]
},
"answerValueSet": "https://dotbase.org/fhir/ValueSet/all-input-types-VALUE-SET-LONG-ID"
},
{
"linkId": "multiple-choice",
"text": "Multiple Choice",
"type": "choice",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "multiple-choice"
}
]
},
"answerValueSet": "https://dotbase.org/fhir/ValueSet/all-input-types-VALUE-SET-SHORT-ID"
},
{
"linkId": "next-question-has-enable-when",
"text": "The next question contains an enable-when behavior and will only be visible if you choose 'Choice 1' AND NOT 'Choice 3' on the previous question.",
"type": "display"
},
{
"linkId": "multiple-choice-many-choices",
"text": "Multiple Choice - Many Choices",
"type": "choice",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "multiple-choice"
}
]
},
"answerValueSet": "https://dotbase.org/fhir/ValueSet/all-input-types-VALUE-SET-LONG-ID",
"enableWhen": [
{
"question": "multiple-choice",
"operator": "=",
"answerCoding": {
"code": "choice-1",
"display": "Choice 1"
}
},
{
"question": "multiple-choice",
"operator": "!=",
"answerCoding": {
"code": "choice-3",
"display": "Choice 3"
}
}
],
"enableBehavior": "all"
}
]
},
{
"linkId": "decimals",
"text": "Decimals",
"type": "group",
"item": [
{
"linkId": "decimal-1",
"text": "Stepsize 0.1, Unit mm",
"type": "decimal",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-unit",
"valueCoding": {
"system": "https://unitsofmeasure.org",
"code": "mm"
}
},
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-step-size",
"valueDecimal": 0.1
}
]
},
{
"linkId": "decimal-2",
"text": "Stepsize 0.5, Without Unit",
"type": "decimal",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-step-size",
"valueDecimal": 0.5
}
]
}
]
},
{
"linkId": "integers",
"text": "Integers",
"type": "group",
"item": [
{
"linkId": "integer-1",
"text": "Stepsize 1, Unit mm",
"type": "integer",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-unit",
"valueCoding": {
"system": "https://unitsofmeasure.org",
"code": "mm"
}
},
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-step-size",
"valueDecimal": 1
}
]
},
{
"linkId": "integer-2",
"text": "Stepsize 5, Unit kg",
"type": "integer",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-unit",
"valueCoding": {
"system": "https://unitsofmeasure.org",
"code": "kg"
}
},
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-step-size",
"valueDecimal": 5
}
]
},
{
"linkId": "integer-3",
"text": "Stepsize 5, Without Unit",
"type": "integer",
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-step-size",
"valueDecimal": 5
}
]
}
]
},
{
"linkId": "date-pickers-1",
"text": "Date Pickers",
"type": "group",
"item": [
{
"linkId": "day-picker",
"text": "Day Picker",
"type": "date",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "day"
}
]
}
},
{
"linkId": "month-picker",
"text": "Month Picker",
"type": "date",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "month"
}
]
}
}
]
},
{
"linkId": "date-pickers-2",
"type": "group",
"item": [
{
"linkId": "year-picker-1",
"text": "Year Picker",
"type": "date",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "year"
}
]
}
},
{
"linkId": "year-picker-2",
"text": "Year Picker",
"type": "date",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "year"
}
]
}
},
{
"linkId": "year-picker-3",
"text": "Year Picker",
"type": "date",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "year"
}
]
}
}
]
},
{
"linkId": "date-time-group-1",
"text": "Date and Time Pickers",
"type": "group",
"item": [
{
"linkId": "date-time-1",
"text": "Date and Time 1",
"type": "dateTime"
}
]
},
{
"linkId": "date-time-group-2",
"type": "group",
"item": [
{
"linkId": "date-time-2",
"text": "Date and Time 2",
"type": "dateTime"
},
{
"linkId": "date-time-3",
"text": "Date and Time 3",
"type": "dateTime"
}
]
},
{
"linkId": "time-group",
"text": "Time Pickers",
"type": "group",
"item": [
{
"linkId": "time-1",
"text": "Time 1",
"type": "time"
},
{
"linkId": "time-2",
"text": "Time 2",
"type": "time"
},
{
"linkId": "time-3",
"text": "Time 3",
"type": "time"
}
]
},
{
"linkId": "string-group",
"text": "Single-line Texts",
"type": "group",
"item": [
{
"linkId": "string-1",
"text": "String 1",
"type": "string"
},
{
"linkId": "string-2",
"text": "String 2",
"type": "string"
},
{
"linkId": "string-3",
"text": "String 3",
"type": "string"
},
{
"linkId": "string-4",
"text": "String 4",
"type": "string"
},
{
"linkId": "string-5",
"text": "String 5",
"type": "string"
}
]
},
{
"linkId": "text-group",
"text": "Multi-line Texts",
"type": "group",
"item": [
{
"linkId": "text-1",
"text": "Text 1",
"type": "text"
},
{
"linkId": "text-2",
"text": "Text 2",
"type": "text"
},
{
"linkId": "text-3",
"text": "Text 3",
"type": "text"
},
{
"linkId": "text-4",
"text": "Text 4",
"type": "text"
},
{
"linkId": "text-5",
"text": "Text 5",
"type": "text"
}
]
},
{
"linkId": "url-group",
"text": "Urls",
"type": "group",
"item": [
{
"linkId": "url-1",
"text": "Url 1",
"type": "url"
},
{
"linkId": "url-2",
"text": "Url 2",
"type": "url"
}
]
},
{
"linkId": "attachment-group",
"text": "Attachments",
"type": "group",
"repeats": true,
"item": [
{
"linkId": "attachment-1",
"text": "Attachment 1",
"type": "attachment"
},
{
"linkId": "attachment-2",
"text": "Attachment 2",
"type": "attachment"
},
{
"linkId": "multi-attachment",
"text": "Multiple File Attachment",
"type": "attachment",
"_type": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-item-type",
"valueCode": "multiple-attachment"
}
]
}
}
]
},
{
"linkId": "repeating-group",
"text": "Repeating Groups",
"type": "group",
"repeats": true,
"item": [
{
"linkId": "repeating-boolean-1",
"text": "Boolean",
"type": "boolean"
},
{
"linkId": "repeating-url-1",
"text": "Url",
"type": "url"
},
{
"linkId": "repeating-date-time",
"text": "Date and Time",
"type": "dateTime"
}
]
}
]
}
For now let´s concentrate on the file sc, which ensures that you can create choice-based questions within dot.base. Choices will look like this:
In the corresponding code you only have to modify the highlighted lines by replacing the strings, written in capital letters.
valueset-short.json
Â
Â
Â
Â
Â
{
"resourceType": "ValueSet",
"id": "all-input-types-VALUE-SET-SHORT-ID",
"meta": {
"profile": ["http://hl7.org/fhir/StructureDefinition/shareablevalueset"]
},
"url": "https://dotbase.org/fhir/ValueSet/all-input-types-VALUE-SET-SHORT-ID",
"description": "all-input-types-VALUE-SET-SHORT-DESCRIPTION",
"name": "all-input-types-VALUE-SET-SHORT-ID",
"title": "all-input-types-VALUE-SET-SHORT-TITLE",
"experimental": true,
"status": "active",
"version": "1.0.0",
"publisher": "Charité – Universitätsmedizin Berlin",
"compose": {
"include": [
{
"system": "https://dotbase.org/fhir/CodeSystem/short-list-of-choices",
"concept": [
{
"code": "choice-1",
"display": "Choice 1"
},
{
"code": "choice-2",
"display": "Choice 2"
},
{
"code": "choice-3",
"display": "Choice 3"
}
]
}
]
}
}
The difference between valueset-short.json
and valueset-long.json
is the number of answer options for the choice questions. Since valueset-long.json
has a large number of answer options, the corresponding question will be displayed differently. Instead of a radio button (screenshot above), a question with valueset-long.json` will result in a select input like this:
2.2.2 Calculating scores
For calculating the final score of a questionnaire, we are going to use the new exemplary questionnaire TWSTRS
, whose input types are all numeric. You can find it in your samples repository in the ordner Example_score-calculation
. There you find multiple Value Sets
, the SectionTemplate-questionnaire-score.json
and the DocumentTemplate-score.json
which are already uploaded to our demo instance.
2.2.2.1 Open a questionnaire on our demo instance
Login to our demo instance, open a random patients´ health record, search for the questionnaire TWSTRS
and fill it out.
In case you want to create a score calculation for your own questionnaire, you have to upload your questionnaire and document template to our demo instance before continuing with the score calculation. Therefore follow the steps in section 5. Upload your ressource. After the upload, open your questionnaire in a random patient´s health record. Then fill out the questionnaire to generate answers.
2.2.2.2 Copying the patient ID
While having the health record of your patient still open on your screen, take a look at the URL of your browser, which will look like this:
https://demo.dotbase.org/patient/f6fef2cd-805a-4d7c-963d-072bd00e065f
Copy the last and cryptic part of this URL, which is the ID
of your patient.
f6fef2cd-805a-4d7c-963d-072bd00e065f
2.2.2.3 Pasting the patient ID into an URL
Into this url, paste the ID of your patient after subject=
and the URL of your questionnaire template after questionnaire=
.
https://demo.dotbase.org/api/fhir/QuestionnaireResponse?subject=f6fef2cd-805a-4d7c-963d-072bd00e065f&_sort=-_lastUpdated&questionnaire=https://dotbase.org/fhir/Questionnaire/twstrs
2.2.2.4 Open the newly created URL in a tab & copy the response body
Now you can open the link in a new tab. It should look similar to this:
.
Copy a (1) QuestionnaireResponse resource
from the returned search Bundle, which looks similiar to this:
"resource": {
"resourceType": "QuestionnaireResponse",
"id": "c3d8b4e9-bb96-4368-a00d-34fe34213954",
"meta": {
"extension": [ {
"url": "https://dotbase.org/fhir/StructureDefinition/resource-creation-datetime",
"valueDateTime": "2023-05-12T15:05:53.866+00:00"
} ],
"versionId": "1",
"lastUpdated": "2023-05-12T15:05:53.860+00:00",
"source": "#yHToSQEpeJCjwtIY"
},
"questionnaire": "https://dotbase.org/fhir/Questionnaire/twstrs",
"_questionnaire": {
"extension": [ {
"url": "https://dotbase.org/fhir/StructureDefinition/questionnaire-canonical-reference",
"valueReference": {
"reference": "Questionnaire/parkinson-questionnaire-twstrs"
}
} ]
},
"status": "completed",
"subject": {
"reference": "Patient/f6fef2cd-805a-4d7c-963d-072bd00e065f"
},
"item": [ {
"linkId": "torticollis-severity-scale",
"item": [ {
"linkId": "maximal-excursion",
"item": [ {
"linkId": "rotation",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-maximal-excursion-rotation",
"code": "3",
"display": "3"
}
} ]
}, {
"linkId": "laterocollis",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-maximal-excursion-laterocollis",
"code": "2",
"display": "2"
}
} ]
}, {
"linkId": "anterocollis-or-retrocollis-group",
"item": [ {
"linkId": "anterocollis-or-retrocollis-choice",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-anterocollis-or-retrocollis",
"code": "retrocollis",
"display": "Retrocollis"
}
} ]
}, {
"linkId": "anterocollis-or-retrocollis-maximal-excursion",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-maximal-excursion-anterocollis-or-retrocollis",
"code": "3",
"display": "3"
}
} ]
} ]
}, {
"linkId": "lateral-shift",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-maximal-excursion-lateral-shift",
"code": "1",
"display": "1"
}
} ]
}, {
"linkId": "sagittal-shift",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-maximal-excursion-sagittal-shift",
"code": "1",
"display": "1"
}
} ]
} ]
}, {
"linkId": "duration-factor",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-duration-factor",
"code": "8",
"display": "4"
}
} ]
}, {
"linkId": "effect-of-sensory-tricks",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-effect-of-sensory-tricks",
"code": "1",
"display": "1"
}
} ]
}, {
"linkId": "shoulder-elevation-anterior-displacement",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-shoulder-elevation-anterior-displacement",
"code": "1",
"display": "1"
}
} ]
}, {
"linkId": "range-of-motion",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-range-of-motion",
"code": "2",
"display": "2"
}
} ]
}, {
"linkId": "time",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-time",
"code": "1",
"display": "1"
}
} ]
} ]
}, {
"linkId": "disability-scale",
"item": [ {
"linkId": "work",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-work",
"code": "2",
"display": "2"
}
} ]
}, {
"linkId": "activities-of-daily-living",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-activities-of-daily-living",
"code": "1",
"display": "1"
}
} ]
}, {
"linkId": "driving",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-driving",
"code": "2",
"display": "2"
}
} ]
}, {
"linkId": "reading",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-reading",
"code": "1",
"display": "1"
}
} ]
}, {
"linkId": "television",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-television",
"code": "2",
"display": "2"
}
} ]
}, {
"linkId": "activities-outside-the-home",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-activities-outside-the-home",
"code": "3",
"display": "3"
}
} ]
} ]
}, {
"linkId": "pain-scale",
"item": [ {
"linkId": "severity-of-pain-group",
"item": [ {
"linkId": "severity-of-pain-worst",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-severity-of-pain",
"code": "2",
"display": "2"
}
} ]
}, {
"linkId": "severity-of-pain-best",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-severity-of-pain",
"code": "3",
"display": "3"
}
} ]
}, {
"linkId": "severity-of-pain-usual",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-severity-of-pain",
"code": "3",
"display": "3"
}
} ]
} ]
}, {
"linkId": "duration-of-pain",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-duration-of-pain",
"code": "2",
"display": "2"
}
} ]
}, {
"linkId": "disability-due-to-pain",
"answer": [ {
"valueCoding": {
"system": "https://dotbase.org/fhir/CodeSystem/twstrs-disability-due-to-pain",
"code": "3",
"display": "3"
}
} ]
} ]
}, {
"linkId": "twstrs-score",
"item": [ {
"linkId": "subtotal-severity",
"answer": [ {
"valueDecimal": 23
} ]
}, {
"linkId": "subtotal-disability",
"answer": [ {
"valueDecimal": 11
} ]
}, {
"linkId": "subtotal-pain",
"answer": [ {
"valueDecimal": 7.75
} ]
}, {
"linkId": "total-score",
"answer": [ {
"valueDecimal": 41.75
} ]
} ]
} ]
}
2.2.2.5 Open the FHIRpath creator
Open this link of the the FHIRpath creator and paste in the QuestionnaireReponse
:
.
2.2.2.6 Create FHIRpath query
Now we have finally reached the step where we calculate the final score of our questionnaire. For this we develop the (1) FHIRpath query
.
In the case of the TWSTRS questionnaire, the FHIRpath query
is:
iif(QuestionnaireResponse.item.where(linkId='twstrs-score').item.where(linkId!='total-score').where(item.empty()).count()=QuestionnaireResponse.item.where(linkId='twstrs-score').item.where(linkId!='total-score').answer.count(), QuestionnaireResponse.item.where(linkId='twstrs-score').item.where(linkId!='total-score').answer.select(valueDecimal).aggregate($this + $total, 0))
If you need help creating the final score of your questionnaire, check out the FHIRpath documentation. There you get introduced to all possible functions, which you might need for your score calculation. For example aggregates function in chapter 7:
value.aggregate($this + $total, 0)
3. Document Templates
Now that you have created your section template, we need to make sure that you can see your questionnaire in the frontend. Therefore we are building the document template. Let´s start by checking out the directory /1-creating-clinical-content/2-example-without-choices
and opening the file document-template.json
. Now, you only have to modify the highlighted lines by replacing the snippets, which are written in capital letters.
document-template.json
Â
Â
Â
Â
Â
Â
Â
{
"resourceType": "PlanDefinition",
"url": "https://dotbase.org/fhir/PlanDefinition/DOCUMENT-TEMPLATE-ID",
"title": "DOCUMENT-TEMPLATE-TITLE",
"id": "parkinson-plandefinition-DOCUMENT-TEMPLATE-ID",
"description": "DOCUMENT-TEMPLATE-DESCRIPTION",
"status": "active",
"publisher": "Charité – Universitätsmedizin Berlin",
"action": [
{
"title": "SECTION-TEMPLATE-TITLE",
"code": [
{
"coding": [
{
"system": "https://dotbase.org/fhir/CodeSystem/section-template-type",
"code": "questionnaire",
"display": "Questionnaire"
}
]
}
],
"definitionCanonical": "https://dotbase.org/fhir/Questionnaire/SECTION-TEMPLATE-ID",
"_definitionCanonical": {
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/definition-canonical-reference",
"valueReference": {
"reference": "Questionnaire/SECTION-TEMPLATE-ID"
}
}
]
}
}
],
"extension": [
{
"url": "https://dotbase.org/fhir/StructureDefinition/document-template-maintainer",
"valueReference": {
"reference": "Organization/dotbase-organization-mainorganization"
}
}
],
"topic": {
"coding": [
{
"system": "https://dotbase.org/fhir/CodeSystem/document-template-type",
"code": "document"
}
]
}
}
4. Submitting Clinical Content
In this chapter we will show you how to easily share your FHIR resource with our dot.base community. This way you can help other dot.base users to benefit from your well thought-out questionnaires.
4.1 Commit your changes
You commit your changes in the files by clicking on (1) Source code management
in the editor on the left bar, then briefly describe the changes you made as a (2) message
and finally commit and push them via (3) clicking the checkmark
.
Alternatively, you can check out this Youtube video on how to commit and push in VSCode Editor.
4.2 How to create a pull requests in Github
After committing your changes to your own fork of the samples repository, it´s time to contribute to the original dotbase samples repository by making a pull request.
There are already good instructions out there on Youtube, that explains the process of a pull request. If you just need to brush up on your knowledge, this video might fit the bill. If you are new to the process, this is a more detailed video.