Skip to content
Back to projects
svc/04employerBank of Georgia

Offers Hub

A management panel for merchants and for the offers the bank runs with them — promotions, cashback, and bonus-point campaigns aimed at merchants and customers.

employer
Bank of Georgia
Role
Angular developer
Timeline
2023–2025
Year
2025
Result
cascading merchant tree made reliable; redundant passes over large JSON removed
Runtime
AngularTypeScript

What it is

The internal panel the bank uses to manage merchants and the promotions it runs with them. Bonus points, cashback, and the other campaign types the bank offers merchants and customers are configured and administered here.

It is the administrative side of something customers only ever see the output of: a cashback offer that appears on a card, or points that land after a purchase, is a record someone created and maintained in a panel like this one. The work is in making that configuration legible and safe to operate — the people using it are managing live commercial arrangements with real merchants.

The merchant tree

The panel's central control is a tree. A merchant contains its brands, and a brand contains its POS terminals, and an operator picks what a campaign applies to by checking nodes in that hierarchy — checking a node selects everything beneath it. It is the component the whole tool is steered from, it holds a lot of nodes, and it was very buggy.

Selection that cascades down a hierarchy is deceptively hard: the checked state of any node is partly its own and partly a function of its descendants, so the bugs show up as a tree that disagrees with itself. That matters more here than in most places, because the thing being selected is the set of real merchants, brands, and terminals a live promotion will apply to. An operator has to be able to trust that what looks selected is what is selected.

I rebuilt how that selection works and made the component hold up at the sizes it actually runs at.

Result

The tree is reliable — checking a node cascades correctly through its subtree — and it stays responsive with the full merchant hierarchy loaded.

The wider performance work was less glamorous and paid off just as broadly: removing code that had been repeated in several places, and cutting out unnecessary loops over large JSON payloads. Much of the app's cost was in walking the same large structures more times than anything needed, and that is the kind of waste that never appears as one slow feature — it is spread thinly across everything, which is exactly why it survives so long.

Built in Angular. It was one of two internal applications I worked on at the bank, alongside the customer CRM, and like that one it is internal software with no public URL.

Back to projects