fasten-onprem/CONTRIBUTING.md

263 lines
11 KiB
Markdown
Raw Normal View History

2022-10-13 09:48:09 -06:00
> 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](https://github.com/fastenhealth/docs/tree/main/technical)
2022-10-15 14:33:38 -06:00
# Tech Stack
2022-08-22 18:51:46 -06:00
2022-10-15 14:33:38 -06:00
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:
```bash
brew install node
npm install -g @angular/cli@14.1.3
npm install -g yarn
2022-10-15 14:33:38 -06:00
brew install go
brew install docker
# Go specific tools
go install github.com/gzuidhof/tygo@latest
2022-08-22 18:51:46 -06:00
```
2022-10-15 14:33:38 -06:00
# Running Tests
Before making changes to Fasten, you'll want to run the test suites to ensure that your environment is setup correctly:
```bash
make test
# if you only want to run the frontend tests (Angular), you can run:
make test-frontend
2022-10-15 14:33:38 -06:00
# alternatively, if you only care about backend (Go) tests, you can run:
make test-backend
2022-10-15 14:33:38 -06:00
```
# Start Development Environment
To run Fasten from source, you'll need to create 2 separate processes:
2022-10-15 14:33:38 -06:00
- Angular Frontend
- Go Backend
First we'll create a development config file (`config.dev.yaml`)
```yaml
version: 1
web:
listen:
port: 9090
host: 0.0.0.0
basepath: ''
src:
frontend:
path: ./dist
database:
location: 'fasten.db'
cache:
location: ''
2022-10-15 14:33:38 -06:00
log:
file: '' #absolute or relative paths allowed, eg. web.log
level: INFO
```
Next we'll start the processes described above:
```bash
# In terminal #1, run the following
2023-12-22 17:35:41 -07:00
make build-frontend-[sandbox|prod]
# eg. make build-frontend-sandbox
2022-10-15 14:33:38 -06:00
# In terminal #2, run the following
2023-12-22 17:35:41 -07:00
make serve-backend
2022-10-09 13:30:26 -06:00
```
2022-10-09 13:30:26 -06:00
_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).
2022-10-15 14:33:38 -06:00
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
2022-10-09 13:30:26 -06:00
- http://localhost:9090/web/dashboard - WebUI
2022-10-15 14:33:38 -06:00
### Credentials
2022-10-09 13:30:26 -06:00
- WebUI:
- username: `testuser`
- password: `testuser`
2022-10-15 14:33:38 -06:00
# Source Code Folder Structure
The Fasten source code is organized into a handful of important folders, which we'll describe below:
## Frontend
2022-10-15 14:56:37 -06:00
```
2022-10-15 14:33:38 -06:00
├── frontend
│   ├── src
│   │   ├── app
│   │   │   ├── app-routing.module.ts
│   │   │   ├── app.component.html
│   │   │   ├── app.component.scss
│   │   │   ├── app.component.spec.ts
│   │   │   ├── app.component.ts
│   │   │   ├── app.module.ts
2022-10-15 14:57:28 -06:00
│   │   │   ├── components # contains shared/partial components reused on multiple pages.
2022-10-15 14:33:38 -06:00
│   │   │   │   ├── 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
2022-10-15 14:57:28 -06:00
│   │   │   ├── models # contains classes for communicating with API's and transfering data between pages.
2022-10-15 14:33:38 -06:00
│   │   │   ├── 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
2022-10-15 14:33:38 -06:00
│   │   │   │   ├── 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
2022-10-15 14:58:02 -06:00
│   │   │   ├── 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
2022-10-15 14:33:38 -06:00
│   │   │   ├── README.md
2022-10-15 14:57:28 -06:00
│   │   │   ├── conduit # Conduit Library - HealthCare provider communication layer (FHIR protocol)
2022-10-15 14:51:28 -06:00
│   │   │   │   ├── fhir # contains healthcare provider specific FHIR clients
2022-10-15 14:57:28 -06:00
│   │   │   ├── database # Database Library - PouchDB/CouchDB client, compatible with web-worker and browser env
2022-10-15 14:33:38 -06:00
│   │   │   │   ├── plugins
2022-10-15 14:51:28 -06:00
│   │   │   │   └── pouchdb_repository.ts
2022-10-15 14:33:38 -06:00
│   │   │   ├── models
2022-10-15 14:51:28 -06:00
│   │   │   │   ├── database # Classes used to store data in CouchDB
│   │   │   │   ├── fasten
│   │   │   │   └── lighthouse # Classes used to communicate with Lighthouse API
2022-10-15 14:33:38 -06:00
│   │   │   └── utils
2022-10-15 14:57:28 -06:00
│   │   ├── styles.scss # Main sylesheet
2022-10-15 14:33:38 -06:00
```
## Backend
2022-10-15 14:51:28 -06:00
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.
2022-10-15 14:56:37 -06:00
```tree
2022-10-15 14:51:28 -06:00
├── backend
│   ├── cmd
│   └── pkg
│   ├── config
2022-10-15 14:56:37 -06:00
│   ├── database # contains CouchDB client, allowing creation of new Users (and associated databases)
2022-10-15 14:51:28 -06:00
│   ├── errors
│   ├── models
│   └── web
2022-10-15 14:56:37 -06:00
│   ├── handler # contains code for API endpoints
2022-10-15 14:51:28 -06:00
│   │   ├── 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
```
2022-10-15 14:33:38 -06:00
## Distribution/Docker
2022-10-15 14:56:37 -06:00
```tree
2022-10-15 14:54:13 -06:00
├── 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
2022-10-15 14:51:28 -06:00
├── docker
│   ├── README.md
│   ├── couchdb
│   │   ├── Dockerfile # dockerfile for "couchdb" only image, used for development
│   │   └── local.ini
2022-10-15 14:54:13 -06:00
│   └── rootfs # filesystem configs, used in Dockerfiles to setup s6-overlay service manager
2022-10-15 14:51:28 -06:00
│   └── etc
│   ├── cont-init.d
│   │   ├── 01-timezone
│   │   └── 50-couchdb-init
│   └── services.d
│   ├── couchdb
│   └── fasten
```
2022-10-15 14:33:38 -06:00
2022-10-15 14:51:28 -06:00
# FAQ
2022-10-15 14:51:28 -06:00
### How do I run individual frontend tests?
- ng test --include='**/base_client.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
```bash
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
```
# Run Component Storybook
```bash
ng run fastenhealth:storybook
```
2023-11-07 16:17:00 -07:00
# 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
```sqlite
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.