/offender-categorisation

A digital service for categorising prisoners

Primary LanguageJavaScript

Offender Categorisation

A digital service for categorising prisoners

CircleCI Docker Repository on Quay Known Vulnerabilities Repo Standards Badge

JS NPM Node.js ExpressJS Jest ESLint

AWS Docker Kubernetes Postgres Redis

Dev Website

https://dev.offender-categorisation.service.justice.gov.uk/

Requirements

You will need the following tools installed:

Tool Version Reason
npm ≥9.5.x Node package manager for resolving/installing project dependencies
node ≥18.17.x NodeJS interpreter
docker ≥18.x Installing/removing/managing containers & images
docker-compose ≥1.25.x Convenience utility for grouped management of containers
jdk 17.x For running the integration tests using groovy 2.5.18

Getting started

Offender-Categorisation is a nodeJS application which by default starts up and listens on URL http://localhost:3000

It has services on which it depends :

Dependency Description Default Override Env Var
prison-api Nomis API providing prisons/offender information http://localhost:8080 ELITE2API_ENDPOINT_URL
hmpps-auth OAuth2 API server for authenticating requests http://localhost:9090/auth NOMIS_AUTH_EXTERNAL_URL
NOMIS_AUTH_URL
risk-profiler Risk Profiler service http://localhost:8082/ RISK_PROFILER_ENDPOINT_URL
allocation-manager Allocation manager http://localhost:8083/ ALLOCATION_MANAGER_ENDPOINT_URL
postgres (form-builder) PostgreSQL database server for offender-categorisation jdbc:postgresql://localhost:5432/form-builder DB_USER
DB_PASS
DB_SERVER
DB_NAME
postgres (risk profiler) PostgreSQL database server for risk-profiler jdbc:postgresql://localhost:5433/<DB_NAME> Uses port forwarding
DB_NAME found in Lens
redis Redis cache for user 'session' data (roles) localhost:6379/tcp
SQS (event) AWS SQS queue for events http://localhost:4566
Name: event
(localstack)
EVENT_QUEUE_URL
SQS (Risk Profiler) AWS SQS queue for risk profiler change events http://localhost:4566
Name: risk_profiler_change
(localstack)
RP_QUEUE_URL
SQS (event dead letter) AWS SQS queue for events dead letter http://localhost:4566
Name: event
(localstack)
EVENT_DL_QUEUE_URL
SQS (Risk Profiler dead letter queue) AWS SQS queue for risk profiler dead letter http://localhost:4566
Name: events_dlq
(localstack)
RP_DL_QUEUE_URL
ingress url http://localhost:3000/ INGRESS_URL
dps url http://localhost:3000/ DPS_URL

Other configuration

Environment variable Default value
GOOGLE_ANALYTICS_ID (blank)
APPROVED_DISPLAY_MONTHS 6
RECAT_MARGIN_MONTHS 2
FEMALE_PRISON_IDS ['AGI', 'DWI', 'DHI', 'ESI', 'EWI', 'BZI', 'FHI', 'LNI', 'SDI', 'STI', 'NHI', 'PFI']

Docker compose files

File Purpose
docker-compose.yml Creates containers for all dependent services and all allows selective start, or override by env vars
docker-compose-test.yml Sets up all containers for running locally

Running the application

The offender-categorisation can be run in two ways.

Simplest way to run locally

  • if you have a high-spec machine
  • if you are unable to connect to remote services

Set up port-forwarding by following the instructions here: https://dsdmoj.atlassian.net/wiki/spaces/SED/pages/3930816517/Port+Forwarding+-+Developer+Instructions

Use docker compose to download and run the four required containers

docker-compose -f docker-compose-test.yml pull

docker-compose -f docker-compose-test.yml up

Either set the environment variable SQS_ENABLED=false or make sure all the SQS queues have started up in the categorisation-localstack container and categorisation-localstack-setup container has exited

Install dependencies using npm install

Run the application using npm run start

Alternative way

