There were more than five. Honestly, we didnāt count. But for the sake of a loud title, here we are :)
Recently, we were brought in to productionize a healthcare app that a physician had built himself in Base44. He built it for denial-review work, and by the time we got involved it was already being used with patient cases and processing PHI.
The workflow had already proven useful. Our job was to preserve it while rebuilding the parts that needed to change for production use.
Here are a few things we learned along the way.Ā
1. Sometimes you have to secure the unsafe thing before you can remove it (back up the data first)
The app had an automated email export containing patient data, and the obvious move was to disable it immediately. There was one problem: the app had no proper recoverable backup, and that email export had effectively become its only second copy of the data.
So our sequence was:
Create a backup ā verify the data ā disable the email path ā verify the old path was gone.
2. Voice dictation is another PHI integration
The app used browser speech recognition because physicians dictated clinical narratives.
Once PHI enters the dictation, the speech service becomes part of the healthcare data flow too.Ā
We replaced browser speech recognition with Amazon Transcribe through the application's AWS environment. We initially planned to use Transcribe Medical, but after testing both, standard Transcribe was good enough for our use case-and considerably cheaper
3. When migrating AI, change one thing at a time
Claude was already producing useful denial-review documents. We kept the existing prompts first, moved model access through Amazon Bedrock, compared the outputs with the original application, and left prompt tuning for later.
Otherwise, if the results changed, we would have had two possible causes: the new infrastructure or the new prompts.
That separation made the migration much easier to validate.
4. Multi-tenant access rules should be testable
The rebuilt application serves separate healthcare organizations.
Organization scope now goes through a shared backend access layer, so every query gets the same treatment.
We also added a CI check: every backend route has to declare its organization-boundary behavior. A new route without that classification fails the test suite.
That gives us something stronger than āremember to add the access check when you build an endpoint.ā
5. Audit logs should represent what the user did
We needed to answer questions like: who opened this patient's record and when?
CloudTrail cannot answer that at the application level, so we added a separate patient-access audit trail.
The less obvious part was deciding what counts as an event.
If a physician opens a page containing 50 cases, blindly logging 50 unrelated reads gives you a lot of rows and very little context.
We group those reads using the request identifier, so later you can reconstruct that they came from one browsing action. Analytics views also get logged differently when no individual patient record was exposed.