Skip to content

SimpleReport is a fast, free, and easy way for COVID-19 testing facilities to report results to public health departments.

License

Notifications You must be signed in to change notification settings

CDCgov/prime-simplereport

Repository files navigation

Simple Report

https://simplereport.gov/

Latest release Quality Gate Status Sonar coverage

Table of Contents

Setup

  1. Install Docker and docker-compose
    • You can install docker hub directly: https://hub.docker.com/. This is the preferred solution and should come with docker-compose
    • Alternatively, you can install docker and run it as a daemon: brew install docker docker-compose.

Backend

There are two major pieces:

  • a Java Spring Boot application
  • a postgresql database

To run the service, you need a JDK and some way of running postgresql (most people choose to use Docker, but you can also just run it as a service on your development box.) To test the full authentication/authorization/user-management integration, you will also need Okta credentials, but that is not necessary most of the time.

Backend-Setup

If Java isn't installed on a Mac you can get it from brew:

brew tap adoptopenjdk/openjdk
brew cask install adoptopenjdk11
brew install gradle

Another option (also compatible with Linux) is to install with jabba, the Java version manager:

curl -sL https://github.com/shyiko/jabba/raw/master/install.sh | bash && . ~/.jabba/jabba.sh
jabba install [email protected]
jabba use [email protected]

Running with docker:

  1. cd backend
  2. Run docker-compose up --build
  3. view site at http://localhost:8080

Running spring app locally and db in docker

  1. cd backend
  2. Run docker-compose up -d db
  3. Run ./gradlew bootRun --args='--spring.profiles.active=dev'
  4. view site at http://localhost:8080

Running spring app locally and db in docker on port 5433

  1. cd backend
  2. Run docker-compose --env-file .env.development up db
  3. Run SR_DB_PORT=5433 ./gradlew bootRun --args='--spring.profiles.active=dev'
  4. view site at http://localhost:8080

Running the app with Make or start.sh

For development, it may be more convenient to start the front and backends simultaneously. This can be done by running the following command in the root directory of the project:

make # "make start" if you're nasty

This will start up both servers in "watch" mode, so that changes to the source code result in an immediate rebuild.

If you'd like to use a local installation of PostgreSQL, run the following to create a local database:

# Run this to create or reset the local db. Assumes your $USER has superuser privileges.
# If not, use POSTGRES_USER=postgres
POSTGRES_USER=$USER LIB_DIR="$(pwd)/backend/db-setup" POSTGRES_DB=postgres ./backend/db-setup/create-db.sh

Then run this to start the app:

./start.sh

This will also start up both servers in "watch" mode. When using start.sh, any environment variables put in .env in the root directory will be available to the app. Press CTRL-C to exit and cleanup the servers cleanly.

Running locally with Okta

You can run the app against the "Okta Preview" instance by running the backend with the okta-local Spring profile. Be sure to set the OKTA_API_KEY environment variable. You can generate an API token for yourself by logging into the Okta Preview admin panel and going into Security > API > Tokens.

You also need to set the following in frontend/.env.local:

REACT_APP_OKTA_ENABLED=true

Updating user role

By default the local test user is an organization admin role. If you need to change this value to test out other permissions. It can be set in application-local.yaml. If you have not created one run:

bash

touch backend/src/main/resources/application-local.yaml

Organization roles

Organization roles can be set by adding the following to application-local.yaml:

simple-report:
  demo-users:
    default-user:
      authorization:
        granted-roles: ADMIN

current role types are ADMIN, USER, ENTRY_ONLY, ALL_FACILITIES, and NO_ACCESS. You can check backend/src/main/java/gov/cdc/usds/simplereport/config/authorization/OrganizationRole.java for a list of available roles

ADMIN - an organization admin with full access to their organization USER - a site user the has access to everything in their organization but the gear icon ENTRY_ONLY - a site user that only has access to the Conduct Test tab ALL_FACILITIES - a site user that can access all facilities in their organization NO_ACCESS - a member of an organization who has no permissions without possessing other roles

Site roles

You can make the default user a site admin by adding the following to application-local.yaml:

simple-report:
  demo-users:
    site-admin-emails:
      - [email protected]

Site admins can access the /admin paths and site admin APIs

Restart & Clean

When there are DB schema changes the backend may throw an error and fail to start.

Restarting the docker way:

  1. run cd backend
  2. Bring down the service by running docker-compose down
  3. Wipe the db by running docker system prune && docker images prune && docker volume prune
  4. Restart the service docker-compose up --build

Restarting the SQL way:

  1. run db-setup/nuke-db.sh
  2. restart the spring app gradle bootRun --args='--spring.profiles.active=dev'

Rollbacks

The application uses the Liquibase plugin for Gradle to perform certain database management tasks.

To roll the database back to its state at a prior date:

$ ./gradlew liquibaseRollbackToDate -PliquibaseCommandValue=${date}

To roll back a certain number of migrations:

$ ./gradlew liquibaseRollbackCount -PliquibaseCommandValue=${n}

To roll back to a certain tag:

$ ./gradlew liquibaseUpdateToTag -PliquibaseCommandValue=${TAG}

If you are required to roll back a non-local database, you may generate the required SQL to execute elsewhere. Use liquibaseRollbackToDateSQL or liquibaseRollbackCountSQL in the manner described above to write the rollback SQL to stdout.

API Testing

Go to localhost:8080 to see interact with the graphql api. You would need to point the api endpoint to the backend at: http://localhost:8080/graphql This gives you a preview to query/mutate the local database.

Tests

All the tests can be run with gradle test. Make sure that you do not have SPRING_PROFILES_ACTIVE set in your shell environment.

Running a single test with a full stacktrace can be accomplished by supping the path to gradle test. Example

