Skip to content
Switch branches/tags
Go to file

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

Iris Api Server

This is the repo for the Iris Msg backend source code. It is an Express server written in TypeScript and deployed through Docker.

It connects to a Mongo database using Mongoose, is unit tested using jest, has a commander CLI and uses ocelot-docs to generate api documentation.

What is Iris Msg?

Table of contents



To develop on this repo you will need to have Docker and node.js installed on your dev machine and have an understanding of them. This guide assumes you have the repo checked out and are on macOS, but equivalent commands are available.

You'll only need to follow this setup once for your dev machine.

# Install npm dependencies
npm install

# Make your secrets file and fill in the values
cp .env.example .env

You will also need to get a copy of assetlinks.json and google-account.json and put them in the root of the repo.

Regular use

These are the commands you'll regularly run to develop the API, in no particular order.

# Start up the docker stack
# -> Runs a mongo database
# -> Runs an instance of shrinky (
docker-compose up -d

# Run unit tests
npm run test

# Run the server and reload on changes
# -> Runs TypeScript directly using ts-node
# -> Uses tsconfig-paths to enhance typescript imports with aliases
# -> Watches for changes in src but ignores .spec.ts changes
# -> The entrypoint is src/index.ts
npm run dev

Irregular use

These are commands you might need to run but probably won't, also in no particular order.

# Generate the table of contents for this readme
# -> Uses
npm run build:readme

# Run development without reloading
npm run dev:once

# Lint source code
# -> Uses tslint
# -> We use IDE extensions to visually see tslint errors
npm run lint

# Manually trans-pile the TypeScript to JavaScript
# -> In development we run TypeScript directly through ts-node
# -> In production TypeScript is trans-pilled in the docker build
npm run build

# Manually build the api docs
# -> These are built in the docker build
# -> It reads files from api/ and outputs into docs
npm run build:docs

# Run the trans-pilled source code
# -> This is the entrypoint for the docker image
# -> Registers tsconfig-paths and loads .env config
npm run start

Code Structure

These are the key directories in the project, some are git-ignored.

Folder Contents
__mocks__ Jest mocks for npm modules
api Ocelot api configuration
coverage Jest coverage export
dist Trans-pilled javascript src
docs Ocelot generate docs
locales Localisation files
logs Development logs
node_modules Node packages installed through npm
seeds Database seeds for testing
src The TypeScript source code
src/i18n The localisation submodule
src/middleware Reusable express middleware
src/public Static assets served through express
src/routes Our routes (see below)
src/schemas Mongoose schemas
src/services Wrappers for external services
src/tasks Long running tasks (like cron jobs)
templates Pug templates for generate pages
tools Node.js utility scripts

Route definitions

The routes of this API are TypeScript functions that take a context object, ctx.

They get converted to express routes in router.ts's makeRoute function. See src/types.ts's RouteContext to see what values are passed. This structuring is what inspired @robb_j/chowchow.

This structuring allows multiple strongly-typed values to be passed to any route, trying to make typing as seamless as possible. It works well with object destructuring so you can destructure only the values you need.

For example, a localised hello-world endpoint is as simple as:

import { RouteContext } from '@/src/types'

export default async ({ api, i18n }: RouteContext) => {


This repo uses unit tests to ensure that everything is working correctly, guide development, avoid bad code and reduce defects. We use Jest to run these unit tests.

Tests are any file in src/ that end with .spec.ts, by convention they are inline with the source code, in a parallel folder called __tests__.

There are also __mocks__ which stub out npm packages so real code isn't called during tests. This means you can test sending a Twilio SMS without actually sending an SMS.

# Run the tests
npm test -s

# Watch tests and re-run on code changes
npm run test:watch -s

# Generate code coverage
npm run test:coverage -s

Code formatting

Coming soon


Building the image

This repo uses a GitLab CI to build a Docker image when you push a git tag. This is designed to be used with the npm version command so all docker images are semantically versioned. The :latest docker tag is not used.

This job runs using the .gitlab-ci.yml file which runs a docker build using the Dockerfile and only runs when you push a tag.

It pushes these docker images to the GitLab registry of the repo.

# Deploy a new version of the CLI
npm version # major | minor | patch
git push --tags

A slight nuance is that npm precedes version with a v, this is disabled in our .npmrc

Environment Variables

Name Description
NODE_ENV What environment the system is running in.
MONGO_URI Where the mongo database is and how to connect to it
JWT_SECRET The secret for json web tokens
API_URL The public url of this api, e.g.
WEB_URL The public url of the web, e.g. (unused)
TWILIO_AUTH_TOKEN Your twilio access token, more info
TWILIO_SID Your twilio sid
TWILIO_NUMBER Your twilio number, the number service sms will be sent from
TWILIO_FALLBACK If the sms donation algorithm should fall back to using twilio
FIREBASE_DB Where your firebase database is
PLAY_STORE_URL The link to download the Iris Msg app (used on deep link fallback)
LATEST_APP_VERSION The name of the latest version of the app
LATEST_APP_URL The url of the latest version of the app

Useful links:

Mounted Files

File Description
/app/assetlinks.json Your android asset links file, more info
/app/google-account.json Your Firebase account file, more info

Using a URL Shortener

You can optionally use skrinky-link to shorten url which are sent in messages.

To enable this feature set the following environment variables:

  • SHRINK_URL - The public URL of the instance, e.g. http://shrinky:3000
    • If using with docker-compose, you can use the container name has the hostname, e.g. shrinky
  • SHRINK_KEY - Your key for shrinky-link, used to authenticate requests

Future work

  • Deprecate PLAY_STORE_URL in favour of LATEST_APP_URL
  • Reference the install guide in downloadApp.pug

The code on is a mirror of


A Node.js server providing authentication, management and messaging




No packages published