Files
monorepo/LCU.WebApps.External.OnlineLoanApp
2026-04-22 15:01:09 +00:00
..
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-04-22 15:01:09 +00:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00
2026-03-25 11:54:22 -05:00

Introduction

TODO: Give a short introduction of your project. Let this section explain the objectives or the motivation behind this project.

Getting Started

TODO: Guide users through getting your code up and running on their own system. In this section you can talk about:

  1. Installation process
  2. Software dependencies
  3. Latest releases
  4. API references

Build and Test

TODO: Describe and show how to build your code and run the tests.

Contribute

TODO: Explain how other users and developers can contribute to make your code better.

If you want to learn more about creating good readme files then refer the following guidelines. You can also seek inspiration from the below readme files:

Landmark Credit Union Loan Application

This readme outlines the developer process, basic coding style guide and provides guidance and details around the technical approach to the user interface. You should always review and update this document to encompass your changes.

Known Contacts

The known contacts for this application are Jeff Knaub and Jerry Wenzen.

Getting Started

Before you can work with the code, build it, or deploy it you will need a proper developmenet environment. The required environment is basically Git, Node, and something to work with C#. This environment code has been wrapped up into a Powershell script that should run on any Windows 10 machine and produce a viable development environment to carry you through this guide. The script is available in the root of this directory as setup-env.ps1.

You should start by reviewing and possibly running that script if needed.

Testing Notes on LandmarkCu.com / online banking

The application is now integrated with Online Banking. Testing this is more difficult and involves having online banking pointed at the dev application. The process flow is documented in the architecture documents, but also briefly included here.

  1. User logs into online banking
  2. User clicks the apply for loan button
  3. Online banking POSTs a SAML token to the api end point.
  4. If valid a redirect to the application is returned, and cookies will be attached.

Cookies are required, and test online banking accounts are required. Additionally, there is a pipe from Azure to on-premise so that we can call the core for member information.

Working With The Code