gradle test --tests gov.cdc.usds.simplereport.api.QueueManagementTest.updateItemInQueue --stacktrace

E2E Tests

E2E/Integration tests are available using Nightwatch.js.

Run them with the following commands while the app (both front and backends) is already running:

cd frontend
yarn e2e

Local Settings

to edit Spring boot settings for your local set up you must first create a application-local.yaml (note this file is git ignored):

bash

touch backend/src/main/resources/application-local.yaml

Useful local settings

  • make the default user an admin
simple-report:
  demo-users:
    site-admin-emails:
      - [email protected]
  • make SQL pretty
spring:
  jpa:
    properties:
      hibernate:
        format_sql: true
  • set CORS allowed-origins (this can be useful for testing the Okta integration)
simple-report:
  cors:
    allowed-origins:
      - http://localhost:3000

SchemaSpy

http://schemaspy.org/

cd backend
docker-compose up db
docker-compose up --build schemaspy
# to run on a different port than 8081
SR_SCHEMASPY_PORT=8082 docker-compose up --build schemaspy

visit http://localhost:8081

Twilio

Twilio's Java SDK auto-configures based on two environment variables: TWILIO_ACCOUNT_SID and TWILIO_AUTH_TOKEN. SMS is also disabled by default, and can be enabled in application.yml:

twilio:
  enabled: true
  from-number: +13214560987

These can also be set by environment variable if desired.

Frontend

The front end is a React app. The app uses Apollo to manage the graphql API. For styling the app leverages the U.S. Web Design System (USWDS)

Frontend-Setup

  1. (optional) Install react developer tools extensions
  2. Install yarn
  3. cd frontend && yarn install && docker-compose up
  4. view site at http://localhost:3000
    • Note: frontend need the backend to be running to work

Linters

This project uses eslint, prettier, and stylelint as frontend linters, and spotless and google-java-format for the backend. GitHub Actions is configured to run these linters on every pull request, so you must resolve all mismatches/errors prior to merging. There are a few ways to manage this:

  1. Run yarn lint:write in the frontend/ dir, and ./gradlew spotlessApply in the backend/ dir, before every commit
  2. Enable the optional pre-commit hook by running yarn install in the root dir
  3. Add extensions to your code editor that runs the linters for you on save, e.g. prettier-vscode, vscode-eslint, vscode-google-java-format

Storybook and Chromatic

Storybook is an open source tool for developing UI components in isolation for React. It makes building UIs organized and efficient.

To view the Storybook locally:

Chromatic is a web-based tool for Storybook that helps speed UI component development. It provides regression testing and review. It also allows for publication of the Storybook.

Changes to the Storybook are sent to Chromatic when changes to the frontend source are push to a any branch. The changes are automatically accepted on merge to main.

View the SimpleReport Storybook

Cloud Environments

Name Frontend API Deployment Intended Use
prod /app/static/commit.txt /api/actuator/info Dispatched on success of stg deploy Used by end users
demo /app/static/commit.txt /api/actuator/info Worflow on success of stg deploy Used internally to demo the application to potential end users
training /app/static/commit.txt /api/actuator/info Dispatched on success of stg deploy Used externally by potential users to get a better uderstanding of the product
stg /app/static/commit.txt /api/actuator/info Push to main To validate the application work in the cloud and works with prod like data
dev /app/static/commit.txt /api/actuator/info Action To validate PRs before merging to main
test /app/static/commit.txt /api/actuator/info Action To validate PRs before merging to main
pentest /app/static/commit.txt /api/actuator/info Action To validate PRs before merging to main

Deploy

SimpleReport uses a continuous deployment deployment (CD) process deployment-1

Revert to a Previous Release

Note: A bad version can be rolled backed independent of the FE via the rollback API actions

  1. checkout main
  2. create a new branch (example: tim-best/revert-feature-A)
  3. Revert to the desired commit git revert --no-commit 9999999..HEAD && git commit where 9999999 is the commit you want to revert to
    • This will revert everything from the HEAD back to the commit hash, meaning it will recreate that commit state in the working tree as if every commit after 9999999 had been walked back
  4. Create a PR with your branch, wait for tests to pass, get approval and merge
  5. Follow instructions in deploy-with-release

Deploy With Action

Navigate to the Github Actions Tab Screen Shot 2021-02-24 at 11 07 13 AM

  1. Select the environment you want to deploy to from the workflows list on the left. In this case we are selecting the test environment
  2. Click the "Run workflow" button
  3. Select the branch you want to deploy. In this case we are deploying the latest commit on main
  4. Click the green "Run workflow" button.
  5. After the workflow is completed you can verify the changes are live by Checking the deployed commit hash. This is done my going to /app/static/commit.txt and /api/actuator/info

Deployment Issues

Maintenance Mode

Users can be notified of deployment issues by placing SimpleReport in maintenance mode. When maintenance mode is enabled, a banner will appear at the top of each page stating that SimpleReport is currently experiencing an outage, along with a configurable supplemental message (e.g. a reason why).

To do so manually:

  1. Create a MAINTENANCE MESSAGE in JSON format with an active and a message key. Example: {"active": true, "message": "SimpleReport is currently undergoing maintenance"}. Note that the active value must be a boolean, not a string.
  2. cd frontend && MAINTENANCE_MESSAGE=(JSON message here) MAINTENANCE_ENV=(desired env) yarn run maintenance:start

Example:

MAINTENANCE_MESSAGE='{"active": true, "message": "SimpleReport is currently experiencing service degradation"}' MAINTENANCE_ENV=dev yarn run maintenance:start

Possible values for MAINTENANCE_ENV: dev, test, pentest, training, demo, stg, prod

An easier way is to run the Maintenance Mode Action, which will automatically enable/disable maintenance mode for all environments with your desired message.