Hospital Benchmarking Report Engine
Express Report Service & Server-Driven React Report UI
Role: Built the Express report-engine service — tokens, report and dashboard endpoints, benchmarking logic — and the React + TypeScript report UI that renders its layouts.
Both sides of a hospital benchmarking report hub: the Express report engine (entitlement-scoped tokens, report and dashboard endpoints, peer-percentile and trend logic) and the React + TypeScript UI that renders its server-driven layouts with MobX, ag-Grid and Chart.js.
Key Features
- Express report engine with an entitlement-scoped token exchange with the main platform
- Report and dashboard endpoints with drill-downs that return only the block to replace
- Benchmarking logic: indicators vs the peer group's median and quartiles, with multi-year trends
- Server-driven layouts: typed UI blocks (cards, tabs, dropdowns, tables, charts) — new reports without a frontend release
- React + TypeScript recursive renderer with MobX stores per domain
- ag-Grid tables and Chart.js charts for the report hub and dashboards
Tech Stack
Backend
Frontend
Tools
Challenges & Solutions
Reports Without Frontend Releases
Analysts wanted to add and change benchmarking reports often. Hardcoding each report layout in React meant a frontend release for every change.
The report engine returns a JSON array of typed blocks — layout, inputs, tables and charts — and the React UI walks it recursively. Each block can declare the endpoint it loads from or posts to, so a new report is a server change only.
Enforcing Subscriptions in a Separate Service
Which reports, years and peer groups a hospital may see is decided by its subscription in the main platform, but the reports are served by a separate service.
A token exchange: the main platform sends the user's entitlements with a server-held key and receives an access token that carries them. The engine enforces access from the token alone, without reading the portal database.
Drill-Downs Without Reloading the Page
Clicking a bar in a distribution chart had to open the detail for that quartile and year without re-rendering the whole report.
Each chart declares how a click maps to request fields (for example dataset → quartile, x-axis → year). The UI posts them back, the engine returns a replacement block with the same id, and the store patches that subtree in place.