121 is an open source platform for Cash based Aid built with Digital Account & Local/Global Financial service partners. -- Learn more about the platform: https://www.121.global/
See: status.121.global
See: Testing
The documentation of the 121 platform can be found on the Wiki of this repository on GitHub: https://github.com/global-121/121-platform/wiki
To set up a local development-environment:
-
Install Git: https://git-scm.com/download/
-
Install Node.js: https://nodejs.org/en/download/
-
Install the version specified in the
.node-version
-file. -
To prevent conflicts between projects or components using other versions of Node.js it is recommended to use a 'version manager'.
-
NVM - Node Version Manager (for macOS/Linux).
-
NVM for Windows (for Windows)
-
FNM (for Windows/macOS/Linux)
-
-
-
Install Docker
-
On Linux, install Docker Engine + Compose plugin: https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository
-
On macOS, install Docker Desktop: https://docs.docker.com/docker-for-mac/install/
-
On Windows, install Docker Desktop: https://docs.docker.com/docker-for-windows/install/
If there are issues running Docker on Windows, you might need to do the following:
- Install WSL2 Linux kernel package.
Check step 4 on https://learn.microsoft.com/en-us/windows/wsl/install-manual - Set WSL2 as default version in PowerShell
wsl --set-default-version 2
- Check step 5 on https://learn.microsoft.com/en-us/windows/wsl/install-manual
- Install WSL2 Linux kernel package.
-
With these tools in place you can checkout the code and start setting up:
git clone https://github.com/global-121/121-platform.git
Navigate to the root folder of this repository:
cd 121-platform
Then install the required version of Node.js and npm
:
-
If you use NVM
-
On macOS/Linux:
nvm install
-
On Windows:
nvm install <version in .node-version>
-
-
If you use FNM:
fnm use
Clone the repository
git clone https://github.com/global-121/121-platform.git
Switch to the repository folder
cd services/
Copy the centralized .env file
cp .env.example .env
Environment variables are explained in the comments of the .env.example, they should be set up prior to development
To start all services, after setup, from the root of this repository, run:
npm run start:services
To see the status/logs of all/a specific Docker-container(s), run: (Where <container-name>
is optional)
npm run logs:services <container-name>
To verify the successful installation and setup of services, access their Swagger UI:
- 121-service: http://localhost:3000/docs/
Follow the "Getting started / installation"-section in the interfaces/README-file.
Install dependencies for all the interfaces at once, run:
npm run install:interfaces
Or from each of the individual interface directories(interfaces/*
) run:
npm ci
To start all interfaces at once, from the root of this repository, run:
npm run start:interfaces
To start an individual interface in development mode:
-
Run: (where
<interface-name>
is one ofpa
,aw
,portal
)npm run start:<interface-name>
-
Or explore the specific options as defined in each interface's own
package.json
orREADME.md
.
All individual Angular applications, when started will be available via:
- PA-App: http://localhost:8008
- AW-App: http://localhost:8080
- Portal: http://localhost:8888
When you use VS Code, you can start multiple editor-windows at once, from the root of this repository, run:
npm run code:all
To start an individual interface/service in VS Code:
-
Run: (where
<package>
is one ofpa
,aw
,portal
,121-service
)npm run code:<package>
When making changes to the data-model of the 121-service
(creating/editing any \*.entity.ts
files), you need to create a migration script to take these changes into affect.
The process is:
- Make the changes in the
\*.entity.ts
file - To generate a migration-script, in the 121-platform/services folder run:
docker compose exec 121-service npm run migration:generate migration/<descriptive-name-for-migration-script>
. This will compare the data-model according to your code with the data-model according to your database, and generate any CREATE, ALTER, etc SQL-statements that are needed to make the database align with code again. - Restart the 121-service through
docker restart 121-service
: this will always run any new migration-scripts (and thus update the data-model in the database), so in this case the just generated migration-script. - If more changes required, then follow the above process as often as needed.
- To run this file locally, do:
docker exec -it 121-service npm run migration:run
- If you want to revert one migration you can run:
docker exec -it 121-service npm run migration:revert
- If ever running into issues with migrations locally, the reset process is:
- Delete all tables in the
121-service
database schema - Restart
121-service
container - This will now run all migration-scripts, which starts with the
InitialMigration
-script, which creates all tables - (Run seed)
- See also TypeORM migration documentation for more info
NOTE: if you're making many data-model changes at once, or are doing a lot of trial and error, there is an alternative option:
- In
services/121-service/ormconfig.js
setsynchronize
totrue
and restart121-service
. - This will make sure that any changes you make to
\*.entity.ts
files are automatically updated in your database tables, which allows for quicker development/testing. - When you're done with all your changes, you will need to revert all changes temporarily to be able to create a migration script. There are multiple ways to do this, for example by stashing all your changes, or working with a new branch, etc. Either way:
- stashing all your changes (git stash)
- restart 121-service and wait until the data-model changes are actually reverted again
- set
synchronize
back tofalse
and restart 121-service - load your stashed changes again (git stash pop)
- generate migration-script (see above)
- restart 121-service (like above, to run the new migration-script)
All services use JSON Web Token (JWT) to handle authentication. The token should be passed with each request by the browser via an access_token
cookie. The JWT authentication middleware handles the validation and authentication of the token.
All the tokens and access keys for third party APIs should be added on the .env file and subsequently imported using the environment variables within typescript files.
To help with some types if files/tasks we've listed them here:
-
Workspace recommendations for VS Code When you open the root-folder of this repository in VSCode and go to: "Extensions" and use the filter: "Recommended"; A list should be shown and each extension can be installed individually.
Generic highlights:
- Cucumber (Gherkin) Full Support - To work with
.feature
-files for test-scenarios
Interfaces / front-end highlights:
- i18n Ally - To work with translations in the HTML-templates and component TS-files
- Cucumber (Gherkin) Full Support - To work with
If the Swagger-UI is not accessible after installing Docker and setting up the services, you can take the following steps to debug:
docker compose ps
to list running containers and their statusdocker compose logs -f <container-name>
to check their logs/console output (or leave out the<container-name>
to get ALL output)
If there are issues with Docker commands, it could be due to permissions. Prefix your commands with sudo docker....
If the errors are related to not being able to access/connect to the database then reset/recreate the database by:
- Setting
dropSchema: true
inormconfig.ts
of the specific service. - Restarting that service will reset/recreate its database(-schema)
When considering upgrading the (LTS) version of the Node.js runtime, take into account:
- The Node.js Release schedule: https://github.com/nodejs/release#release-schedule
- The (specific) version supported by Microsoft Azure App Services,
in their Node.js Support Timeline: https://github.com/Azure/app-service-linux-docs/blob/master/Runtime_Support/node_support.md - Angular's Actively supported versions: https://angular.io/guide/versions#actively-supported-versions
- Ionic Framework's supported Node.js versions: https://ionicframework.com/docs/intro/environment#Node--npm
When new Node.js dependencies are added to a service since it is last build on you local machine, you can:
-
Verify if everything is installed properly:
docker compose exec <container-name> npm ls
-
If that produces errors or reports missing dependencies, try to build the service from a clean slate with:
npm run install:services -- --no-cache <container-name>
Or similarly:
npm run start:services -- --force-recreate <container-name>
- Scenarios of end-to-end/integration-tests for the whole platform are described in
/features
. - Each component has its own individual tests:
- Unit-tests and UI-tests for all interfaces; Run with
npm test
in eachinterfaces/*
-folder. - Unit-tests and API/integration-tests for all services; Run with
npm test
in eachservices/*
-folder. See:121-service/README.md
/Testing for details.
- Unit-tests and UI-tests for all interfaces; Run with
- Is it to test query-magic?
- Is it to test essential endpoints (FSP integrations) and import/exports/etc?
- Often used (with different parameters) endpoints: PATCH /registration etc.
- Is there actual business-logic performed?
- Not necessary:
- update single (program) properties?
- Examples:
- import registrations -> change PA-status (with list of refIds) -> export included PAs
- update PA attributes: all different content-types + possible values (including edge cases)
These tests are still expensive (to bootstrap app + database)
There are a few reasons why we write unit tests cases:
- Unit tests are written to ensure the integrity the functional level aspect of the code written. It helps us identify mistakes, unnecessary code and also when there is room for improvement to make the code more intuitive and efficient.
- We also write unit test cases to clearly state what the method is supposed to do, so it is smoother for new joiners to be onboarded
- It helps us achieve recommended devOps protocols for maintaining code base while working within teams.
How are Unit Tests affected when we make changes within the code in future?
- We should aim to write and update unit tests along side the current development, so that our tests are up to date and also reflect the changes done. Helps us stay in track
- Unit tests in this case differ from manual or automated UI testing. While UI may not exhibit any changes on the surface it is possible code itself might be declaring new variables or making new method calls upon modifications, all of those need to be tested and the new test-scenario or spec-file should be committed together with the feature change.
We are using jasmine
for executing unit tests within interfaces
and jest
within services
. However, while writing the unit test cases, the writing style and testing paradigm do not differ since jest
is based on jasmine
.
See the Guide: Writing tests
We try to follow the "Conventional Commits" convention, combined with the "Angular Commit Message format".
When committing your changes, provide a commit message that starts with an appropriate keyword:
feat
: new feature for the userfix
: bug fix for the userdocs
: changes to the documentationstyle
: formatting, missing semi colons, etc; no production code changerefactor
: refactoring production code, eg. renaming a variabletest
: adding missing tests, refactoring tests; no production code changechore
: cleanups, version updates etc; no production code change
Add an Azure DevOps task ID at the end of the commit message.
For example: "feat: new feature added to the profile page AB#123456
".
After pushing your changes to the branch you can create a PR on https://github.com/global-121/121-platform/pulls.
Add additional description for the PR only if required.
Most (development-)dependencies in this repository are monitored by the GitHub Dependabot service, to keep them up-to-date.
The configuration of these updates is in .github/dependabot.yml
.
Unfortunately most individual dependencies are 'linked' to related dependencies that need to stay 'in sync'.
Sheetjs is not monitored by Dependabot. Check the latest version of Sheetjs:
Interface dependencies:
To update all Angular and ESLint related dependencies together, run (in each individual interface's directory):
npm run upgrade:angular
All related changes will be handled by the Angular CLI, but need to be checked afterwards with lint
, test
commands.
See notable changes and the currently release version in the CHANGELOG.
This is how we create and publish a new release of the 121-platform. (See the glossary for definitions of some terms.)
- Define the date/time of the release. (Notify the dev-team for a code-freeze.)
- Define what code gets released. ("Is the current
main
-branch working?") - Define the
version
(-number) for the upcoming release. - Update the CHANGELOG with the date + version.
- Commit changes to
main
-branch on GitHub.
- Commit changes to
- Create a
release
-branch ("release/<version>
") from currentmain
-branch and push this branch to GitHub - Given current setup of automatic deployments on release:
Make any configuration changes (ENV-variables, etc.) to the staging-service in the Azure Portal. - "Draft a release" on GitHub
- Add the
version
to create a new tag - Select the new
release/<version>
-branch - Set the title of the release to
version
. Add a short description and/or link to relevant other documents (only if applicable) - Publish the release on GitHub
- Check the deployed release on the staging environment
- Make any needed configuration changes (ENV-variables, etc.) on production-service(s)
- Use the manual deployment-workflows to deploy to production
- Add the
This follows the same process as a regular release + deployment. With some small changes.
-
Code does not need to be frozen. (As there is no active development on the release-branch)
-
Checkout the
release/<version>
-branch that needs the hotfix. -
Create a new local branch on top of it (e.g.
release/<v0.x.1>
) and make the changes -
Add the hotfix-release to the CHANGELOG
-
Push this branch directly to the main/upstream repository, not to a personal fork.
-
Create a new release (see above) and publish it.
-
Use the manual deployment-workflows to deploy to production
-
After the hotfix-release, apply the same fix to the main-branch in a regular PR (by creating a PR from the hotfix-branch to
main
-branch)
If you deploy the 121-platform to a server for the first time it is recommended to setup a separate Postgres database server. The connection to this database can be made by editing the POSTGRES_*
variables in services/.env
.
See: (via GitHub Action(s); i.e. deploy_test_*.yml
)
- PR's to the branch
main
are automatically deployed to an individual preview-environment. - When merged, a separate deployment is done to the test-environment; for that interface only.
See: (via GitHub Action(s); i.e. deploy_staging_*.yml
)
- A manual deploy can be run using the "Run workflow/
workflow_dispatch
" and selecting the preferred branch.
See: (via GitHub Action(s); i.e. deploy_test_service.yml
)
- When merged, a separate deployment is done to the test-environment.
- Make sure to update any environment-configuration in the Azure-portal as soon as possible, preferably before the merge & deploy.
- Create the necessary Azure resources
- Configure the service configurations based on
.env.example
- Create the necessary build/deploy-workflow files
- Merge these new files into the
main
-branch - Build/Deploy the platform via the GitHub Action(s) by selecting the target release-branch
- Decide on what version to deploy
- Check for any changes/additions/removals in the CHANGELOG
- Prepare the environment accordingly (Setting all service-configuration in Azure Portal)
- Build/Deploy the platform via the GitHub Action(s) by selecting the target release-branch
Term | Definition (we use) |
---|---|
version |
A 'number' specified in the SemVer -format: 1.1.0 |
tag |
A specific commit or point-in-time on the git-timeline; named after a version, i.e. v1.1.0 |
release |
A fixed 'state of the code-base', published on GitHub |
deployment |
An action performed to get (released) code running on an environment |
environment |
A machine that can run code (with specified settings); i.e. a service, or your local machine |
Released under the Apache 2.0 License. See LICENSE.