Skip to content

Latest commit

 

History

History
282 lines (214 loc) · 11.4 KB

CONTRIBUTING.md

File metadata and controls

282 lines (214 loc) · 11.4 KB

This doc is a WIP and will be expanded shortly.

In the meantime, please consider looking at the extensive docs in the Fasten Docs Repository

Tech Stack

Fasten is made up of a handful of different components. Here's a summary of the technologies & languages used in Fasten:

Frontend

  • NodeJS v18.9.0
  • Yarn 1.22.19
  • Angular v14.1.3

Backend

  • Go v1.18.3

Misc

  • Docker v20.10.17

Setup

If you're on a Mac, you can run the following commands to install the necessary software to get setup:

brew install node
npm install -g @angular/cli@14.1.3
npm install -g yarn

brew install go

brew install docker

# Frontend tests run with ChromeHeadless browser.
brew install --cask google-chrome

# Go specific tools
go install github.com/gzuidhof/tygo@latest

Running Tests

Before making changes to Fasten, you'll want to run the test suites to ensure that your environment is setup correctly:

make test

# if you only want to run the frontend tests (Angular), you can run:
make test-frontend

# alternatively, if you only care about backend (Go) tests, you can run:
make test-backend

Note: Running backend tests may take awhile to complete the first time you run

Start Development Environment

To run Fasten from source, you'll need to create 2 separate processes:

  • Angular Frontend
  • Go Backend

First we'll create a development config file (config.dev.yaml)

version: 1
web:
  listen:
    port: 9090
    host: 0.0.0.0
    basepath: ''
  src:
    frontend:
      path: ./dist
database:
  location: 'fasten.db'
cache:
  location: ''
log:
  file: '' #absolute or relative paths allowed, eg. web.log
  level: INFO

Next we'll start the processes described above:

# In terminal #1, run the following
make build-frontend-[sandbox|prod]
# eg. make build-frontend-sandbox

# In terminal #2, run the following
make serve-backend

Note: Fasten can run in 2 modes: sandbox or production (prod). In sandbox mode, it can only communicate with test servers (full of synthetic health data).

Now you can open a browser to http://localhost:9090 to see the Fasten UI.

Important URL's

The following URL's and credentials may be helpful as you're developing

Credentials

  • WebUI:
    • username: testuser
    • password: testuser

Source Code Folder Structure

The Fasten source code is organized into a handful of important folders, which we'll describe below:

Frontend

├── frontend
│   ├── src
│   │   ├── app
│   │   │   ├── app-routing.module.ts
│   │   │   ├── app.component.html
│   │   │   ├── app.component.scss
│   │   │   ├── app.component.spec.ts
│   │   │   ├── app.component.ts
│   │   │   ├── app.module.ts
│   │   │   ├── components                        # contains shared/partial components reused on multiple pages.
│   │   │   │   ├── components-sidebar
│   │   │   │   ├── footer
│   │   │   │   ├── header
│   │   │   │   ├── list-fallback-resource
│   │   │   │   ├── list-generic-resource         # A component containing a table view for every FHIR resource
│   │   │   │   ├── list-patient
│   │   │   │   ├── resource-list                 # Thin shim which populates template depending on FHIR resource type
│   │   │   │   ├── toast                         # Toast/notification component
│   │   │   │   └── utilities-sidebar
│   │   │   ├── models                            # contains classes for communicating with API's and transfering data between pages. 
│   │   │   ├── pages
│   │   │   │   ├── auth-signin                   # Login/Signin page
│   │   │   │   ├── auth-signup                   # Signup page
│   │   │   │   ├── dashboard                     # Dashboard, visible after logging in
│   │   │   │   ├── medical-sources               # Medical Provider connection page
│   │   │   │   ├── patient
│   │   │   │   ├── resource-detail               # Page displaying detailed information about FHIR resource
│   │   │   │   └── source-detail                 # 2 column page displaying FHIR counts, and table listing FHIR resources for selected type
│   │   │   ├── services
│   │   │   │   ├── auth-interceptor.service.ts   # service that looks for 401/403 API responses and triggers Logout
│   │   │   │   ├── is-authenticated-auth-guard.ts    # service that checks if user is logged in
│   │   │   │   ├── fasten-api.service.ts         # api service, used to commnunicate with Go backend (WILL BE REMOVED)
│   │   │   │   ├── fasten-db.service.ts          # db service, used to communicate with CouchDB database
│   │   │   │   ├── lighthouse.service.ts         # api service, used to communicate with auth-gateway (Lighthouse)
│   │   │   │   └── toast.service.ts              # notifications service, used to send notifications
│   │   │   └── workers
│   │   │       ├── queue.service.spec.ts
│   │   │       ├── queue.service.ts              # queue service, used to coordinate background work
│   │   │       └── source-sync.worker.ts         # background job (web-worker) that syncs all FHIR resources from healthcare provider
│   │   ├── lib                                   # root directory for libraries
│   │   │   ├── README.md
│   │   │   ├── conduit                           # Conduit Library - HealthCare provider communication layer (FHIR protocol)
│   │   │   │   ├── fhir                          # contains healthcare provider specific FHIR clients
│   │   │   ├── database                          # Database Library - PouchDB/CouchDB client, compatible with web-worker and browser env
│   │   │   │   ├── plugins
│   │   │   │   └── pouchdb_repository.ts          
│   │   │   ├── models
│   │   │   │   ├── database                      # Classes used to store data in CouchDB
│   │   │   │   ├── fasten                        
│   │   │   │   └── lighthouse                    # Classes used to communicate with Lighthouse API
│   │   │   └── utils
│   │   ├── styles.scss                           # Main sylesheet

