← Back to Case Studies
GovTech / HR

Adaa – Performance Management Platform

Dubai Land Department·14 months
Angular 15TypeScriptRxJS.NET 6SQL ServerSignalRAzure DevOps

The Problem

A government entity with 5,000+ employees relied on spreadsheets and paper forms for annual performance reviews, creating a 3-month processing bottleneck each cycle and frequent data inconsistencies across departments.

Constraints

  • Must integrate with existing Active Directory and SAP HR
  • Arabic RTL as primary language, English secondary
  • IE11 support required for legacy government machines
  • Full audit trail for compliance

My Role

Lead Frontend Engineer

Architecture

Angular SPA → .NET Core API → SQL Server, with SignalR for real-time notifications. Modular feature architecture with lazy-loaded routes per department. Hierarchical data model supporting org-level → department → team → individual KPI cascading.

Key Decisions

RxJS State Management over NgRx

Used BehaviorSubjects with service-based state instead of a full Redux pattern.

The team was small (3 devs) and the state was mostly server-driven. NgRx would have added boilerplate without proportional benefit. Service-based state kept the codebase lean and approachable.

Dynamic Form Generation

Built a form engine that generates Angular Reactive Forms from JSON schema definitions.

Each department had unique KPI structures. Hard-coding forms would have required constant deployments. The JSON-driven approach allowed HR admins to modify review templates without developer involvement.

Highlights

  • Built a cascading KPI tree component rendering 500+ nodes with virtual scrolling
  • Implemented real-time notifications for approval workflows via SignalR
  • Created a reusable chart module (bar, line, radar) used across 12 dashboard views

Results

3 months

3 weeks

Review Cycle Time

~70%

99.2%

Data Accuracy

Manual

92% active users

Employee Adoption

Lessons Learned

  • RTL-first development is significantly easier than retrofitting LTR apps for RTL.
  • Virtual scrolling is essential for hierarchical data – DOM node count directly impacts perceived performance.

What I'd Do Differently

  • Would use Angular Signals instead of BehaviorSubjects for simpler reactivity.
  • Would implement a micro-frontend architecture for better team scalability.