How Urban Company is standardizing change controls!

UC Blogger
Urban Company – Engineering
6 min readJun 28, 2022

By — Anil Maheshwari (Engineer, Fintech)

At Urban Company, our Marketplace Platform is growing at a tremendous scale. That’s a testimony of the high quality services we have been offering to our customers and they have been showing a strong trust in the platform. Especially in the last 3 years, we have been able to scale the marketplace from 12 cities in India and 1 International city to 60+ cities in India and 9 international cities in 5 countries.

Now to run all of the operations smoothly, our business teams would keep updating a lot of data sets on the platform using internal tools. Many of these changes include the ones which have a direct impact on the company’s financials (e.g. launching new pricing / sku, discount coupons, subscription plans etc and updating these). We call it critical changes.

There are two parts to the problem:

  1. Access Control: Who can perform what kind of actions based on their access?
  2. Change Workflow: How these actions (specially the critical changes) be performed with clear minimal guardrails? Mainly two things — ensuring actions are serving intended purpose and these are logged for auditing.

In this article, we are are going to focus on the Change Workflow part of it.

Problem Statement:

As we are growing and our revenues are also increasing with time it’s very important and critical that we are able to make all of these critical changes without any unintended consequences. At the same time, we have been getting feedback from our auditing teams to strengthen our change control process to give them clear confidence that we are always doing the right things. Also, we don’t want to hamper our business team’s productivity in order to achieve it. So in a nutshell, we are striving to achieve the following goals inside solving for Change Workflow:

  1. Review Process: Ability to have effective change approval process.
  2. Audit: Ability to easily audit log all the changes in same format.
  3. Ease of Use: Reducing overall time investment for all the stakeholders in making changes.
  4. Ease of Replication: Different teams don’t reinvent the wheel to solve same thing.

Proposed Solution and Design:

As a tech first organization, standardization through platform thinking is core part of our DNA and we keep it very close to our hearts. Going by that philosophy we decided to solve it through a Unified Maker Checker (UMC) which would be used for all critical changes across teams & services:

Before we look at the design of the solution, let me quickly tell you about the different items involved in it.

  1. Entity: Every critical change is represented by creating / updating a particular entity in the system.
  2. Entity-Service: For every entity, there is a service which owns it.
  3. Access-Control-Service: This is the service which contains logic for the Unified Maker Checker Control system.
  4. Central Review Dashboard: This is part of the service which powers our internal tools.

For every critical change, we need to tackle it with following parts

  1. Define two types of role for any change
    Maker: Maker is a person who has an access right to make changes within the system
    Checker: Checker is the person who checks & approves of all the changes made by a maker using an access right.
  2. Entity-service needs to divide create / edit logic into two parts
    Create Logic:
    submitCreateForApproval() — This is the function which takes data from the maker user on the tool and sends this request to the unified maker checker system.
    createEntity() — This is the function which consumes the event published from the unified maker checker system once the checker has approved this change.
    Edit Logic:
    submitUpdateForApproval() — This is the function which takes data from the maker user on the tool and sends this request to the unified maker checker system.
    updateEntity() — This is the function which consumes the event published from the unified maker checker system once the checker has approved this change.
  3. Access-control-service provides common functionalities
    createChangeRequest() — This is the function which every entity-service needs to call for any change.
    approveChangeRequest()/rejectChangeRequest() — These are the functions which are called by the dashboard-service whenever the checker users take an action on it.
    completeChangeRequest() — This is the function which every entity-service needs to call for marking the change request as success/fail.
  4. Central Review Dashboard provides these functionalities
    – Common UI for makers and checkers to see all the requests raised.
    – Common UI for checkers to review changes before making a decision to approve / reject it.
Systems Flow Diagram for Maker Checker Process
Systems Flow Diagram for Maker Checker Process

How to use Maker Checker?

Client API:

Every entity-service would be calling the createChangeRequest API for creating / updating any entity.

function submitCreateForApproval(){
...
...
...
let resp = await AccessControlService.createChangeRequest({
entityType: ‘LeadPricingConfig’,
entityId: configId,
requestMethod: ‘Update’,
initialState: JSON.stringify(currentLeadPricingConfig),
finalState: JSON.stringify(newLeadPricingConfig),
makerUserId: userId});
...
...
...
}

Event consumer code in the entity-service would be calling the completeChangeRequest API after it has made the changes successfully in the system.

function createEntity(){
...
...
...
try {
await LeadPricingConfigService.create(config);
await AccessControlService.completeChangeRequest({
requestId: requestId,
status: ChangeRequestStatus.SUCCESS});
} catch(err) {
await AccessControlService.completeChangeRequest({
requestId: requestId,
status: ChangeRequestStatus.FAIL,
reason: err.message});
}
...
...
...
}

Configuration:

As a one time effort, every entity-service needs to put the details related to the entities it wants to bring under the maker checker control system in the centralized access-control-service’s configuration.

"LeadPricingConfig": {     entityType: "LeadPricingConfig",

// This is the role access which a maker for this particular entity must have (part of Access Control)
makerAccessKeys: ["LEAD_PRICING_EDIT"],
// This is the role access which a checker for this particular entity must have (part of Access Control)
checkerAccessKeys: ["LEAD_PRICING_APPROVE"]
}

Tooling UX:

View to see all the requests
Checker can review the changes and then approve/reject

We are using react-diff-viewer to show changes in JSON format.

So far our business teams are happy using it to make sure all the changes are reviewed. However, as we scale and grow our business teams more, we would move our plain vanilla JSON based UX to more form based UX which would be closer to the UX teams use to make changes.

Conclusion:

One of the biggest benefits of building and adopting centralized platforms is that as these platforms evolve with time and get more capabilities built, these capabilities are done for free with all the existing clients. We have got leadership at Urban Company Engineering which always encourages to think in terms of framework / platforms.

This framework is already adopted in 15+ services across teams controlling changes for 30+ entities. Currently ~200 changes per day by the business teams go through this framework. That has happened as at Urban Company everyone in the leadership is committed to not just building but equally on adopting the platforms.

About the team:

  1. Pranav Siddharth (Engineer, Payments)
  2. Shubham Pandey (Engineer, Compliance and Finance)
  3. Kaushik Srinivasan (Product Manager, Compliance and Finance)
  4. Anil Maheshwari (Engineering, Urban Company)

The team is part of the Supply vertical at Urban Company Engineering, building products and systems to empower and make 30k+ professionals on the platform successful not just in India but across the globe.

Sounds like fun?
If you enjoyed this blog post, please clap 👏(as many times as you like) and follow us (UrbanClap Blogger) . Help us build a community by sharing on your favourite social networks (Twitter, LinkedIn, Facebook, etc).

You can read up more about us on our publications — https://tech.urbancompany.com
https://design.urbancompany.com
https://medium.com/uc-culture
https://www.urbancompany.com/blog/humans-of-urban-company https://tech.urbancompany.com/ucs-secret-to-10x-engineering-94c3684e27a4

If you are interested in finding out about opportunities, visit us at https://careers.urbancompany.com

--

--

UC Blogger
Urban Company – Engineering

The author of stories from inside Urban Company (owner of Engineering, Design & Culture blogs)