Run redis as a local docker container on the default port of 6379 when running the app locally with tls disabled (the default)

docker run -p6379:6379 redis

The other option is to run stunnel and port forward using the cloud platform guidance: https://github.com/ministryofjustice/cloud-platform-terraform-elasticache-cluster If running locally against elasticache with TLS_ENABLED='true' you will also need to provide the following env vars:

REDIS_AUTH_TOKEN=<from the namespace secret>
NODE_TLS_REJECT_UNAUTHORIZED=0

Install dependencies

npm install

Run the application

npm run start

Notes:

Transactions

This app is transactional for Postgres database operations but NOT elite2 calls. So it is vital that router endpoints do all db calls BEFORE elite2 (updating) calls. Otherwise when an error occurs, Nomis could get updated with the corresponding postgres changes being rolled back.

Users

You can log in with users stored in the seeded nomis oauth db e.g. CA_USER, password123456

Dependencies

The app authenticates using nomis Nomis Oauth2 Server and saves to a Postgres database.

The app uses redis (cloud platform elasticache when deployed to our environments) to store the user session.

Env variables

In config.js you can see all the required variables. These are set with defaults that will allow the application to run, but you will need to add a .env file at some point.

Run the node application

npm run start

Run linter

To automate the checking of the source code for programmatic and stylistic errors run lint using:

npm run lint

Running the tests

Unit Tests

To run the jest unit tests:

npm run test

Integration Tests (Groovy)

To run the integration tests you need to install chromedriver :

brew install --cask chromedriver (If there are permission problems, you can show in finder then 'open' it and allow it to run.)

Or for non-macs, download from https://chromedriver.chromium.org/downloads and put chromedriver.exe on your path.

The integration tests uses wiremock stubs to log into the application so the default configuration listed above should be used

The easiest way to run the integration tests on your local machine is to:

  • Start the docker containers by running docker-compose-test.yml

  • Run the application npm run start using the default environment variables

  • Run ./gradlew chromeTest to run with a visible browser or ./gradlew chromeHeadlessTest to run without a visible browser

The tests can be run in debug mode for troubleshooting.

More detailed instructions can be found here: https://dsdmoj.atlassian.net/wiki/spaces/DCAT/pages/3919872182/UI+Code+Local+Setup#Integration-Tests

Example Test .env File

DB_USER=form-builder
DB_PASS=form-builder
DB_SERVER=0.0.0.0
DB_NAME=form-builder
SQS_ENABLED=true
NOMIS_AUTH_URL=http://localhost:9090/auth
NOMIS_AUTH_EXTERNAL_URL=http://localhost:9090/auth
EVENT_QUEUE_ACCESS_KEY_ID=dummy
EVENT_QUEUE_SECRET_ACCESS_KEY=dummy
EVENT_DL_QUEUE_ACCESS_KEY_ID=dummy
EVENT_DL_QUEUE_SECRET_ACCESS_KEY=dummy
RP_QUEUE_ACCESS_KEY_ID=dummy
RP_QUEUE_SECRET_ACCESS_KEY=dummy
RP_DL_QUEUE_ACCESS_KEY_ID=dummy
RP_DL_QUEUE_SECRET_ACCESS_KEY=dummy
RP_QUEUE_URL=http://0.0.0.0:4576/queue/risk_profiler_change
RP_DL_QUEUE_URL=http://0.0.0.0:4576/queue/risk_profiler_change_dlq
EVENT_QUEUE_URL=http://0.0.0.0:4576/queue/event
EVENT_DL_QUEUE_URL=http://0.0.0.0:4576/queue/event_dlq

Running integration tests (Cypress)

For local running, start a test db, redis, and wiremock instance by:

docker-compose -f docker-compose-test.yml up

Then run the server in test mode by:

npm run start-feature (or npm run start-feature:dev to run with nodemon)

And then either, run tests in headless mode with:

npm run int-test

Or run tests with the cypress UI:

npm run int-test-ui