Backend

The backend is incredibly simple (by design). The hope is to remove it completely if possible, allowing Fasten to be served by a CDN or minimal Nginx deployment.

├── backend
│   ├── cmd
│   └── pkg
│       ├── config
│       ├── database                  # contains CouchDB client, allowing creation of new Users (and associated databases)
│       ├── errors
│       ├── models
│       └── web
│           ├── handler               # contains code for API endpoints
│           │   ├── auth.go           # authentication endpoints (create new user)
│           │   ├── cors_proxy.go     # CORS proxy/relay for communicating with healthcare providers who do not support CORS
│           │   ├── couchdb_proxy.go  # reverse proxy for CouchDB api, allowing for database API to be exposed (with limitations)
│           │   └── metadata.go       # API endpoint returning metadata for healthcare providers

Distribution/Docker

├── docker-compose.yml                  # docker-compose file which can be used to compile and run "all-in-one" image
├── Dockerfile                          # dockerfile for "all-in-one" image, containing frontend, backend & database
├── docker
│   ├── README.md 
│   ├── couchdb                               
│   │   ├── Dockerfile                  # dockerfile for "couchdb" only image, used for development
│   │   └── local.ini
│   └── rootfs                          # filesystem configs, used in Dockerfiles to setup s6-overlay service manager
│       └── etc
│           ├── cont-init.d
│           │   ├── 01-timezone
│           │   └── 50-couchdb-init
│           └── services.d
│               ├── couchdb
│               └── fasten

FAQ

How do I run individual frontend tests?

From the frontend directory, you can run ng test with the --include argument.

ng test --include='**/badge.component.spec.ts'
ng test --include='lib/**/*.spec.ts'

How do I change the default encryption key and admin credentials

  • FASTEN_ISSUER_JWT_KEY

Generate JWT for local use

curl -X POST http://localhost:9090/api/auth/signup -H 'Content-Type: application/json' -d '{"username":"user1","password":"user1"}'

curl -X POST http://localhost:9090/api/auth/signin -H 'Content-Type: application/json' -d '{"username":"user1","password":"user1"}'


curl -H "Authorization: Bearer ${JWT_TOKEN_HERE}" http://localhost:5984/_session

How do I work with Storybook?

Storybook allows development and testing of frontend components in isolation. When running the Storybook server, each defined story can be viewed and interacted with on it's own allowing for defining and testing of various states and conditions.

In order to run the Storybook server, run the following command and open the url provided:

make serve-storybook

If you only want to verify that all stories build properly (a check that is run on commits and PRs), you can run the following command:

make build-storybook

Access Encrypted SQLite Database with IntelliJ

  • Download the latest sqlite-jdbc-crypt jar from https://github.com/Willena/sqlite-jdbc-crypt/releases
  • Open IntelliJ -> Data Source Properties -> Driver Tab
  • Find & Select Sqlite -> Right Click -> Duplicate
  • Rename to Sqlite (Encrypted)
  • Find Driver Files -> Select sqlite-jdbc-crypt jar that you downloaded previously
  • Remove Xerial Sqlite JDBC jar
  • Click Apply -> Click OK
  • Create New Data Source -> Select Sqlite (Encrypted) -> Change Connection Type to Url only
  • Specify the following connection url: jdbc:sqlite:fasten.db?cipher=sqlcipher&legacy=3&hmac_use=0&kdf_iter=4000&legacy_page_size=1024&key=123456789012345678901234567890
  • Replace key with the encryption key specified in your config file (database.encryption_key)
  • Click Test Connection -> Should be successful
  • Click Apply -> Click OK

Flush SQLite Write-Ahead-Log (WAL) to Database

PRAGMA wal_checkpoint(TRUNCATE);

See: https://sqlite.org/forum/info/fefd56014e2135589ea57825b0e2aa3e2df5daf53b5e41aa6a9d8f0c29d0b8e5 TODO: check if https://www.sqlite.org/pragma.html#pragma_wal_checkpoint can be used to do this automatically.