An operations console for a healthcare integration engine
Built the API layer, PHI-access auditing features and most of the frontend for a console that operates an HL7 integration engine.
- Role
- Top contributor
- Period
- 2025 to 2026
- Status
- Shipped, then feature work paused by the client
- Outcome
- I wrote 272 of the 389 commits, the largest share in the repository.
01 / Problem
Hospitals route clinical messages between systems with integration engines. The people who run one needed a web console to search messages, reprocess and export them, start and stop channels, and watch traffic trends. It is operations tooling, not clinical software. The engine already had its own server API and its own audit log, so the console had to sit in front of both without disturbing either, and it had to stay honest when one channel was slow. My part was the backend-for-frontend, most of the React frontend, the CI/CD pipeline and the staging deployment.
My role: Top contributor: backend-for-frontend, most of the frontend, CI/CD and staging
02 / System
Select a component to read what it does and how it fails.
- React console. Search, reprocess, export, channel control and dashboards, with focus trapping and keyboard navigation. It shows the gaps in a result instead of hiding them.
- Backend for frontend. Proxies the engine's API with CSRF handling, login rate limiting and input validation. When the engine is slow, this layer has to cope.
- Global search. Queries channels in batches of 10, with a 10-second timeout each. It fails per channel, and names the channels that timed out.
- PHI audit. Searches and message views on patient-ID channels post an audit event to the engine. Fails if the console's own polling adds false entries.
- Engine API. The engine's own server API, outside my control. Reprocess, export and channel control go through it. One channel can be slow while others are fine.
03 / Decisions
Batch the global search and name the gaps
- Decision
- I made global search query channels in batches of 10, gave each a 10-second timeout, and added a banner naming every channel that timed out.
- Rejected
- The old code fired one request per channel, all at once, with no timeout and no cap. A comment in it admitted the risk and moved on.
- Why
- One slow channel could stall the whole search. A result that hides its own gaps is worse than a slow one.
- Cost
- A search over many channels now runs in rounds, so the best case is slower than firing everything at once.
Keep the console out of the audit log
- Decision
- I moved the dashboard's polling to a coarser endpoint and filtered in the browser, then built the PHI-access auditing feature on top.
- Rejected
- Building auditing on a log that the console's own background polling was already filling with false entries.
- Why
- An audit log full of noise is no use to the person who has to read it.
- Cost
- The dashboard fetches more than it shows and does the filtering itself.
Replace the hidden time picker with a modal
- Decision
- I replaced the hidden native datetime input with a custom jump-to-time modal.
- Rejected
- Hiding the native input behind an icon, which was the original design.
- Why
- Firefox draws the time part inline inside the input, so hiding the input hid the time picker, in Firefox only.
- Cost
- A custom control that I have to keep accessible and consistent myself.
04 / What broke
Every trend count was too high
- Symptom
- Each message count on the dashboard trend chart was inflated.
- Cause
- Every data point summed connector-level rows on top of the channel-level aggregate that already included them.
- Fix
- I kept only the channel-level aggregate rows.
Formatting changed HL7 messages
- Symptom
- Viewing a pipe-delimited HL7 message with formatting on added stray brackets.
- Cause
- Every message went through the XML formatter, and HL7 is not XML.
- Fix
- I added XML detection, so anything else is shown untouched.
The staging image would not build
- Symptom
- Staging builds failed outright.
- Cause
- One copy step staged a single script, not the directory its dependencies lived in.
- Fix
- I copied the whole directory.
05 / Outcome
- I shipped the feature build and set up the CI/CD pipeline and the Traefik staging deployment. The client then paused feature work, and my later commits are deployment and infrastructure migration only.
- The console has ARIA labels, focus trapping and keyboard navigation.
- I have no figures for users, channels or messages handled, so I make no usage claim.
06 / The rule I took from this
Stack
Next
Working on something similar? Email me about this build.
Related: A social and market signal intelligence backend, An AI voice front desk for dental clinics.
Hiring for this kind of work? Python backend engineer.
Next case study: Architecture for a multi-tenant lead-intelligence SaaS.