Skip to content

← Back to work

Employee Self Service Portal

One surface over HR systems, building services, approvals and a SharePoint CMS — with consistency and accessibility enforced at a boundary rather than requested.

Duration:
2021–2025
Role:
Lead Engineer
At:
Macquarie
Single-spaReactAngularStencilNode.jsEnvoyOPAAWS

Problem

The problem


Everything an employee needed lived somewhere else. SAP for one thing, PeopleSoft for another, building services somewhere else again, approvals arriving from several upstream systems, and content in SharePoint. Each had its own login, its own interface conventions, its own design system, its own vocabulary for the same ideas.

The cost was not any single system being bad. It was that using the company required knowing the company’s org chart of software.

Challenge

What made it hard


You cannot fix this by fixing the backends. Nobody was going to redesign SAP, and the systems underneath would keep multiplying. The only available surface was the front.

Which creates the real constraint: a portal built by many teams over many backends will quietly become as inconsistent as the systems it was meant to hide, unless consistency is enforced by construction rather than by agreement. The problem was never building the portal. It was making the portal stay one thing while many people built it.

Architecture

How it is put together


A Single-spa shell hosting React and Angular micro-frontends against a shared Stencil component library, with Envoy and OPA enforcing policy at the edge, over Node.js services on AWS serverless, fronting SAP, PeopleSoft and the rest.

Policy at the edge is the load-bearing decision. Authorisation stops being something each micro-frontend implements and becomes something the gateway guarantees, which is what lets teams ship independently without each shipping its own security model.

Employees through a Single-spa shell and micro-frontends, via Envoy and OPA, to Node.js services fronting ESS, PeopleSoft and SAP
Policy at the edge, so no team ships its own security model.

Tradeoffs

What we chose, and what it cost


We chose

Independent deployability with enforced consistency. Teams owned their own micro-frontend and released on their own cadence, but inherited the shell’s identity, the shared component library and the gateway’s policy whether they thought about it or not.

We gave up

Simplicity, permanently. A micro-frontend shell is harder to run than a monolith: version skew between independently released apps, a debugging story that crosses boundaries, and a shared component library that becomes a coordination point exactly when everyone is busiest. The architecture buys team autonomy and charges rent in operational complexity.

Outcome

What changed


  • Halved

    the clicks needed to complete an everyday task

  • WCAG 2.1 AA

    accessibility built into the shared component library, not retrofitted per app

  • One place

    HR systems, building services, approvals and a SharePoint CMS behind a single identity

    Design intent, not a measured result.

  • Four years

    in production, and the template for its successor

Lessons learned

What this changed


Anything left to convention drifts and anything enforced at a boundary holds. Accessibility is the clearest case: WCAG 2.1 AA held across the portal because it lived in the shared component library, not because each team was asked to remember it.

The sharper lesson only showed up on the second attempt. This shell had a lot of moving pieces, and they cost more in delivery and maintenance than they returned. Building the same pattern again for different users forced a separation this build never made: the shell should own composition, routing, identity and policy, and stay agnostic about appearance.