Access to Remote Care - Important Changes to OHIP

Among the many planned changes to Ontario's health care system, something that we think deserves particular attention are the changes that will negatively affect how many new family physicians will be able to provide care to patients.

It’s important to understand that existing Magenta Health patients will likely not be affected by these changes, but we nevertheless ask you to consider the issues presented below and to voice any concerns with the planned changes. A few suggestions for how to do so are provided towards the bottom of this post.

While there are many changes, in our view, the key change is that OHIP will largely return to only covering in-person visits with new family physicians. This nuance is one of the primary reasons why family doctors traditionally did not provide medical care for patients by telephone or by email.

As a clinic that emphasizes using technology to care for patients in a timely, convenient, effective, and efficient way, this change is in direct opposition to how we think family medicine should be practiced in this day and age.

Put in more concrete terms, the planned changes will prevent many future family physicians from providing:

  • Medical advice by email or telephone;
  • Telephone or other remote appointments;
  • Prescription renewals by fax or phone;
  • Lab results by email or telephone; and
  • Lab and imaging requisitions by email or fax.

Other negative effects include increasing the functional cost of medical care by forcing patients to take time off work or school, and requiring patients to travel for medical care. The effects of these changes on low-income or other disadvantaged groups is particularly troubling; consider, for example, the impact of this change on caregivers with dependents or individuals with mobility challenges.

Even if these changes likely don’t directly impact existing Magenta Health physicians and patients, we believe these planned changes are the wrong approach for Ontario’s health care system, and that it’s important to voice our concerns in this respect.

Should you agree, some steps that you can take include:

  • Visiting this website to contact your MPP and to share your thoughts on this issue (there’s a pre-written letter that you can send);
  • Calling your MPP to express your concerns;
  • Sharing, posting, and tweeting this blog post with your friends and family.

We’ll continue to keep you advised of the impact of these changes.

Protecting Patient Privacy - Doing it Right

We previously shared this post about the wrong way of protecting patient privacy where we were sent an encrypted file together with the password.

In contrast to this previous failure, we recently received another DVD a couple days ago, again with an encrypted file, but this time, with instructions to contact the medical office directly by phone to obtain the password.  Presumably they will verify our identity and authorization before providing us the password to the file.

Since it's the weekend and their office is closed, it occurred to us that we could try breaking the encryption on the file, instead of waiting until next Tuesday to get the password.

We therefore downloaded John the Ripper, an open source password cracker, followed these instructions, and set a modern desktop (a quad-core i7 with 16GB ram) to work. 

The consequence? 0.01% of all possible passwords were tested in 24 hours, meaning it would take 100 days to test 1% of all possible passwords, 1000 days to test 10% of all possible passwords, or 10000 days to test all possible passwords.

While in theory we could speed up the process by using faster or more computers (e.g. by spinning up a large number of cloud-based servers), we'll just call the medical office on Tuesday to get the password instead of leaving our computer to guess passwords for the next 15 years.

The takeaway?  Encryption, while not absolutely fool-proof, is an important tool to protect patient privacy. It just needs to be used correctly(*).

* For the cryptography experts out there, yes, we do know that there are better methods of key exchange than having us call our counter-party medical office for the secret key. Public-key cryptography is the better answer, without a doubt. Perhaps we'll start including our public key in our requests for patient health information and see how long it takes before another medical office actually uses it to encrypt the information. ;)



A Peek Behind the Curtain - Software in the Making

One of the reasons we started Magenta Health is because of our belief in technology. Sometimes we buy or license what we need (E.g. OSCAR, Veribook), but sometimes we build from scratch what we can't buy.

In particular, we're about to deploy a new system that we're building for helping streamline the day-to-day operations of the clinic. It's been a lot of work, but it's incredibly satisfying to see our original vision come to life feature by feature, line of code by line of code.

We'll share more details once it's fully ready, but in the meantime, here's a sneak peek of the system in testing.  For patients who have asked, this is the reason why we have outlets and tablets outside every examination room!

Stay tuned!

The system in testing

The system in testing

Lists upon lists upon lists of features and bugs.   We're using Trello, which we love.

Lists upon lists upon lists of features and bugs.   We're using Trello, which we love.

Why large multiple monitors are so important for working effectively.  

Why large multiple monitors are so important for working effectively.  

