Written by James Britt
A referral has been sent, but nobody knows whether the specialist got it. Reception checks the electronic health record (EHR). A nurse searches her inbox. Another employee looks at the spreadsheet.
Consider a Ruby on Rails project built around that day-to-day problem: a referral tracker for an outpatient clinic. The proposed application would track referrals, assign follow-up tasks and show which requests still need attention. Clinical decisions would remain with qualified staff.
When selecting a health care software partner for your project you want to know more than who can develop the screens. Who is responsible for maintaining the EHR interface? Who determines why a referral is stuck? How does the firm respond if the initial developer leaves?
A contractor can certainly perform outstanding work. However, a firm stating it is a “partner” may produce a subpar system. Identify what both have committed to maintain.
Begin with a small, tangible Rails application
The first release could allow receptionists to enter referrals into a work queue, provide clinicians with a means of viewing details regarding the referral and permit employees to note when an appointment has been made. In addition, it would have to clearly indicate whether synchronization with the outpatient department’s EHR was successful.
A feasible Ruby implementation using Rails would use Rails for the application, PostgreSQL to store data and Active Job along with a persistent queue backend for background processing. Do not build multiple applications unless you have a valid rationale for doing so.
The proposed Active Record Models might consist of:
Clinic: represents the organization owning each record.StaffMembership: establishes a connection between an individual employee’s account and their permitted role within a clinic.Referral: holds the source identifier of the referral, the status of the referral through all stages of its lifecycle and identifies which employee has been designated as the point of contact for the referral.ReferralEvent: records relevant actions and changes in status.IntegrationDelivery: tracks all attempts to exchange data with the EHR.
This is an example set of naming conventions used in the design. These are not built-in Rails elements. The schema should represent how the clinic operates. Prior to establishing a status called “complete”, ask yourself what complete means. Has an appointment been scheduled? Did the consultation occur? Were results received? Those are different events.
Inspect the Ruby code
You could write the entire workflow into a single method within a controller action: update the referral, call an external interface, record an entry into the historical log and notify the employees.
While this might be sufficient for a demonstration, debugging an issue with a failed external call would likely be a very different story.
Within this project, a simple Ruby service object such as Referrals::Accept could manage the status change to the referral and record of the event within a database transaction. A separate component would interact with the EHR. The group would then be able to test the referral rules independently of any network calls.
However, there is still a problem to address. A successful database commit does not guarantee that the job was successfully placed in a background queue. One solution is to save a pending delivery in the same transaction as updating the referral. A worker could process pending deliveries, with reconciliation to catch any left behind.
Ask a potential developer to walk through that scenario. You will obtain more value from their response than from a presentation showing off slides that highlight Rails and PostgreSQL.
Bounded contracts could define the terms for developing this service and testing it. Ongoing relationships with the contractor could also provide for monitoring queues, addressing issues related to production incidents and modifying workflows based upon feedback from users. Document those responsibilities in written form.
Designate EHR integration as its own area of focus for your project
HL7 developed FHIR as an interoperability standard; it is not a privacy law. Its ServiceRequest resource can represent a referral. The application’s integration must comply with the same version of FHIR supported by the receiving system, as well as any applicable profiles and operations.
Check which operations the EHR actually supports. Access to a FHIR API does not necessarily include referral creation or updates.
In Ruby, vendor specific mapping could reside in a client class such as Ehr::ReferralClient. This class would translate the application’s data into the agreed upon external format, return an explicit result and keep vendor-specific error handling out of controllers.
What happens if the EHR accepts a request but the Rails worker never receives its response? Sending the same request again could create a duplicate.
Each distinct submission needs an unchanging identifier, documentation of delivery attempts and some means of determining if an external outcome exists. Use idempotency or conditional creation where the EHR supports an appropriate mechanism. Otherwise, unresolved deliveries need resolution as opposed to blind retry attempts.
For incoming records, enforce a database unique constraint on the appropriate combination of clinic, source system and external identifier. An Active Record uniqueness validation alone does not prevent concurrent duplicate inserts.
Both contracting models can benefit from having these as part of their acceptance criteria. There also needs to be ownership of integration when the EHR vendor modifies its interface.
Include Access Controls Within Your Acceptance Tests
Logging into an application verifies a staff member’s identity. Logging into an application does not verify which patients’ records that staff member can access.
Every referral lookup should respect the user’s authorized clinic membership and the permissions needed for the requested action. A receptionist may be capable of booking appointments without having authorization to export referral notes.
Strong parameters in Rails can restrict which attributes an action accepts. They do not replace authorization. Hiding an export link does not prevent someone from requesting the export directly.
Ask the development team to demonstrate request tests for a staff member entering an altered referral ID in the URL path, attempting to perform a forbidden export operation or submitting an alternate clinic ID. The application should reject those requests even when the user is logged in.
Background workers need the same care. Workers need to identify their intended clinic context explicitly and queue arguments must only contain what is required for execution of the task.
Review logging as well. Parameter filtering provided by Rails limits sensitive data that appears in application logs. It does not automatically exclude data from custom log messages, monitor tools or saved HTTP responses. Test those pathways with fabricated data.
Distinguish Compliance Decisions From Framework Functionality
For a US deployment, HIPAA obligations depend on the organizations involved and the information they handle. Organizations covered by HIPAA and their business associates are subject to regulations governing compliance; simply using Rails does not constitute compliance. Appropriate business associate agreements and safeguards may be required for outside services handling protected health information.
The tracker must document decisions regarding access, hosting, retention, backup, and response to incidents. Application event tables can assist in creating an audit trail; however, protection of audit trails, completeness of audit trails and retention policies remain to be created.
The FDA describes software as a medical device as software intended for medical purposes that performs those purposes without being part of a hardware medical device. Using an application within a clinical setting does not inherently determine whether or not it is regulated.
The administrative coordination described here is within the scope of this proposed tracker. Adding diagnostic recommendations or automated clinical prioritization would require reassessing its intended use and regulatory position before those features proceed.
The provider must bring up this topic when there are changes in scope. The designation as a “partner” offers no assurances regarding future cooperation.
Test The Awkward Scenarios Prior To Launch
A passing test suite is useful only if it covers the failures that matter.
For this Rails project, consider including scenarios that involve:
- The EHR accepts a referral request but never returns its response to the Rails worker.
- Two workers process the same delivery attempt.
- Staff alter an appointment while its reminder is waiting in the background queue.
The last item is often overlooked. Before sending out reminders, jobs should re-check the current appointment and applicable patient communication permissions. Information that was correct when the job was queued may have changed before it runs.
Utilize Minitest or RSpec to depict behavior of your application utilizing synthetic fixtures or factories. Keep real patient information out of test data and recorded HTTP interactions.
Employees should try using the workflow as well. Are they able to differentiate between referrals awaiting clinical review versus referrals unable to synchronize? Who receives alerts regarding failures? What is mutually agreed upon protocol for outages?
These are questions that should be resolved prior to finalizing the design while both developers and clinical staff can collaborate.
Define Maintenance And Handoff In Agreement
Your tracker will require maintenance after deployment. Ruby and Rails dependencies need maintenance, database migrations need planning, and EHR credentials or interfaces may change.
Ongoing engagements should detail who monitors failed jobs, reviews security patches, and assesses recovery from backup systems. Detail response expectations, out-of-hours coverage and escalation procedures. Leave nothing ambiguous regarding “support.”
Contractor engagements should detail hand-off equally as thoroughly. The clinical facility will require repository access, deployment scripts, dependency versions, integration maps, and known constraints. Transfer secrets through an approved secret management process versus embedding secrets in documents.
Keeping experienced team members involved can help with handover, but the clinic should not depend on one engineer. Have another developer follow the deployment and recovery instructions. Missing steps are easier to fix before the person who knows them leaves.
Select Engagement Based Upon Work
Ruby contractors skilled at building imports, improving performance on slow Active Record queries, and incorporating authorization tests into existing applications can be beneficial depending upon what is desired by the clinical facility. This arrangement is suitable if internal personnel within an organization retain possession of surrounding systems and can ultimately take over responsibilities after completion of development efforts.
An ongoing engagement may prove more suitable if clinical facilities require assistance with workflow revisions; production incidents; and long-term maintenance of integrations. Regardless of which arrangement you select compare proposals based upon identical practical questions. Who responds when a stalled delivery attempt occurs? Who authorizes revised workflows concerning referrals? Who ensures continued support for your application after deployment?
For this Ruby on Rails project, those answers tell the clinic more than the word “partner” on a proposal.
