This is the backend for the Simple app to help track hypertensive patients across a population.
Table of Contents
Caveat for Apple Silicon M1 macs
If you are installing on an M1 Mac, you should do all the below in Rosetta (ie
arch returns i386 in a terminal). See here for how to create a Rosetta specific Terminal.
We have some rubygems that don't work under the native ARM architecture, so a fully ARM native setup does not work yet. For details you can follow this issue.
We have a
bin/setup script that does most of the work of getting things setup, but you need a few things in place first.
If you are on a Mac, install homebrew and then install rbenv, redis, and yarn:
brew install rbenv ruby-build redis yarn
You also need Postgres 10 - Postgres.app is a nice small GUI to manage PostgreSQL on a mac, though it isn't required. You can install it via brew:
brew cask install postgres
Then open Postgres.app and ensure you have a PostgreSQL 10 server initialized.
To set up the Simple server for local development, clone the git repository and run the setup script included:
$ git clone firstname.lastname@example.org:simpledotorg/simple-server.git $ cd simple-server $ bin/setup
If you encounter issues with this script, please open a new issue with details. Please include the entire log from bin/setup, as well as your computer / OS details.
For quick development and testing, the server can be run locally using Docker Compose and the command:
docker compose up
The Dockerfile and docker-compose.yml files replicate the steps detailed below for manual installation, including the running of ngrok for local android development.
Once the Docker Compose server is running, the logs should provide the ngrok URL. For example:
SIMPLE_SERVER_HOST=91a705dde8c1.ngrok.io. This is the value that should be used when setting up the Android app as described in the section below.
To remove the server and clear the volumes of database data, run the command:
docker compose down --volumes
If the included
bin/setup script fails for some reason, you can also manually
set up the application step by step. You can do so as follows.
gem install bundler -v 1.17.3 bundle _1.17.3_ install rake yarn:install rails db:setup
We cleanup old migration files every once in a while and so running
db:migrate would not work for the initial setup.
While setting up a fresh DB you will need to load the schema first with
db:setup already takes care of this.
Developing with the Android app
brew install --cask ngrok rails server ngrok http 3000
The output of the ngrok command is HTTP and HTTPS URLs that can be used to access your local server. The HTTP URL cannot be used since HTTP traffic will not be supported by the emulator. Configure the following places with the HTTPS URL.
gradle.properties file in the
simple-android repository, set:
manifestEndpoint=<HTTPS URL>/api/ fallbackApiEndpoint=<HTTPS URL>/api/
.env.development.local (you can create this file if it doesn't exist),
SIMPLE_SERVER_HOST=<URL> # i.e. without https:// SIMPLE_SERVER_HOST_PROTOCOL=https
Alternatively, you can make the change on the server side. In the server repo, open
json.endpoint "<HTTPS URL>/api/"
We use sidekiq to run async tasks. To run, first make sure that redis (>4) is installed:
brew install redis # after installing ensure your redis version is >4 redis-server -v
We use Mailcatcher for testing email in development. Please use the following to set it up on your machine.
Note: Please don't add Mailcatcher to the
Gemfile, as it causes conflicts.
gem install mailcatcher mailcatcher
Now you should be able to see test emails at http://localhost:1080
Testing Web Views
When testing web views like the progress tab or help screens, you will need to authenticate yourself with specific request headers. You can run the following command to get a set of request headers for a user that you can attach to your requests.
$ bundle exec rails get_user_credentials
Attach the following request headers to your requests: Authorization: Bearer 9b54814d4b422ee37dad46e7ebee673c59eed088c264e479880cbe7fb5ac1ce7 X-User-ID: 452b96c2-e0cf-49e7-ab73-c328acd3f1e5 X-Facility-ID: dcda7d9d-48f9-47d2-b1cc-93d90c94386e
Messages sent through Twilio are currently fixed to specific countries. To override this setting, go to the heroku console and add/update the
DEFAULT_COUNTRY config variable on your review app to your desired country. The supported country codes are listed here.
# for US/Canada DEFAULT_COUNTRY = US # for UK DEFAULT_COUNTRY = UK
Updating this config will automatically restart the review app and should allow one to receive messages in their appropriate ISD codes.
The app uses a base development configuration using
.env.development. To add or override any configurations during
local development, create a
.env.development.local file and add your necessary configurations there. If a
configuration change is applicable to all dev environments, ensure that it is added to
.env.development and checked
into the codebase.
Running the application locally
Foreman can be used to run the application locally. First, install foreman.
$ gem install foreman
Then, run the following command to start the Rails and Sidekiq together.
$ foreman start -f Procfile.dev
Note: Foreman will also execute the
whenever gem in trial mode. This will validate that the
configuration is valid, but will not actually schedule any cron jobs.
Alternatively, you can start these services locally without foreman by using the following commands individually.
bundle exec rails serveror
bundle exec puma
bundle exec sidekiq
Running the tests
RAILS_ENV=test bundle exec rspec
To check all the offenses throughout the codebase:
$ bin/rails standard
To automatically fix all offenses,
$ bundle exec standardrb --fix
Note: Some files have been temporarily ignored under a
.standard_todo.yml. As we fix these files, remove them from the
yml file so that they can be picked up by
standard again for future offenses. Refer to usage on how to generate todo files.
Note: Some files are permanently ignored under
.standard.yml and do not require linting.
Generating seed data
To generate seed (fake patients) data, execute the following command from the project root
$ bin/rails db:seed_patients
To purge the generated patient data, run
$ bin/rails db:purge_users_data
You can also purge and re-seed by running:
$ bin/rails db:purge_and_reseed
Creating an admin user
Run the following command from the project root to create a new dashboard admin:
$ bin/rails 'create_admin_user[<name>,<email>,<password>]'
View Sandbox data in your local environment
- Follow the steps in the "How to add an SSH key..." section here to add your SSH key to the deployment repo
- Ask someone from the Simple team to add you as an admin to Sandbox
- Create a password for your Sandbox account and use that to log into the Sandbox dashboard on https://api-sandbox.simple.org
ssh email@example.com verify that your SSH access from step 1 was completed successfully.
bundle exec cap sandbox db:pullto sync Sandbox data with your local machine.
- Use your Sandbox email and password to log into your local environment (http://localhost:3000).
API Documentation can be accessed at
/api-docs on local server and hosted at https://api.simple.org/api-docs
To regenerate the Swagger API documentation, run the following command.
$ bundle exec rake docs
Architecture decisions are captured in ADR format and are available in
Guides, instructions and long-form maintenance documentation can go in
ERD (Entity-Relationship Diagram)
These are not actively committed into the repository. But can be generated by running
bundle exec erd
Simple Server is continuously deployed from master to all environments via Semaphore Workflows as long as the build passes. We use a mixture of tools under the hood for deployments:
- Ansible: Server management and configuration is done using Ansible. See the deployment repository for more information.
- Capistrano: Application code is deployed to servers for a specific country and environment using Capistrano.
- SemaphoreCI: Continuous deployment - all merges to master are auto-deployed to all environments.
If you need to make a manual production release, run the release script from master:
This will create a git release tag and automatically trigger a deployment to all environments through Semaphore. You can monitor the deployment progress in Semaphore via the tagged release's workflow. Please make sure to copy / paste the changelog from
bin/release so you can post it in the #releases channel.
Deployment to a specific environment
- We use Capistrano multi-config to do multi-country deploys.
capcommands are namespaced with the country name. For eg:
bundle exec india:sandbox deploy.
- The available country names are listed under
config/deploy. The subsequent envs, under the country directory, like
Simple Server can be deployed to a specific environment of a specific country with the following command.
bundle exec cap <country_name>:<enviroment> deploy # eg: bundle exec cap india:staging deploy # or, bundle exec cap bangladesh:production deploy
Rake tasks can be run on the deployed server using Capistrano as well. For example,
bundle exec cap india:staging deploy:rake task=db:seed
Deployment to a new environment
When setting up a new environment to deploy Simple Server to, follow these steps.
1. Create a config file
Create a new file in
config/deploy/<env_name>.rb for the new environment. It can be placed inside a subdirectory if
desired. Populate the new config file with relevant IP address info. Use an existing file for reference. For example,
the configuration for a deployment with two EC2 instances may look like:
server "ec2-12-111-34-45.ap-south-1.compute.amazonaws.com", user: "deploy", roles: %w[web app db cron whitelist_phone_numbers seed_data] server "ec2-12-222-67-89.ap-south-1.compute.amazonaws.com", user: "deploy", roles: %w[web sidekiq]
The first server runs the web application and cron tasks, the second server runs Sidekiq to process background jobs.
2. Install Sidekiq
A one-time installation of Sidekiq is required in new environments. Run the following command:
bundle exec cap <environment> sidekiq:install
You can now run a regular Capistrano deployment:
bundle exec cap <environment> deploy
This may take a long time for the first deployment, since several dependencies (like Ruby) need to be installed. Subsequent deployments will be much faster.
The infrastructure setup including the ansible and terraform scripts are documented in the deployment repository.
If you're working on a project that will affect any of the indicators listed in this document, please contact the product / design team.