Additional after-hours appointments

As our number of family doctors has grown, we are expanding our after-hours coverage to provide better access for our patients.  

Starting February 2015, Magenta Health will be offering additional after-hours appointments on Saturdays from 10:00 AM to 1:00 PM.  As with before, these appointment times are for urgent matters only.  

Learn more about our clinic hours here.  More information on how to book an appointment using our online booking tool can be found here

Using Greasemonkey to Resize Windows in OSCAR

We've been asked for our script for resizing windows within OSCAR, it's provided below for reference.

Some tweaking of the script will unfortunately be necessary to match your specific needs.

Lots more information about using Greasemonkey to customize OSCAR is available here.

window.addEventListener('load', function () {
var url = document.URL;
//move these windows to the left half of the screen
if (url.indexOf('efmformadd_data.jsp') != - 1 || //new eform
url.indexOf('oscarEncounter/ViewRequest.do') != - 1 || // viewing consultation
url.indexOf('oscarEncounter/ViewConsultation.do') != - 1 || // viewing all consultation
url.indexOf('oscarEncounter/oscarConsultationRequest') != -1 || //viewing all consultations
url.indexOf('efmshowform_data.jsp') != - 1 || //existing eform
url.indexOf('oscarPrevention/index.jsp') != - 1 || //preventions
url.indexOf('oscarPrevention/AddPreventionData.jsp') != -1 || //preventions
url.indexOf('efmformslistadd.jsp') != - 1 || //eform list
url.indexOf('inboxManage.do') != - 1 || //inbox
url.indexOf('oscarRx') != - 1 || //rx
url.indexOf('demographic/demographiccontrol.jsp') != -1 || //demographic
url.indexOf('Oscar12_1/form') != - 1 || //forms
url.indexOf('dms/MultiPageDocDisplay.jsp') != -1 || //documents
url.indexOf('dms/showDocument.jsp') != - 1 || //documents
url.indexOf('labDisplay.jsp') != - 1//labs
 ) {
moveLeft(false);
}

//move these windows to the upperleft of the screen
if (url.indexOf('Oscar12_1/tickler/ticklerMain') != - 1 //viewing all ticklers 
 ) {
moveUpperLeft(false);
}

//move these windows to the lowerleft of the screen
if (url.indexOf('Oscar12_1/tickler/ticklerEdit.jsp') != - 1 || //individual tickler 
url.indexOf('Oscar12_1/tickler/ForwardDemographicTickler.do') != - 1 || //individual tickler when adding from inbox
url.indexOf('Oscar12_1/tickler/ticklerAdd.jsp') != - 1 //individual tickler when adding from list of ticklers
 ) {
moveLowerLeft(false);
}

//move these windows to the right of the screen, and refresh the window
if (url.indexOf('casemgmt/forward.jsp?action=view&demographicNo=') != - 1 //echart 
 ) {
moveRight(true); 
}
}, false);

function moveRight(refresh){
window.resizeTo(screen.width / 2, screen.height - 40);
if (refresh && (window.screenX - (screen.width / 2) > 2 || window.screenX - (screen.width / 2) < -2)){ //doing it this way because of rounding issues, just want to reload if not close to right spot.
location.reload();
}
window.moveTo(screen.width / 2, 0);
window.focus();
}

function moveLeft(refresh){
window.resizeTo(screen.width / 2, screen.height - 40);
if (refresh && window.screenX != 0){
location.reload();
}
window.moveTo(0, 0);
window.focus();
}

function moveUpperLeft(refresh){
window.resizeTo(screen.width / 2, (screen.height - 40)/2);
if (refresh && window.screenX != 0){
location.reload();
}
window.moveTo(0, 0);
window.focus();
}

function moveLowerLeft(refresh){
window.resizeTo(screen.width / 2, (screen.height - 40)/2);
if (refresh && window.screenX != 0){
location.reload();
}
window.moveTo(0, (screen.height - 40)/2);
window.focus();
}

Protecting Patient Privacy - Points for Effort

It's a difficult time for health care providers to practice, given the constant changes in computer technology, patient requests, and government regulations.

One particular difficulty relates to how sometimes it's easy to miss the forest for the trees when it comes to IT security, as in this DVD that we recently received from a third-party wherein the password for decrypting the files stored on the DVD was simply written on the DVD itself.