Code is checked out from the Azure DevOps Repository, which is currently [https://landmarkcu.visualstudio.com/LoanWizard/_git/LoanWizard] with the back end code located at [https://landmarkcu.visualstudio.com/LoanWizard/_git/LoanWizardAPI].

Work should be done in a branch from Develop. In the shared folder there is a software development process document that talks about this, you should start there. A brief introduction will be included here.

Start by checking out the repository, and specifically the develop branch. You should be branching off of develop with your own working branch. When you are complete, you will create a pull request within VSTS here: [https://landmarkcu.visualstudio.com/LoanWizard/_git/LoanWizard/pullrequests]

Before submitting your pull request, review the following:

  • Did you commit with commitizen? git cz (see below)
  • Did you add all needed unit testing, and ensure all existing tests are passing?
  • Have you run the e2e tests and ensured they all pass?

In order to work and submit code, the project will need to be built and run. Instructions follow. Generally the project doesn't need to be built, just run locally. However, running a production build after major changes will ensure the production build is still working before CI runs.

Build

Run ng build to build the project. The build artifacts will be stored in the dist/ directory. Use the --prod flag for a production build. You can also use npm to run these commands: Run npm run build to build the project with default settings. Run npm run build-nvisia to build the project with default settings. Run npm run build-release to build the project with release settings (configuration for qa). Run npm run build-prod to build the project with production settings (and build optimizer).

Run (Development server)

Run npm run start for a dev server. Navigate to https://localhost:4200/. The app will automatically reload if you change any of the source files. Note that this will run with a proxy in place so that you can contact the web services.

This start script is in the package.json file, and runs ng serve --proxy-config proxy.conf.json --configuration=local --ssl

Run (Develop, QA, Prod)

Deployments to Develop, QQ, and Prod are automatically handled by Azure Dev-Ops. See the additional resources section below; as there is a document outlining the software development process, as well as the cloud setup Azure.

Running unit tests

Run npm run test to run the unit tests with code coverage. Run npm run test-debug to run the unit tests without code coverage, but with full stack traces. Run npm run test-interactive if you want to use real chrome for debugging and not headless. Firefox, IE, and Edge are also supported in this project. Run the ng test command and pass in the desired browser(s) into the browser argument Example: ng test --watch=false --browsers Firefox,Chrome,IE,Edge --no-progress

Running end-to-end tests

Tests run against Chrome and Firefox in parallel. Run ng e2e to execute the end-to-end tests via Protractor. Run npm run update-e2e if someone has changed the protractor config and you are getting errors; this usually fixes the problem. You may also need to run this if you are missing one of the browsers in the configuration.

Resources

There is additional documentation available within the Landmark shared folders; you should look for the following files, or ask someone for them if you can't find them. Start in the "Phase 1 Final Documents" folder under the 'LCU Credit App 2018' folder:

  • LCU Credit App 2018: This is a folder
    • The following documents, plus additional documents should be available in this folder, get access to it as soon as possible.
  • Architecture Document: Landmark Credit Union - Credit Application - SAD
    • This is the software architecture description.
  • Site Layout / Reference: Landmark_Site_Reference.XLSX
    • This shows urls/locations for source code and deployables and the Azure configuration
  • Software Process: landmark_software_process.docx
    • Outlines the process for working with the source code.
  • Azure Key Vault keys
    • Outlines each key used by the API and it's purpose
  • Additional notes on OLA's coding and components can also be found in the repo's wiki

Suggestion for IDE

  • Visual Studio Code
  • Webstorm

Architecture

The best explanation for the architecture can be found by referencing the document listed in the resources section above. However if you are looking to do something specific, here are some tips.

A. Add a new loan type 0. If you are adding a sub-type to an existing type, you do not need to follow all of these steps, these instructions cover adding a new category of loan type. 0. See: loan-type.ts, credit-card-outline.ts, credit-card-routing.module.ts, application-wizard.service.ts, credit-application.service.ts, credit-application-dao.service.ts, api-translator.service.ts

  1. Begin in loan-type.ts file; add your type.
  2. Create an Outline, start by looking at credit-card-outline.ts.
  3. With your outline created, create a set of routes similar to credit-card-routing.module.ts
  4. Add any needed sets of fields to common-groups.ts
  5. Create a new pages in the loan-wizard/wizards folder.
  6. Create any new field groups needed in the loan-wizard/field-groups folder.
  7. If you need custom waypoints, that is in loan-wizard/controls folder.
  8. update the CreditApplicationService to support any new fields.
  9. update the ApplicationWizardService to support any new fields and pages.
  10. Update the api-translator for any fields that need to be submitted to the back end, this is in shared/api-translator.
  11. Add your loan to app/select-loan if needed.
  12. Make sure to add additional unit testing as needed for all new code.
  13. Don't forget you may need to change the back end services!

B. Change an environment

  1. There is currently local, prod, e2e, and default. These are in src/environments, but you must also change angular.json!!!!!

C. Add e2e testing

  1. This is under the e2e folder.
  2. There is a folder for each major loan type, and a shared folder for common pages.
  3. Add your folder and tests per the existing pattern, adding to shared when possible.
  4. In the protractor.conf.js file is where we specify which test files are run, and on which browsers.
  5. Don't forget to update your protractor install, there is a script in the package.json "npm run update-e2e"

D. Something not listed here

  1. The file structure for this project is organized as a hybrid - most code is organized by feature, with shared code organized under the shared folder. If you are looking for something with common behavior, start in app/shared. Otherwise it's best to start in app/loan-wizard.
  2. It's fairly easy to find the code for a specific page - use the route shown in your browser, like this: > https://applydev.azurewebsites.net/loan-wizard/cc/st/step-2 The 'CC' part is the category, and the 'ST' is the type. The 'step-2' is the page. 1. Check the various routing modules to find your category (cc is credit card), this is *-routing.module.ts 2. Find the route in that module corresponding to the page (step-2 in this case), the component listed is the code for that page. Start there. In this case, CC leads to credit-card-routing.module.ts which leads to the PersonalInfoPageComponent.
  3. Beyond this, you should refer to the architectural document and spend some time reviewing the code.

Releases

Releases are handled by anyone on the team with access to VSTS. Generally when a pull request is accepted to develop, that will be automatically built and deployed to DEV. The Dev application is here: [https://applydev.landmarkcu.com]. The same is true for the back end / API. When you want to make a release, you must revise the changelog (CHANGELOG.md file). This is a two step process:

  1. run 'npm run release' in the develop branch, this will: A. Update the version in package.json automatically. B. Update the CHANGELOG.md file automatically
  2. Update/Review the CHANGELOG.md as needed, usually for: A. Add backend features/fixes/etc B. Add missing ticket numbers (or 'no ticket') C. Remove duplicates

You can force a version number if needed by changing the package.json, package-log.json, and CHANGELOG.md. Once you are done revising you can 'git commit --amend --no-edit' and then 'git push -f' will push the release to develop.

To get to QA, develop must be merged into the release branch and pushed. This will automatically cause the release branch to be build and the resulting release to be pushed to QA.

To get to production, release must be merged into master and pushed. This will automatically cause the code to be built and packaged as artifacts. However the release process is manual, and can be done here: [https://landmarkcu.visualstudio.com/LoanWizard/_release]

When creating releases, it's important not to forget to make a release and update the change notes as needed. There is information on creating a release below. An important tip is that on the website you can hover over the landmark copyright in the bottom left to see the released client version.

Setup Commitizen and Produce changelogs and release notes

Commitizen is a command line tool that helps format commit messages with a series of prompts that are used to generate a commit message. We use this tool to standardize our commits for tracking a changelog and producing release notes.

  • npm install commitizen -g
  • npm install commitizen --save-dev // Already done for you, skip.
  • npm install cz-conventional-changelog --save-dev // Already done for you, skip.
  • npm install --save-dev validate-commit-msg // Already done for you, skip.
  • npm install -g conventional-changelog-cli

Instead of committing with git commit commit with git cz This will force your messages into the format ():

Definition Description
feat A new feature
fix A bug fix
docs Documentation only changes
style Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc)
refactor A code change that neither fixes a bug nor adds a feature
perf A code change that improves performance
test Adding missing or correcting existing tests
chore Changes to the build process or auxiliary tools and libraries such as documentation generation

Here is how semantic-release will map these to release types and how it maps to semantic verioning:

Commit message Release type
fix(pencil): stop graphite breaking
when too much pressure applied
Patch Release (PATCH)
feat(pencil): add 'graphiteWidth' option Feature Release (MINOR)
BREAKING CHANGE: The graphiteWidth option
has been removed. The default graphite
width of 10mm is always used for performance reasons.
Breaking Release (MAJOR)

Produce or update the changelog

You shouldn't need to do this, it should be generated for you when you create a release (below)

  • Create changelog from scratch: conventional-changelog -p angular -i CHANGELOG.md -s -r 0
  • Update the changelog: conventional-changelog -p angular -i CHANGELOG.md -s

Produce a release

  • Use: npm run release

Resources:

ADA Compliance

This application is targeting level AA ADA Compliance, here is the checklist you should keep in mind when developing:

  • Every image, video file, audio file, plug-in, etc. has an alt tag
  • Complex graphics are accompanied by detailed text descriptions
  • The alt descriptions describe the purpose of the objects
  • If an image is also used as a link, the alt tag describes the graphics and the link destination
  • Decorative graphics with no other function have empty alt descriptions (alt=””)
  • Data tables have the column and row headers appropriately identified (using the tag)
  • Make sure the page does not contain repeatedly flashing images
  • Check to make sure the page does not contain a strobe effect
  • All scripts and plug-ins and the content within them are accessible to assistive technologies, or else an alternative means of accessing equivalent content is provided
  • When form controls are text input fields use the LABEL element
  • When text is not available use the title attribute
  • Include any special instructions within field labels
  • Make sure that form fields are in a logical tab order
  • Include a ‘Skip Navigation’ button to help those using text readers
  • SVG icons should not focusable by tabbing in IE (utilize focusable="false" on all icon tags)

Coding tools for ADA Compliance

Style Concerns

  1. Make sure the validators listed are full and correct.
  2. Make sure the error display component shows all validators you are using.
  3. Make sure default value is provided at the model level.
  4. A field cannot be a number, be part of a select, and have blank ('') as the default. Make these non-numbers if possible.
  5. Select boxes should all start on their default, which should derive from the MODEL.
  6. Select boxes title/default should be "Please Choose" if they do not have a default value.
  7. Select boxes and text inputs should have class="form-control".
  8. every declaration should have an (ngSubmit)="commandNext()".
  9. Next button should be at the LEFT, the back button should be BEFORE it.
  10. Next button should say "Continue", not "Next".
  • Always keep the web development checklist in mind: http://webdevchecklist.com/
  • (click) bindings should bind to a CommandXXX function with Command as a prefix. This denotes to anyone looking at the component that a given function is UX driven.
  • Keep minimal functionality in Components, they should act as minimal controllers. Refactor work and business logic to a service.
  • You should have unit tests for all components and services.
  • Take your time with naming and ask the team for help; but take naming seriously so that your components and services are recognizable.
  • Review the .editorconfig file if you are notices style differences in PRs, resolve any problems with the team.
  • DO NOT use angular material for the loan application system! Angular material should only be used for the admin system.

Libraries

Admin System Dependencies

  • @angular/cdk
  • @angular/material

Angular Material

  • Angular material is a library used exclusively for the admin system.
  • Provides the datatable with native sorting/paging/filtering

Angular

This project was generated with Angular CLI version 6.0.8 with the command ng new ui --routing --style scss The project's package.json has been updated with various libraries and scripts; it should always be reviewed.

Code scaffolding

Run ng generate component component-name to generate a new component. You can also use ng generate directive|pipe|service|class|guard|interface|enum|module. We do not generally use the code scaffolding.

FAQ

Q. I'm running the unit test and I see output like this: HeadlessChrome 68.0.3440 (Windows 10.0.0) XYZComponent should use the service to add address controls to the form group FAILED [object ErrorEvent] thrown

A. Re-run the tests using npm run test-debug, which will show the full stack trace but not provide code coverage.

Q. What do I need to know about NGX-Translate

A. The primary translation file is en.json, and is loaded asynchronously (it could be moved out of project); this is setup in the app.module.ts by using a TranslateHttpLoader. Some entries have HTML, if you want to use HTML in an entry, you have to bind to [innerHtml] Html example: <h6 translate [innerHTML]="'COPY.DISCLOSURES' | translate: localState"></h6> non-html example <h6 translate>{{'COPY.DISCLOSURES' | translate: localState}}</h6> You should refer to the ngx-translate documentation for full usage and instructions.

Q. What do I need to know about Security?

A. There are many security concerns outlines in the architecture documents in the share (see resources above). To add to it, there are multiple security mechanisms at play. One is for Landmark employees, and uses the ADAL-Angular-6 library to authenticate against Azure AD. The other is with NCR/DI and is used to authenticate members; this is handld in the API and the client uses this via checking for cookies. Be careful not to mix up these two methods.

File Upload Component and Azure Blob Storage

The file upload component allows users and dealerships to upload files to ACTion. This is handled with both Azure Blob Storage and CosmosDB. CosmosDB has a list of files associated with a loan application that contains information about the file and the GUID of the file in Blob Storage.

When an application is submitted or a dealership clicks transmit, the LoanApplicationController will get the CosmosDB record for the list of files and loop over them to transmit them to ACTion. After the files have been transmitted to ACTion, they are removed from Blob Storage.

The files that aren't ever transmitted to ACTion will remain in Blob Storage (this can happen from API failure or if a dealership closes the form without transmitting). Files that are older than 30 days will be removed automatically by a rule set in the Lifecycle section of Azure.

Dealership Portal

The dealership portal can be accessed via /dealership-portal and allows dealerships to upload documents to an ACTion loan. There are four required fields that are used to authenticate a dealership: dealership code, dealership password, application ID, and the primary applicant's last name/full business name.

Dealership Code

(string, case-sensitive, max length: 60)

2-3 digit code that is automatically generated by ACTion when a dealership is added. It takes the first letter of the dealership's name and then increments the number based on other dealerships with the same first letter. So if there were 9 dealerships that started with B (B1-B9), the next B-named dealership would become B10.

It also appears that it converts dealerships that begin with a number to the first letter of that number, e.g. 5 -> F; so 5 Corners Dodge becomes F6, as it is the 6th dealership to begin with F.

The dealership code can be found within ACTion.

Dealership Password

(string, case-sensitive, max-length 30)

This password is not a password in the traditional sense, as it is being stored in the plain-text field costCenterCode within ACTion. Dealership's will not have access to create/change their password, so it must be done by someone at Landmark with access to ACTion.

Application ID

(integer)

Self-explanatory

Primary Applicant's Last Name or Business Full Name

(string, case-insensitive, max-length: 250)

When the authentication request is made, the application is taken from ACTion, the primaryBorrower field is inspected for idRef which contains the GUID of the primary borrower. The primary borrower can be an individual or a company. Once this ID is found, the API loops over the individuals and companies associated with the application until it finds the matching ID.

Once the matching ID is found, it will return the lastName if it is an individual or the tradeName if it is a company. The request much match this value exactly, but is not case-sensitive.

Other notes

This portal utilizes the file upload component, which is the same component used for the loan application process. Any changes to this component that is specific to the dealership portal must be made with caution as those changes will affect all loan processes that use it.

In non-production environments, you can force an error to happen to test what happens if a file transmission error occurs by uploading the first file with the name do-not-allow-transmission.jpg. The API will see this file and return a 500.