Vonage Challenge Project repository dedicated for the recruitment process.
Let’s imagine you need to design a contact center application. It’s a simplified version of the domain on which we’re working on every day in Vonage.
There are 3 levels of employees: Agents, Supervisors, General Managers:
- There can be multiple Agents.
- There can be multiple Supervisors, but not more than Agents.
- There can be only one General Manager.
There are 2 types of interactions: voice (phone), non-voice (text chat) with interaction routing protocols as follows:
An Agent can handle 1 voice or 2 non-voice interactions at a time.
A Supervisor can handle 1 voice or 2 non-voice interactions at a time.
The General Manager can handle 1 interaction at a time.
The contact center allocates the incoming interactions in a specific way.
An incoming interaction needs to be allocated to an Agent.
If he cannot handle (reached maximum of interactions at a time) the interaction, it must be forwarded to Supervisor.
In case the Supervisor cannot handle the interaction, it needs to be forwarded further, this time to the General Manager.
If no-one can handle the interaction, the strategy is to reject that interaction.
How much time did you spend?
I've worked most of the time in the after-dinner time and not every day from the 30th of August to the 10th of September 2021. Each session was around 1.5h ~ 2h. From 3rd to 6th of September I've traveled. In total I count ~20h of work in these ten days.
More precisely ~3h were spent setting up the project, with a change of direction at the beginning, from pure angular 12 to Nx workspace. ~12h were spent on the main logic (and libs), while last 3-4h to setup the dashboard view.
How can we build your solution and run unit tests?
To run the application in browser make sure you have node installed (LTS, 16 used during development), clone this repo, run npm install
. In particular this project is based on Angular 12 and Nx workspace.
- Angular CLI
To be able to use indipendently some of the feature provided by the CLI of Angular, please install globally the package from npm npm install -g @angular/cli
. Thanks to that it's easier to run tests and build the application without using other scripts.
- Nx features
To be able to use the nx features for running tests I suggest to install globally nx npm install -g nx
. Nx will use a PowerShell script to load the application and tests. Remember to enable script execution in Powershell. To do so, open in administrator mode Powershell and launch
Set-ExecutionPolicy Unrestricted
.
- How to Build the app
Run ng build vonage-app
to build the project. The build artifacts will be stored in the dist/
directory. Use the --prod
flag for a production build.
- How to run unit tests
Run ng test vonage-app
to execute the unit tests via Jest. It can take also the library name for example ng test contact-center
. Under the hood launches tests with nx script.
Run nx run {library/app-name}:test
to run the test with nx.
Run nx run-many --all --target=test --codeCoverage
to execute all unit tests and generate code coverage for each library/app in the workspace. Coverage can be created also for specific library/app.
More Nx specific information in the Nx-README.md file.
The commands to test the three libraries independently are:
nx run agents:test --codeCoverage
nx run interactions:test --codeCoverage
nx run contact-center:test --codeCoverage
These commands will generate also the code coverage report.
- How to run the app
To run the application in browser, run npm start
and access the page http://localhost:4200 of your browser.
What technologies / libraries / programming paradigms have you chosen? Why?
I've choosen Angular and Typescript with RxJS as base technology stack. Angular has a good modularity built in while keeping very well separated contextes. Change management is handled with RxJS. Thanks to the Observables, changes are detected on push of new data. I've decided to move to use Nx workspace so that I have access to schematics that speed up scaffolding. The workspace organized like this separate libraries from apps. In this way I can have multiple apps sharing parts of libraries. Nx supports also Ngrx, if state management needs to be expanded I can fastly add facades for each lib. Jest used for unit testing, as required.
I've separated the problem in 3 contextes: Interactions (Messages or Phone calls), Agents (the people handling those interactions), Contact-Center (main logic). I've structured the libs so that they are as much agnostic one of the others as possible, except for the Contact-Center which coniugates Interactions and Agents with the Business logic.
Each libs has it's interfaces/models and services. Services handle state and interactions between classes. Interaction lib does all the logic that implies working on interactions, as Agents lib handles all the logic to work on agents. Contact-Center lib is different as it uses the services provided by the previous libs to support the business logic required by the problem. It has some specific models/interfaces and a Service that can be used as point of access for creating a Contact Center App. In the dashboard, this is the entity handling all the logic.
Asynchronous tasks are handled with RxJS using the Subject/Subscriber pattern. Everytime some data need to notify external entities of the change, a subject pushes the change of state so that all the subscribers can react on it. This is used to handle the execution of an "Interaction", from start to end.
The dashboard view of the project is a fastly developed frontend using Bulma CSS and some simple interaction handling with Angular/RxJS. I haven't had the time to workout proper components and tests for it, but it's possible to improve maintainability extracting some repeated parts.
Have you done any modeling / planning before coding? Please share that with us :)
After I setup the project I started to model with some simple interfaces what the data model should look like. Given the limitation of working with code, I needed a better spatial representation of the model, so in the second and next sessions of work I've created a diagram (root of repository) on draw.io with the schema of the libs and a diagram of the execution flow requested.
During the sessions I've updated the diagram and committed changes. Storing the diagram in the repository helps with tracking of the evolution of the models.