This repository contains the source code for the frontend applications of the Money and Pensions Service (MaPS). This is an Nx monorepo containing multiple Next.js applications and shared libraries.
This repository includes the following applications:
- Adjustable income calculator - Tool for calculating adjustable income scenarios
- Baby cost calculator - Tool for planning costs for having a baby
- Baby money timeline - Timeline of events leading up to the arrival of a baby
- Budget planner - Comprehensive budgeting tool for financial planning
- Cash in chunks - Pension withdrawal calculator
- Compare accounts (PACs) - Tool for comparing different account options
- Credit options - Credit comparison and advice tool
- Credit rejection - Support for credit rejection scenarios
- Debt advice locator - Service to find local debt advice
- Evidence hub - Evidence based documentation and reports
- Guaranteed income estimator - Pension income estimation tool
- Leave pot untouched - Pension pot preservation calculator
- Midlife MOT - Financial health check tool
- Money adviser network - Directory of financial advisers
- Moneyhelper contact forms - Various contact and enquiry forms
- Moneyhelper tools - Collection of financial tools and calculators
- Mortgage affordability - Mortgage affordability calculator
- Mortgage calculator - Mortgage payment calculator
- Pensions dashboard (MHPD) - Unified pensions overview
- Pensionwise appointment - Appointment booking system
- Pensionwise triage - Pension guidance triage system
- Redundancy pay calculator - Calculate redundancy payments
- Retirement budget planner - Tool for planning how much you may need in retirement
- Savings calculator - Tool to calculate how long/much to save to hit a goal
- Stamp duty calculator - Property stamp duty calculator
- Standard financial statement - Financial statement tool
- Take whole pot - Pension withdrawal calculator
- Tools index - Landing page for all tools
Each application has its own README in its respective directory under /apps/ with specific setup and usage instructions.
- Node.js (version specified in
.nvmrc) - npm
-
Clone this repository from Azure DevOps
-
Install dependencies:
npm install
Each application requires environment variables to run properly, you can either have a root level .env.local file, or an app specific file:
- Navigate to the specific app directory (e.g.,
/apps/budget-planner/) - Copy the
.env.examplefile and rename it to.env.local - Ask an existing team member for the correct values to populate the
.env.localfile
It is recommended to use the Nx Console extension to run app scripts (starting, linting, testing, etc.). The plugin provides an easy-to-use interface for managing and executing various tasks within your workspace.
Using Nx Console (Recommended):
- Install the Nx Console VS Code extension
- Use the sidebar panel to run tasks for specific applications
- View and execute build, serve, test, and lint commands through the UI
Command Line:
# Start a specific application
npm run serve <app_name>
# Example: npm run serve pensionwise-triage
# Use nx directly
npx nx serve <app_name>
# Or run Netlify dev (config in apps/<app_name>/netlify.toml)
# Runs locally with Netlify's proxy and redirect rules
netlify dev --filter <app_name>Open your browser and navigate to the URL returned in the terminal (typically http://localhost:4200 or similar).
# Build a specific application
npx nx build <app_name>
# Build all applications
npx nx run-many --target=build --all
# Build only affected applications
npx nx affected --target=buildTo generate a new Next.js application:
# Create app directory first
mkdir apps/example-app
# Generate the application
npx nx generate @nx/next:application example-app --directory=apps/example-appConfiguration Options:
- E2E test runner: Cypress/Playwright
- Use App Router: No
- Use
src/directory: No - Project name: Derived from directory
After generation, configure the project.json file using existing apps as examples to maintain consistency.
# Generate a shared library
npx nx generate @nx/react:library shared/uiConfiguration Options:
- Default stylesheet format: SCSS
- Use App Router: No
For each new application:
# Set up Tailwind for the app
npx nx g @nx/react:setup-tailwind --project=example-appAdd the workspace preset to the app's tailwind.config.js:
module.exports = {
presets: [require('../../tailwind-workspace-preset.js')],
// ...other config
};# Install Storybook dependency
npm add --dev @nx/storybook
# Generate Storybook configuration
npx nx generate @nx/storybook:configuration shared-uiE2E applications are organized in a common folder to prevent clutter:
├── apps
│ ├── e2e
│ │ ├── app-name-e2e
│ │ └── ...
│ ├── app-name
│ └── ...
Ensure E2E project.json has "projectType": "application" for proper NX detection.
# Run all tests
npm run test:all
# Run tests for specific app
npx nx test <app_name>
# Run affected tests only
npx nx affected --target=testSome dependencies, such as slug, are distributed as ESM-only modules. By default, Jest does not transform ESM code in node_modules, which can cause test failures when importing these packages.
To resolve this, the following configuration has been added to the shared Jest preset (jest.preset.js):
// jest.preset.js
module.exports = {
// ...other preset config
transformIgnorePatterns: [
// Allow Jest to transform slug ESM
'node_modules/(?!(slug)/)',
],
};This ensures Jest can correctly process ESM code from slug and prevents unexpected token errors during test runs.
All Jest configs in the workspace import this preset, so the change is applied globally.
Local Testing:
# Pensionwise Triage
npm run test:e2e pensionwise-triage-e2e
# Pensionwise Appointment
npm run test:e2e pensionwise-appointment-e2e
# Pensions Dashboard
npm run test:e2e pensions-dashboard-e2eEnvironment Testing:
# Test against dev environment
npm run test:e2e pensionwise-triage-e2e -- --baseUrl=https://dev-pwtriage.moneyhelper.org.uk/en/pension-wise-triage/
npm run test:e2e pensionwise-appointment-e2e -- --baseUrl=https://dev-pwappt.moneyhelper.org.uk/en/pension-wise-appointment/MoneyHelper Tools E2E Tests:
npm run test:e2e moneyhelper-tools-adjustable-income-e2e
npm run test:e2e baby-cost-calculator-e2e
npm run test:e2e baby-money-timeline-e2e
npm run test:e2e budget-planner-e2e
npm run test:e2e moneyhelper-tools-cash-in-chunks-e2e
npm run test:e2e moneyhelper-tools-guaranteed-income-estimator-e2e
npm run test:e2e moneyhelper-tools-pension-type-e2e
npm run test:e2e moneyhelper-tools-pot-estimator-e2e
npm run test:e2e moneyhelper-tools-pot-untouched-e2e
npm run test:e2e savings-calculator-e2e
npm run test:e2e moneyhelper-tools-workplace-pension-calculator-e2e# Run Storybook locally
npm run storybookOpen your browser and navigate to http://localhost:4400/
Production Storybook: When a pull request is merged to main, Storybook is automatically deployed and can be viewed at: https://main--65c4bdbe9bcdf2e1145a3b6a.chromatic.com
// Add to all story variations
const StoryProps = {
title: 'Components/Button',
component: Button,
parameters: {
design: {
type: 'figma',
url: 'https://link-to-figma-url',
},
},
};
// Add to specific story variant
export const Primary = Template.bind({});
Primary.parameters = {
design: {
type: 'figma',
url: 'https://different-link-to-figma-url',
},
};There is a custom generator that creates components following the Frontend Best Practices:
Via NX Console (Recommended):
- Select
generate→@maps-react/tools - component
Via CLI:
npm nx generate @maps-react/tools:componentGenerated Structure:
└── libs/shared/ui/src/components
└── ComponentName
├── ComponentName.stories.tsx
├── ComponentName.test.tsx
├── ComponentName.tsx
└── index.tsUse targetPath option to create components in specific directories (e.g., apps/pensionwise-triage/components).
# Lint specific app
npx nx lint <app_name>
# Lint all projects
npx nx run-many --target=lint --all
# Lint affected projects only
npx nx affected --target=lintInstructions for SonarQube setup and configuration can be found in sonarqube/README.md.
Upon creation of a PR, any apps that have changed in the source branch will have e2e tests and sonar scans run against them. In certain scenarios, we may want E2E tests or Sonar Scans to run against all apps in the monorepo, even for PR's where these apps have not changed. For example, upon changing SonarCloud configuration files, we may want to trigger Sonar Scans for every app to verify this isn't a breaking change, without having to manually change every app.
To trigger these test runs in the PR, add a marker to the end of your commit message for the most recent commit for your PR. Either add the marker to your last commit, or you can add an empty commit before creating the PR once all work is done on the branch.
# Empty commit message which triggers Sonar Scans for every app
git commit -m "Run sonar scans for all apps in this PR [run-all-sonar]" --allow-empty
# Commit message which triggers E2E tests for every app
git commit -m "Run all e2e tests for this PR [run-all-e2e]"
# Commit message which triggers both E2E and Sonar Scans for every app
git commit -m "Run all apps for this PR [run-all-e2e] [run-all-sonar]" --allow-empty- content-synch.yml - Content synchronization with AEM
- github-synch.yml - Push code from this repo to GitHub repository
- dependabot-pipeline.yml - Weekly dependency and vulnerability checks
| Pipeline Name | Trigger | Description |
|---|---|---|
| Netlify - PR Review | PR | Runs code analysis and e2e tests in parallel to netlify creating deploy previews |
| Netlify - Develop on Merge | PR Merged | Runs e2e tests on affected apps, resets develop with main and commits, netlify builds dev environment for affected apps (develop--<app_name>.netlify.app) |
| Netlify - Deploy to Environment | Manual | Deploys specific app and branch (usually main) to test or staging (e2e tests optional, enabled via pipeline parameter, urls test--<app_name>.netlify.app and staging--<app_name>.netlify.app) |
| Netlify - Branch to Environment | Manual | Allows teams to create a production build of a branch, which can then be published to the production URL in Netlify |
| Netlify - Redeploy Published to Production | Manual | Allows teams to re-deploy a previous commit of main to production, in the case of an environment variable changing but the team don't want the most recent build of main to be published. |
| Netlify - Unset Branch Environment Variables | Manual | Cleans up branch specific environment variables created in the 'Branch to environment' pipeline. Applies mostly to MHPD where the production deploy isn't the main branch. |
| Parameter Name | Default | Description |
|---|---|---|
| Branch/tag | main | The branch or tag to deploy |
| App to deploy | pensions-dashbaord | The application to deploy. Available options; All available applications. |
| Environment | test | Available options; test, staging or custom |
| Custom Environment | for use when 'custom' environment is specified | |
| Environment variables | Match environment | Which set of environment variables to use. Available options; Match environment, deploy-preview, test, staging |
| Custom environment variables | Comma-separated list (Key1=Value1, Key2=Value2) | |
| Run e2e tests | false | Whether to run E2E tests for the selected app |
| Parameter Name | Default | Description |
|---|---|---|
| Branch/tag | main | The branch or tag to deploy |
| App to deploy | pensions-dashbaord | The application to deploy. Available options; All available applications. |
| Copy Environment Variables | deploy-preview | Which set of environment variables to use. Available options; deploy-preview, branch-deploy, branch:test, branch:staging, production |
| Parameter Name | Default | Description |
|---|---|---|
| App to deploy | pensions-dashbaord | The application to deploy. Available options; All available applications. |
| Override Commit Reference | If empty will use the last published commit for the selected app. Otherwise requires full commit reference / hash |
| Parameter Name | Default | Description |
|---|---|---|
| App to deploy | pensions-dashbaord | The application to deploy. Available options; All available applications. |
| Branch Name | The name of the unused branch that was deployed to clear the environment variables for. |
Production deployments are managed through the Netlify UI:
- Visit the deploy list for your app (e.g., Mortgage Calculator Deploys)
- Filter by branch (enter "main") and status ("Successful")
- Adjust time frame to find the target build
- Verify the commit reference matches your expected deployment
- Click "Publish deploy" to deploy to production
# Create migrations file for latest version
npm nx migrate latest
# Or migrate to specific version
npm nx migrate [version]
# Run the migrations
npm nx migrate --run-migrations
# Install updated dependencies
npm installPost-Migration Testing:
- Run unit tests
- Run E2E tests
- Test component generation with
nx generate - Test apps in local environment
- Build and test all applications
# Build the project
npx nx build moneyhelper-tools
# Navigate to build directory
cd dist/apps/moneyhelper-tools
# Run the build
npm startThe following extensions provide useful features and improve productivity. Install them for the best development experience:
- Prettier (
esbenp.prettier-vscode) - Automatically formats code to maintain consistent style - ESLint (
dbaeumer.vscode-eslint) - Ensures code adheres to industry standards and catches errors early - Headwind (
heybourn.headwind) - Sorts Tailwind CSS classes automatically
- Nx Console (
nrwl.angular-console) - Provides UI for NX CLI, making it easier to generate components and run tasks - Conventional Commits (
vivaxy.vscode-conventional-commits) - Helps write conventional commit messages
- Wallaby.js (
WallabyJs.wallaby-vscode) - Real-time code coverage and test results - Jest Runner (
firsttris.vscode-jest-runner) - Run and debug Jest tests directly from editor - Better Comments (
aaron-bond.better-comments) - Enhanced code comments with colors and styles - TODO Tree (
Gruntfuggly.todo-tree) - Highlights TODO comments and provides overview - Tailwind Docs (
austenc.tailwind-docs) - Quick access to Tailwind CSS documentation - Figma (
figma.figma-vscode-extension) - View and inspect Figma designs in VS Code - Peacock (
johnpapa.vscode-peacock) - Customize workspace color for easy project identification
Filter extensions with @recommended to display workspace recommendations.
To avoid committing changes to .vscode/settings.json:
- Right-click the changed file and select "Skip Worktree", or
- Manually add
/.vscode/settings.jsonto.git/info/exclude
├── apps/ # Applications
│ ├── [app-name]/ # Individual Next.js applications
│ └── e2e/ # End-to-end test applications
├── libs/ # Shared libraries
│ └── shared/
│ └── ui/ # Shared UI components
├── tools/ # Custom NX generators and tools
├── netlify/ # Netlify deployment configurations
├── sonarqube/ # SonarQube analysis configuration
├── nx.json # NX workspace configuration
├── package.json # Root dependencies and scripts
└── tsconfig.base.json # Base TypeScript configuration
- Apps: Use maximum 2 separators (e.g.,
cash-in-chunks, notcash-in-chunks-calculator) - Components: PascalCase for component names
- Files: kebab-case for file names
- Pipelines: Follow
{resource}-{action}.ymlformat
- Follow the Frontend Best Practices
- Use conventional commit messages for better semantic versioning
- Ensure each pipeline achieves one goal, not many
- Document pipeline behavior in this README
- Test thoroughly after NX migrations
- Keep E2E tests in the dedicated
/apps/e2e/folder - Use shared libraries for common functionality
- Maintain consistent project.json configuration across apps
- Follow the established Tailwind configuration pattern
- Consult individual app READMEs for specific application details
- Review the NX documentation for workspace management
- Check the Frontend Best Practices wiki for coding standards
- Ask team members for environment variable values and specific configuration details
- Create a feature branch from
main - Make your changes following the established patterns
- Ensure all tests pass
- Create a pull request with a descriptive title and conventional commit messages
- Code will be reviewed and E2E tests will run automatically
- After approval and merge, changes will be deployed to the development environment
For application-specific information, please refer to the README in each app's directory under /apps/.