The Opal Room Management System (ORMS) provides a clinical viewer (aka. live clinician dashboard), a virtual waiting room and separate frontends for kiosks and TV screens.
This project has the following requirements to be available on your system:
- Docker Desktop (or Docker Engine on Linux)
- Composer for installing
PHPcode quality dependencies that used in git hooks - Optional: node v20 (needed if you want to invoke
npmcommands locally)
After cloning this repo, follow the below steps to get started.
All configuration is stored within the .env file to follow the 12factor app methodology on storing config in the environment. This means that any setting that depends on the environment the app is run in should be exposed via the .env.
Copy the .env.sample to .env and adjust the values as necessary. You need to set FIREBASE_CONFIG_PATH and FIREBASE_BRANCH for the Virtual Waiting Room page. The firebase configuration file needs to be present in FIREBASE_CONFIG_PATH. In the firebase configuration file, apiKey, authDomain, databaseURL and projectId must be defined.
These configuration parameters are read by docker compose and by php/class/Config.php (via phpdotenv).
If your database is being run with secure transport required (SSL/TLS traffic encryption), also update the values for the SSL environment variables: DATABASE_USE_SSL=1 and SSL_CA=/var/www/orms/certs/ca.pem after copying the ca.pem file into the certs directory of ORMs. Detailed instructions on how to generate SSL certificates can be found either in the documentation repository or in the db-docker README.
This project uses AngularJS which reached end of life in January 2022.
A long-term support version of AngularJS can be used instead, provided by HeroDevs.
If you have an npm token to retrieve this version from their registry, place the .npmrc file containing the credentials in the root directory.
This project comes with a docker-compose.yml file providing you with db-orms and db-log databases, as well as the app in their respective containers. In addition, the following services are required:
memcachedfor storing the sessions in-memorycrunzfor running a cron daemon
The ORMS app is built with a custom image (defined in Dockerfile).
Execute the following command to start up the containers:
docker compose upNote: The ORMS application is not available in the root path but rather under /orms. For example: http://localhost:8086/orms
If you need to rebuild the containers, you can either run docker compose build before starting the container or docker compose up --build to force a rebuild. To rebuild containers without Docker’s build cache, run: docker compose build --no-cache.
To connect to the app container, run docker compose exec app bash (or any specific command instead of bash).
The current Dockerfile is using a multi-stage build to avoid having unnecessary dependencies in the final image. For example, to run ORMS node, npm and composer are not needed.
If you need to run npm commands you can either do it using your locally installed node or run a separate container:
docker run --rm -it -v $PWD:/app --workdir /app node:20 npm install markdownlint2-cliFor installing composer dependencies, the same concept is used as for the npm dependencies.
In order for linting, type checking, unit testing etc., to be available in your IDE and githooks, we recommend to install the dependencies inside working/root directory. Although the Docker container automatically installs all the required dependencies, they cannot be seen by the IDE for the code quality tools and githooks.
To quickly install the composer in the current directory, run the following script in your terminal:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === 'baf1608c33254d00611ac1705c1d9958c817a1a33bce370c0595974b342601bd80b92a3f46067da89e3b06bff421f182') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"After running the installer, you can run this to move composer.phar to a directory that is in your path, so you can access it globally.
mv composer.phar /usr/local/bin/composerFor more details look here and here.
After installing composer, run one of the following commands for installing PHP dependencies:
./composer.phar installor
composer installFor testing Clinical Viewer and Virtual Waiting Room locally:
- Set
OpalUUIDfield in thePatienttable. The value should be copied from thePatient.UUIDfield in thedjango-backend - Set
OpalPatientfield in thePatienttable to1 - Create a record in the
MediVisitAppointmentListtable. For example:
'1','1','2023-05-31 18:09:00','2023-05-31','18:09:00','0','1','Aria','1','Open','Active','2023-05-30 00:00:00','1',NULL,NULL
⚠️ Note: For theScheduledDateTime,ScheduledDate,ScheduledTimefields, the date should be the same as the date when theClinical Viewer/Virtual Waiting Roomtest is performed, and the time should be set to the later/future time of the day (e.g., an appointment cannot be in the past). For theStatusandMediVisitStatusfields it should be set toOpenandActiverespectively.
Note: Most of the data specified above can be inserted in the orms database when setting up your database container in db-docker, just by following the README and executing the test data insertion commands for orms:
docker compose run --rm alembic python -m db_management.run_sql_scripts orms db_management/ormsdb/data/initial/docker compose run --rm alembic python -m db_management.run_sql_scripts orms db_management/ormsdb/data/test/However you will still have to edit the ScheduledDateTime, ScheduledDate, ScheduledTime fields to match the current day of testing.
For the Virtual Waiting Room page, make sure that the provided Firebase settings are correct (e.g., in the browser's console, there are no Firebase errors when you go to the Default Profile - Virtual Waiting Room page).
To see the appointment on the Clinical Viewer page:
- Click on
Show Menu - Disable the
Questionnaire Filter - Disable the
Additional Filters - Click
Submit
To see the appointment on the Virtual Waiting Room page:
- On the
Virtual Waiting Room Menu, chooseDefault Profile - Include to the filter the scheduled appointments by clicking on the
Scheduledbutton - Click on the
USER SELECTED RESOURCE(S), and in the modal dialog check theTest Codeand clickOK
⚠️ Note:Virtual Waiting Roomrequires./tmp/1.vwr.jsonfile that is created and updated bycron, otherwise the page will not work. For testing purposes, in case thecrondoes not work, log in to theormscontainer and generate the file by running:php php/cron/generateVwrAppointments.php.
For testing the weight PDFs locally:
-
In the
.env, setSEND_WEIGHTS=1andVWR_CRON_ENABLED=1 -
Copy and rename
config/crunz.yml.templatetoconfig/crunz.yml. Then edit the required fields -
In the
ormsdatabase, update existing record in theHospitaltable by settingHospitalCodefield toRVH -
In the
php/class/External/OIE/Export.phpfile, add the call to pdf generation function before the line that makes OIE call. Note: the old pdf generator function is deprecated and has been removed. Please create a new one before testing. -
Comment the following line in the
php/class/Document/Pdf.phpfile:
if(file_exists("$fullFilePath.pdf")) unlink("$fullFilePath.pdf");- Login to the ORMS and find session cookies
- Run the following curl command (NOTE! you need to use your cookie values that found in the previous step)
curl 'http://127.0.0.1:8086/php/api/private/v1/patient/measurement/insertMeasurement' -X 'POST' -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/ avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' -H 'Cookie: adminer_key=your-adminer_key; adminer_settings=; PHPSESSID=your-PHPSESSID; sessionid=your-sessionid; adminer_permanent=; adminer_sid=your-adminer_sid; specialityGroupId=1; specialityGroupName=Test%20Group; clinicHubId=1; clinicHubName=Test%20Hub; hospitalCode=RVH; csrftoken=your-csrftoken' -H 'Referer: http://127.0.0.1:8086/' -d "patientId=1&height=180&weight=80&bsa=50&sourceId=1&sourceSystem=BBB"- Check
tmpfolder, it should contain generated weights PDF file.
To enable git pre-commit hooks, run the following command:
sh .githooks/activateHooks.sh
⚠️ Note: If you are using a git GUI tool (such asSourcetree) the path might not be set up correctly and pre-commit might not be able to findphp-cs-fixer,phpstan, andpsalm. Currently, the solution is unknown and needs to be investigated.
This project contains recommendations for vscode extensions (see .vscode/extensions.json). You should get a popup about this when you open the project. These extensions are also highlighted in the extensions list.
The following extensions are required or strongly recommended:
- PHP Intelephense
- phpcs
- PHP Debug
- EditorConfig for VSCode
- YAML
- Docker
- GitLens
- ShellCheck
- markdownlint
- phpstan
- Psalm VScode Plugin
- PHP Mess Detector
- hadolint
- Set environment variables (e.g.,
.envfile) - Provide
FIREBASE_CONFIG_PATHandFIREBASE_BRANCH. The firebase configuration file needs to be present inFIREBASE_CONFIG_PATH. In the firebase configuration file,apiKey,authDomain,databaseURLandprojectIdmust be defined. - Provide
crunz.ymlconfiguration settings for the cron
TBD
TBD
There are several scripts that are run periodically in production.
These scripts are located in the directory php/cron/.
To test functionality that require these scripts, execute them manually as follows:
docker compose exec app php php/cron/<nameOfScript>.phpThis specification is inspired by Angular commit message format.
We have very precise rules over how our Git commit messages must be formatted. It is based on the Conventional Commits specification which has the following advantages (non-exhaustive list):
- communicates the nature of changes to others
- allows a tool to automatically determine a version bump
- allows a tool to automatically generate the CHANGELOG
Each commit message consists of a header, a body, and a footer.
<type>(<scope>): <short summary>
│ │ │
│ │ └─⫸ Summary in present tense. Not capitalized. No period at the end.
│ │
│ └─⫸ Commit Scope: deps|i18n
│
└─⫸ Commit Type: build|chore|ci|docs|feat|fix|perf|refactor|style|test
The <type> and <summary> fields are mandatory, the (<scope>) field is optional.
Breaking Changes must append a ! after the type/scope.
Use the summary field to provide a succinct description of the change:
- use the imperative, present tense: "change" not "changed" nor "changes"
- don't capitalize the first letter
- no dot (.) at the end
Must be one of the following:
- build: Changes that affect the build system or external dependencies (i.e., pip, Docker)
- chore: Other changes that don't modify source or test files (e.g., a grunt task)
- ci: Changes to our CI configuration files and scripts (i.e., GitLab CI)
- docs: Documentation only changes
- feat: A new feature
- fix: A bug fix
- perf: A code change that improves performance
- refactor: A code change that neither fixes a bug nor adds a feature
- style: Changes that do not affect the meaning of the code (whitespace, formatting etc.)
- test: Adding missing tests or correcting existing tests
The (optional) scope provides additional contextual information.
The following is the list of supported scopes:
- deps: Changes to the dependencies
- i18n: Changes to the translations (i18n)
In addition to appending a ! after the type/scope in the commit message header, a breaking change must also be described in more detail in the commit message body prefixed with BREAKING CHANGE: (see specification).
- put ssl certs in certs/ as server.crt and server.key
- ensure that the scripts in the
php/cron/directory are executed periodically via a cronjob or similarendOfDayCheckout.php: once per day at 23:30generateAppointmentReminders.php: once per day at 18:00 (or whenever you want appointment reminders to be sent the day before)generateVwrAppointments.php: every 3 secondsprocessIncomingSmsMessages.php: every 5 seconds
- Test the mailing setup in the DEV/QA servers, make sure the mailing service works properly
- Add CI/CD setup (
gitlab-ci.yml) - git hooks currently do not work since everything is done in the container and a multi-stage Dockerfile is used
- When adding a new column type, run the php/tool/verifyProfileColumns script right after
This project includes Opal logos and other branding references.
To apply your own branding, search the repository globally for the key word BRANDING.
This will identify most instances of logos, names, etc. that should be replaced to reflect your brand identity.
Note: most of the branding elements can be configured by editing the VirtualWaitingRoom/js/config.js file.
Only two files must be updated manually: VirtualWaitingRoom/js/vwr/templates/legendDialog.htm and
VirtualWaitingRoom/js/vwr/templates/legendDialogClinicalViewer.htm.