For context, Magenta Health physicians commonly request the medical records of patients from former physicians and health care facilities.  Once we send this request off, the requested documents are sent to us via various means such as fax, mail, flash drives, or DVD.

Particularly when physically mailing information, there is a risk of the package being misdirected, and accordingly, if the information is being mailed on physical media such as a DVD or flash drive, it will sometimes be encrypted.  In theory, this is a great idea, although it raises the issue of how to convey to us the password to decrypt the information.  There's no perfect answer, but what is commonly done is that the password and the information will be sent separately. This is similar to how, for example, banks send credit card PINs separate from the credit card itself.

Where this breaks down is if the password is sent together with the information, as in the image above.  In these circumstances, the entire purpose of encrypting the information on the DVD (to protect it from inadvertent disclosure) is defeated since anyone who happens across the DVD would be able to readily access the information.

Suffice it to say, this is an example of why we think it's always important to take a step back and think about, in practical terms, why a particular measure or precaution is being taken, and to evaluate whether it's being deployed and utilized correctly.

OSCAR EMR + Greasemonkey = Amazing Customizability

As users, we all gripe about software and how software is "poorly designed" or "hard to use". In practice, there's usually a good reason, whether it's legacy code that can't be easily rewritten, or the simple fact that a single piece of software needs to meet the needs of diverse individuals with different requirements.

Accordingly, one of the advantages of OSCAR EMR, the electronic medical record system that we've selected as a platform for our organization, is that it is highly customizable and so we can adapt it to meet our organization's unique needs.  (This is not to say that we're the only organization with unique needs - the fundamental issue is that every organization will have unique needs and the challenge when it comes to procuring software is finding the right software for you.)

One particular advantageous aspect of OSCAR is that it is built as a web application, and as a result, common web tools can be used to adapt and customize OSCAR.  One particular tool is called Greasemonkey - a Firefox extension that enables users to dynamically insert javascript into webpages.  A whole slew of scripts have already been developed by OSCAR community members, but we've been writing a few of our own to resolve certain issues that our physicians or staff complain about.  Hopefully the below can help other OSCAR users down the road, whether as inspiration, or as a starting point for your own scripts.  There may be errors though we warn; everything remains a work in progress and we are constantly revising.

  • Resizing most windows to a consistent spot in the screen.  For example, the echart is automatically moved and resized to the right half of the screen, whereas eforms, consults, ticklers, forms, preventions, Rxs, etc... are moved/resized to the left half of the screen.  Just adapt the code below as required.
if (url.indexOf('labDisplay.jsp') != - 1) {
window.moveTo(0, 0);
window.resizeTo(screen.width / 2, screen.height - 40);
}
  • Making more of the patient's name show up in the scheduling screen.   Our receptionists were having trouble because the patient's name was being truncated
if (url.indexOf('provider/providercontrol.jsp') != - 1) {

var links = document.evaluate("//a[contains(@class,'apptLink')]",document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);

for (var j =0 ;j < links.snapshotLength; j++){

var thisLink = links.snapshotItem(j);

thisLink.innerHTML = thisLink.title.split("reason:")[0].trim();

}

}
  • Making it so that when the "tickler" link is clicked from the calendar view, a report of the user's ticklers is automatically run
//changing tickler link so that providerNum is passed in when tickler link clicked
if (url.indexOf('provider/providercontrol.jsp') != - 1) {
var tareas = document.getElementsByTagName('a'); 
var providerNum;
for (var i = 0;i <tareas.length; i++){ 
if (tareas[i].title=="View lab reports"){
var onclickValue = tareas[i].getAttribute('onclick');
 providerNum = onclickValue.substr(79,3); 
}
}

for (var i = 0;i <tareas.length; i++){ 
if (tareas[i].title=="Tickler"){
var onclickValue = tareas[i].getAttribute('onclick');
var split = onclickValue.split(',');
var newStr = split[0].substring(0,38) + "?customProviderNum=" + providerNum + "'," +split[1]; 
tareas[i].setAttribute('onclick',newStr);
}
}
}

//automatically running report of relevant ticklers
if (url.indexOf('Oscar12_1/tickler/ticklerMain.jsp?customProviderNum') != - 1) { 
var provider = getUrlParameters("customProviderNum","",true);
if (provider){ 
 var assignedTo = document.getElementsByName('assignedTo')[0];
 for (var i=0; i<assignedTo.length; i++){
if (assignedTo.options[i].value == provider){
 assignedTo.selectedIndex = i;
}
 }
 eval("document.forms['serviceform'].Submit.value='Create Report'; document.forms['serviceform'].submit();");
} 
}
  • changing the functionality of the ticklers in the echart so that a) if viewTicklers is clicked, a report of all completed ticklers is displayed, and b) if a particular active tickler is clicked, then the corresponding tickler in editable form is opened.

