Local development

Prerequisites

Requirement Detail

Node 12.21.0

Pinned in .nvmrc. Run nvm use in the repository root. Newer Node will not build this project.

Python 3

deployment/setenv.sh calls python3 ./deployment/generate_gci.py for non-release environments.

Chrome

Supplied by Puppeteer for headless unit tests; a real Chrome for development.

Repository access

git clone git@github.com:Payability/internal-client-v2.git

The repository README references nvm install 12.13.0 while .nvmrc pins 12.21.0. Trust .nvmrc.

Setup

nvm use                 # pin Node 12.21.0
npm install             # also installs Husky hooks via the postinstall script

Then generate the environment file — this is the step people forget:

./deployment/setenv.sh <ENV_NAME> [DOMAIN] [CONFIG_DIR] [ENV_FILE_NAME]

# example, pointing at the `exp` dev environment
./deployment/setenv.sh exp "dev.payability.com" "$PWD/deployment"

npm start runs setenv.sh for you with whatever environment name is currently committed in package.json, then ng serve:

npm start

The environment name in the start script is committed to package.json and changes as developers point at different backends. Check what it currently says before running npm start — if it is not the environment you want, run setenv.sh explicitly instead, or you will silently develop against someone else’s backend.

To switch backend later, re-run setenv.sh with a different name (staging, apps, …). ./deployment/checkenv.sh prints which environment you configured last.

Details of what the script generates: environments.

Commands

Command Does

npm start

setenv.sh then ng serve on port 4200.

npm run lint / npm run lint:fix

ESLint over src/app.

npm run format

Prettier write over src.

npm test

Karma in watch mode.

npm run test-single

Karma once — prefer this in agent and CI loops.

npm run test:ci

Headless with coverage and JUnit/Cobertura reports.

npm run build / build-prod / build-test

Angular builds. The prod/test variants go through ng-high-mem (--max_old_space_size=8192).

npm run cy:open / cy:run

Cypress interactive / headless.

npm run cy:open-local / cy:run-local / cy:run-local-no-watch

Start the app then run Cypress against it (start-server-and-test).

npm run connect-to-eva

Prepare an EVA-aware environment and serve.

npm run start-with-eva

The above, plus open the EVA dev server in a second terminal tab.

Ports

Google SSO only works on ports registered with the Google client. From the repository README:

http://localhost:4200   (default)
http://localhost:4300
http://localhost:4400
http://localhost:4500
http://localhost:4600   (used by EVA)
http://localhost:5000
http://localhost:8082

Serving on any other port breaks login: the Google client id (env.googleAuthClientId) is registered only for these origins, and it is the same client id in dev and production. If sign-in silently fails, check the port first.

Note 4600 is EVA’s dev server port, so do not use it for this application when running both.

Incognito mode is not supported

Stated explicitly in the repository README. The application depends on localStorage, sessionStorage and a cross-subdomain cookie for the EVA token — see caching and persistence.

Running against a local EVA

Parts of the UI are rendered by EVA. To develop against a local EVA checkout:

npm run start-with-eva

which expands to:

export EVA_API_CUSTOM_URL=http://localhost:4600
./deployment/setenv.sh exp dev.payability.com "$PWD/deployment" environment.with-eva
# … then serves this app and, via `ttab`, runs `npm run start-with-ia` in ../eva-fe

So it expects an eva-fe checkout as a sibling directory.

npm run connect-to-eva does the environment preparation and serves this app only — use it when EVA is already running.

Two behavioural differences on localhost:

  • The EVA auth token travels in the iframe URL (?auth=<jwt>) instead of a cookie on the shared parent domain.

  • Iframe origin checks treat localhost as always allowed.

Both are in iframe messaging and EVA. A bug that only reproduces locally is often one of these.

EVA_API_CUSTOM_URL is honoured by deployment/set-env.ts:

evaApiUrl: '${process.env.EVA_API_CUSTOM_URL ? process.env.EVA_API_CUSTOM_URL : process.env.EVA_API}/',

Iframe resizing

The repository README documents the contract: a same-named ResizeIframeService exists in both applications. In the default direction EVA sends width/height (and optionally a selector for a different frame) and Internal Admin resizes.

Husky hooks

Installed by npm install (the postinstall script runs husky install).

Hook Runs

pre-commit

npm run lint:staged (eslint --fix on staged *.ts via lint-staged) then npm run format:staged (pretty-quick --staged).

pre-push

npm run test-single.

Do not bypass with --no-verify. If a hook is failing, fix the cause. The hooks are the only automated gate on a branch before CI.

Feature flags locally

Build flags come from environment.featureFlags, which setenv.sh regenerates — so editing it by hand is temporary. For local experimentation prefer the runtime console at /admin/feature-flags (needs the DEV permission), which stores overrides in sessionStorage.

In non-production builds the resolved flag table is printed to the console once per page load. See feature flags.

Useful development tooling

Tool Detail

Redux DevTools

Instrumented unconditionally. The fastest way to understand any screen — every meaningful transition is a named action.

/admin/feature-flags

Runtime flag console for this app and EVA.

Iframe message log

[IA] Sending / [IA] Received in the console on non-production builds.

Request ring buffer

Last 50 requests in state.errors.cachedRequests.

./deployment/checkenv.sh

Which environment you last configured.

SonarLint (optional)

The repository README documents connecting an IDE to SonarCloud:

  1. Generate a token in SonarCloud (My Account → Security).

  2. Install the SonarLint extension (it requires Java).

  3. In VS Code user settings:

    "sonarlint.connectedMode.connections.sonarcloud": [
      { "connectionId": "payability", "organizationKey": "payability", "token": "GENERATED_TOKEN" }
    ]

WebStorm instructions are a // TODO in the README.

First-run failures

The recurring ones, with fixes, are in troubleshooting. The short version: almost every "it will not build" is a missing setenv.sh run or the wrong Node version.