The SmartSleep project is a sleep study for the Faculty of Health and Medical Sciences. The SmartSleep project is a research project about sleep.
These repositories contain the source code for all components involved in gathering the sleep data submitted by the research participants.
The project is composed of multiple parts:
- Mobile applications
- Backend
- Authentication module
- Activity data service
- Notification service
- Survey service
- Authenticating proxy
- Desktop application for survey configuration
All the backend components are referenced assembled in a services project which includes configurations and links to all the the services and docker-compose files for local development and for staging and production deployment.
The project is composed of mobile frontend applications, a backend which has multiple sub-components, and a backoffice desktop application for survey configuration.
Each individual component is described below.
The iOS application is architected with Views, Controllers, and Services. The Views has view specific code which is needed for layout of components on screen. The controllers composite the data structures and handle user events. The Services handle data gathering and storage, from accelerometer data used in detecting sleep, storing data in local caches, and transmitting activity data to from the backend. The services also make composite night data from the activity data.
The views are created using Interface Builder, with the exception of special view components which could not be described using standard components, which are then found in the Views subfolder.
The controllers and services can be found in Controllers, and Services folders, respectively.
All user secrets (like credentials) are stored securely in the keychain encrypted storage on the device.
All cached data is stored in an embedded SQLite database in the application documents folder on the device.
The backend is composed of multiple sub-components.
- Authentication module
- Activity data service
- Notification service
- Survey service
- Authenticating proxy
The proxy is an nginx webserver which authenticates all incoming requests before allowing access to either the activity microservice or the survey microservice. Authentication is done via authentication subrequests which sends a request to the authentication microservice which in turn evaluates the client and user credentials before allowing or denying access.
All user and activity data is stored in a MongoDB database with separate database users for accssing PII and SPI data. All data is stored with encryption-at-rest.
All survey data is stored in MySQL.
Authentication is done via JWT which are transmitted via bearer authentication headers in a TLS encrypted request to the backend via https. A request to a login endpoint on the authentication microservice with valid client id, client secret, and user credentials, will yield a JWT result which is then carried in all subsequent requests to the backend.
Whenever the user submits activity data, rest data is derived from it and stored alongside it for followup sleep data gathering.
Once the survey participants sleep rythms are submitted, the notification microservice will send background push notifications to mobile devices every morning prompting the device to upload all activity data in the background.
The survey microservice is a Limesurvey fork which is used to create surveys which survey participants are requested to partake in. The surveys responses are keyed by user id which in and of themselves contain no PII.
The backoffice desktop application is a portable electron application used to access the survey microservice. It carries a shared client secret which alongside a username and a password prevents anyone outside the study from accessing participant data.
Xcode is used for building the iOS application. CocoaPods is used for dependency management.
Android Studio was used for building the Android application.
Docker and docker-compose is needed to build and deploy locally. Docker-machine and Docker Stack is used to deploy to the staging server.
Node 8, and OpenJDK 8 is used in development of the individual services. You should have Node 8 and a recent JDK installed locally. nvm is recommended for maintaining multiple versions of node locally.
IntelliJ IDEA has been used for development of microservices implemented in Kotlin and Atom has been used for microservices implemented in Typescript, but any IDE can be used for local development.
GPG is used for managing secrets.
Git submodules are used for maintaining dependencies. To pull all dependencies (if you did not perform a recursive clone) run:
git submodule update --init --recursive
Before starting the stack for the first time, secrets must be decrypted. To decrypt the secrets, run:
gpg --decrypt-files --yes `find . -path '*secrets*' -and -name '*.gpg'`
To build and run the backend services locally, simply clone the services project including all submodules and run:
docker-compose up