//echart to rewrite the tickler links
if (url.indexOf('Oscar12_1/casemgmt/forward.jsp') != -1){
setTimeout(redirectTicklers,3000);
}

//to simulate clicking on correct tickler edit button if certain parameters passed
if (url.indexOf('CustomTicklerTitle') != -1 && url.indexOf('tickler/ticklerMain.jsp') != -1){ 
var pN = getUrlParameters("CustomPatientName","",true);
var tT = getUrlParameters("CustomTicklerTitle","",true); 
var trs = document.getElementById('sortableTable0').getElementsByTagName('tr'); 

for (var i= 0;i < trs.length; i++){
if (trs[i].textContent.indexOf(pN.split(", ")[0] + "," + pN.split(", ")[1])!=-1 && trs[i].textContent.indexOf(tT) != -1){
var tds = trs[i].getElementsByTagName('td');
tds[1].childNodes[0].click();
window.close();
}
}
}

//to delete all ticklers except for those related to a particular patient
if (url.indexOf('CustomShowAllForPatient') != -1 && url.indexOf('tickler/ticklerMain.jsp') != -1){
var mainPatientName = getUrlParameters("CustomShowAllForPatient","",true);
var trs = document.getElementById('sortableTable0').getElementsByTagName('tr'); 
var markDelete = new Array(trs.length);
var mostRecentPatientName = "";
for (var i= 2;i < trs.length; i++){if (trs[i].childNodes[1].childNodes.length > 0){mostRecentPatientName = trs[i].childNodes[5].textContent.trim(); } 
if (mostRecentPatientName.indexOf(mainPatientName.split(", ")[0] + "," + mainPatientName.split(", ")[1])==-1){ 
 markDelete[i] = true;
}else {
markDelete[i] = false;
}
markDelete[0] = false;
markDelete[1] = false;
} 
for (i = trs.length-1; i>=2; i--){
if (markDelete[i]){
trs[i].parentElement.removeChild(trs[i]);
}
}
}

function redirectTicklers(){
var tareas = document.getElementsByTagName('a'); 
var patientName;
for (var i = 0;i <tareas.length; i++){ 
var title = tareas[i].title;
if (title == "Master File"){ 
 patientName = tareas[i].textContent;
i = tareas.length;
}
}

for ( i = 0;i <tareas.length; i++){ 
var onclickvalue = tareas[i].getAttribute('onclick'); 
var ticklerTitle;
var ticklerDate; 
if (onclickvalue != null){
 if (onclickvalue.indexOf("ticklerDemoMain") != -1 && onclickvalue.indexOf("ViewTickler") == -1){ 
 var ticklerTitle = tareas[i].title.split("...")[0].trim(); 
 var ticklerDate = tareas[i].title.split("...")[1].trim(); 
var newStr = "window.open('../tickler/ticklerMain.jsp?xml_vdate=1900-01-01&xml_appointment_date=8888-12-31&ticklerview=A&mrpview=all&providerview=all&assignedTo=all&Submit=Create+Report";
newStr += "&CustomPatientName=" +encodeURIComponent(patientName);
newStr += "&CustomTicklerTitle=" +encodeURIComponent(ticklerTitle);
newStr += "&CustomTicklerDate=" +encodeURIComponent(ticklerDate);
newStr += "','MagentaCustom','height=100,width=100');return false;"; 
tareas[i].setAttribute('onclick',newStr);
} else if (onclickvalue.indexOf("ticklerDemoMain") != -1 && onclickvalue.indexOf("ViewTickler") != -1){ 
var newStr = "window.open('../tickler/ticklerMain.jsp?xml_vdate=1900-01-01&xml_appointment_date=8888-12-31&ticklerview=C&mrpview=all&providerview=all&assignedTo=all&Submit=Create+Report";
newStr += "&CustomShowAllForPatient=" +encodeURIComponent(patientName);
newStr += "','MagentaCustom2','height=100,width=100');return false;"; 
tareas[i].setAttribute('onclick',newStr);
}
}
}
}
//helper function
function getUrlParameters(parameter, staticURL, decode){
 /*
Function: getUrlParameters
Description: Get the value of URL parameters either from
 current URL or static URL
Author: Tirumal
URL: www.code-tricks.com
 */

 var currLocation = (staticURL.length)? staticURL : window.location.search,
 parArr = currLocation.split("?")[1].split("&"),
 returnBool = true;

 for(var i = 0; i < parArr.length; i++){
parr = parArr[i].split("=");
if(parr[0] == parameter){
return (decode) ? decodeURIComponent(parr[1]) : parr[1];
returnBool = true;
}else{
returnBool = false; 
}
 }
 if(!returnBool) return false; 
}

