This is a working NodeJS (express) web application that uses the GOV.UK frontend and adheres to the GOV.UK Design System.
It also acts as the standard for how an express project should be structured, and what files are expected.
It can be copied and used at the starting point for any new web app.
NodeJS services in the MCA follow the express routes/controllers pattern, along with service classes that CRUD data.
src
+-- bin
| -- www
| controllers
| routes
| views
| services
| ...
test
--- web
--- services
--- ...
This project uses nunjucks for its view templating.
You will need to have Docker installed.
The rest of this documentation will assume you are using:
- asdf to manage the required software (see the
.tool-versionsif you want to manage them some other way). - direnv to manage your shell environment.
Copy .env.example as .env and replace the placeholders with variables found within the contents of the "SMarT-UI .env contents", inside the SMarT 1Password Vault. Ensure you click 'EDIT' before you copy or else the hashtags won't copy as required.
Copy .envrc.example as .envrc and replace the placeholders.
Add the following to your /etc/hosts file
# SMarT UI
127.0.0.1 service.local.smart.mcga.uk
Add the following to your ~/.aws/config file
[profile smart-dev-support]
sso_start_url=https://mcaconsole.awsapps.com/start/#
sso_region=eu-west-2
sso_account_id=<smart_dev_aws_account_number_as_found_for_smart_dev_account_in_the_aws_console>
sso_role_name=SMarTSupportAccess
region=eu-west-2
output=json
We recommend using AWS Vault for easy running of commands that need AWS access and an improved security position.
Simply prefix any command with aws-vault exec smart-dev-support -- as we do in the examples here. E.g.
aws-vault exec smart-dev-support -- aws sts get-caller-identityFor less typing, you can create add the following alias to your shell, which will leverage the AWS_PROFILE environment variable...
# In your `.bashrc`, `.zshrc` etc. file
alias awsv='if [ -z "$AWS_PROFILE" ]; then echo "Error: AWS_PROFILE environment variable is required by the awsv alias"; fi; aws-vault exec $AWS_PROFILE -- '...Then run your commands like this...
awsv aws sts get-caller-identityaws-vault exec smart-dev-support -- aws codeartifact login --tool npm --repository mcga-npm --domain mcga --domain-owner $AWS_ACCOUNT_NUMBER
npm installLog into AWS Elastic Container Registry if Docker Compose will need to pull the images:
aws-vault exec smart-dev-support -- aws ecr get-login-password --region eu-west-2 | docker login --username AWS --password-stdin $AWS_ACCOUNT_NUMBER.dkr.ecr.eu-west-2.amazonaws.comRun the backing services with Docker Compose:
docker compose upnpm startThe service will be available at http://localhost:2997/
All certificates required for Redis to run locally with TLS are generated by a docker container, and saved into your local repo. This folder is ignored by git but required for running locally, so please so not remove it.
Run SMarT API with no authentication.
Change COMPOSE_PROFILES in your .env file to COMPOSE_PROFILES=default,attachments,comments.
Ensure your COMPOSE_PROFILES in your .env is set to COMPOSE_PROFILES=default,attachments,comments
Then make sure the following are set in the .env file too...
NODE_ENV=dev
LOCAL_AUTH=falseYou also need to run the main SMART-API in dev mode too. Instructions on how to do this are in the SMarT-API readme.
Note that these test seem to have a reliance on the API being running, which is not very unit testy, but it's how they are right now.
npm run testNote: These do not work at the time of writing, but we have created a ticket to address this.
The tests use the domain https://service.local.smart.mcga.uk which is pointed at 172.17.0.1, the standard Docker gateway.
The certificates are generated by the SMarT UI project with alternative names for smart.
The script ./terraform/update-local-certs.sh copies the certs from the SMarT ssm and saves them to the nginx ssl folder. These certs MUST be committed in git.
There is a file /scripts/kube_login_smart.sh that enables a quick way to assume the Cross Account Administrator IAM role for SMarT.
You will need this role when using terraform, as well as when you access Kubernetes from the terminal.
When running the script, simply follow the instructions provided. If you are using the IAM role for terraform only, you don't need to use the kubernetes login command.
SMarT UI is a Node.js and Express website that shows GOV.UK‑style pages and talks to the SMarT API to get and update data. It uses Nunjucks templates, Superagent for API calls, and OIDC (Okta in production, a simple mock in development) for sign‑in and sessions.
-
Main Flow (3 steps)
-
User request and login The browser sends a request to Express ( src/app.js and src/routes/ ). OIDC code checks the session and adds user info and an access token if the user is signed in. -
Controller and service A controller (for example, src/controllers/tptrainees.js ) reads inputs, runs validation, and decides what to do. It calls a service (for example, src/services/trainees.js ), which uses Superagent and the access token to call the SMarT API. -
Build and return the page The service returns data to the controller. The controller renders a Nunjucks template (for example, src/views/tptrainees/trainee.html ) and sends the final HTML page back to the browser.
-
-
Key Building Blocks
Routes ( src/routes/ ): Define URLs and connect them to controllers and middleware. Controllers ( src/controllers/ ): Decide what should happen for each request, including validation and navigation. Services ( src/services/ , WebService.js ): Talk to the SMarT API and return data. Auth ( local-oidc.js , Okta): Handle login and user roles via OIDC. -
One‑line End‑to‑End View
User → Route/Auth → Controller/Service → SMarT API → Controller/View → User