← All workBalaji SankarCase study 04 / 12
Procurement / spend analytics / B2B SaaS2022 - present

SimfoniSuite

I’m rebuilding a live procurement suite one product at a time, without ever switching it off. A shared design system now ties four products together, with around 60 screens built across the suite.

Client

Simfoni

Role

Lead frontend engineer and full-stack contributor

Timeline

2022 - present

Stack
React 18TypeScriptViteRedux ToolkitTanStack QueryAnt Design 5TailwindAG Grid EnterpriseDjangoDjango REST FrameworkPostgreSQLSnowflakePowerBI
Outcomes
4

Products sharing one design system

~60

Screens built across the suite

3

Legacy-to-React migrations on the same live platform, with no planned downtime

450

Parity checks on the migrated project boards

Thechallenge

The client sells a suite of procurement tools: a hub for spend analytics and supplier intelligence, a procurement project tracker, a spend analytics product and a supplier marketplace. Each grew up separately - some as server-rendered Django with jQuery, one as an older React app - each with its own header, its own look and its own idea of which category, region and date range you were looking at.

Customers saw four products where they should have seen one, and every change to shared behaviour had to be made several times. The oldest apps couldn’t simply be switched off and rewritten either, because enterprise customers ran live procurement projects, approvals and savings reports through them every day.

How Iapproached it

01

One design system for the suite

I created the private UI kit every product now imports: global navbar, tab bar, a scope selector with category tree, region and date range, auth and session context, router and API setup, and the Ant Design theme. A fix to navigation or scope lands everywhere with one version bump.

02

Shell first, screens second

I set up a React + TypeScript app inside the Django monolith and mounted the shared navbar and scope bar into the existing server-rendered pages. Users got one consistent shell straight away, and screens could move to React one at a time while the old pages stayed live.

03

Rebuild against legacy behaviour

The project tracker and contracts were rebuilt in the hub from scratch - the old and new apps share no code - and checked behaviour by behaviour with a 450-point parity audit.

04

Full-stack where it mattered

When a migrated screen needed data the old page had baked into HTML, I wrote the Django REST endpoint myself rather than waiting on a backend queue.

Highlightsworth showing

  • (01)

    Around 60 screens: analytics dashboards, market intelligence, supplier libraries, an AI chat assistant UI, PowerBI embeds, user management, notifications and a drag-and-drop widget dashboard.

  • (02)

    Project tracker and contracts rebuilt in the hub: grid, kanban, status and Gantt boards, the project wizard, savings tracker, exports and contract expiry views.

  • (03)

    Runtime white-label theming that collapses every brand colour onto one tenant colour and swaps logos across the hub, project tracker, analytics and the shared kit.

  • (04)

    A written migration contract shipped as an AI coding skill, so engineers and AI agents port legacy pages the same way.

  • (05)

    Test plans layered by cost: each behaviour pinned at the cheapest level that can prove it, end-to-end only where a browser is genuinely needed.

Have a project like this?

Tell me what you’re building or what’s broken. I’ll tell you straight whether I’m the right person for it.

Next caseEdTech / student transport safety2019-22Scabbr→