Online Booking Walkthrough - Regular Appointments

Patients occasionally aren't quite sure how to book appointments (including regular, urgent, and physical health exams) with their physician. This post will walk through the steps with screenshots exemplifying what to do and where to click.

Step 1 - The first step is always to have a new patient intake appointment with your physician. Only once you've had this appointment will you be provided by email a link to book subsequent follow-up appointments with your doctor. Please bookmark the link for future reference although this search tool is available if you have lost the link.

Step 2 - When you wish to book a regular appointment with your physician, access the link provided to you.  You'll be taken to a page similar to the following:

Step 3 - Towards the bottom, you will be presented with a number of different appointment types. These will differ from physician to physician.  Select the type of appointment that is appropriate for your circumstances.  In most circumstances, "Regular Visit" will be the correct choice.  

Step 4 - Once you select from the options, the webpage will display a booking form such as the below:

Step 5 - Use the booking form to book your appointment.  You'll need to choose a date and time for your appointment, and also complete the form questions.  A completed form appears as follows.  

Step 8 - Once you've completed the form, click the "Send request" button.  A login screen will appear, such as the following. Type in the email address that you had previously selected when creating your booking account (see step 9 of this walkthrough) and your password.

Step 9 - Once you enter your credentials, click "Login".  Your booking will proceed, and you will be displayed a green confirmation box as follows:

You'll also receive an email confirmation to the email address that you provided the first time you used the username (see step 9 of this walkthrough).

Online Booking Walkthrough - New Patient Intake Appointment

Patients occasionally aren't quite sure how to book their new patient intake appointment.  This post will walk through the steps with screenshots exemplifying what to do and where to click.

Step 1 - The first step is always to register here.  Only after a patient registers will they receive by email a link to book a new patient intake appointment with a particular doctor. This email will have the subject "Magenta Health - Invitation for Scheduling Patient Intake Appointment"

Step 2 - Once you receive the email, read through the email, and there will be a section that states the following:

With this in mind, you have been assigned to [doctor] and new patient intake appointments can now be scheduled, as follows:

1. Visit the following link: [link]

2. You will need to register for an account as part of the booking workflow....

Step 3 - Click on the link provided, and you'll be taken to a page that appears similar to the below:

Step 4 - There's a bit of overlap with the invitation email, but we strongly recommend that you read through this webpage carefully.

Step 5 - If you're ready to schedule your appointment, look towards the bottom of the page. It first asks you how many family members, including yourself, you are booking for.  If you're booking for just yourself, select 1, if you're booking for you and a spouse, select 2, if you're booking for yourself and two children, select 3, etc...

Step 6 - Once you select from the options, the webpage will display a booking form such as the below:

Step 7 - Use the booking form to book your appointment.  You'll need to choose a date and time for your appointment, and also complete the form questions and check off the required check-boxes.  A completed form appears as follows:

Step 8 - Once you've completed the form, click the "Send request" button.  A login screen will appear where you can choose the option "Create an Account".  

Step 9 - Once you have clicked on "Create an Account", you'll need to provide a "Display Name", password and email address of your choosing then click the "Register" button. This process provides you with an appointment booking account which you can use for all future bookings.  Please note that in the future you will be able to use your email address to login.

Step 10 - After you have properly created an account, you will be displayed a green confirmation box as follows:

You'll also receive an email confirmation to the email address that you provided at Step 9.