Form submission altering the patient enrollment date

hello @jkuester

We encountered an issue where the submitting of a particular report on a patient alters their enrollment date ie when a patient changes their phone number in CHT by filling out the using phone capture form ie

it ends up altering their enrolment dates to the date phone numbers were changed which is wrong .
Any thoughts on why ?

I think I will need to know more about your setup before I can have a clear idea of why this might be happening.

  • Is the phone number being stored on the patient’s contact document? Or, is it coming from the contact summary? Or is it on a registration app form?
  • How are you editing the phone number? If it is on the contact document, then how does the value on the contact document actually get updated? Is the “phone capture form” just a contact-edit form for the patient contact? Or are you editing the original registration app form doc?
  • What do you mean by “their enrollment dates”? Is this a value stored on the contact doc or calculated in the contact summary? Or is it some field set on the registration doc?

In the past I have seen unexpected behavior happen for calculated fields on edit forms (where the field is “re-calculated” when the contact/report is edited). In that case it was enough to use the coalesce function to simply not re-calculate the field value if it already has a value.

thanks @jkuester yes

the phone capture form is just a contact-edit form for the patient contact , i have also granted you access to the form

I had a look at the Phone Number Capture form that you shared with me, but unfortuanly, I am not sure I understand how that form is supposed to update the contact doc. Specifically, it seems like the form is loading the initial data from inputs/contact which would indicate this is actually an app form and not a contact form (based on the available inputs data).

Unfortunatly, while the CHT supports adding new docs and loading read-only data from an app form, there is no support for editing a contact in an app form. That can only be done in a contact edit form.

1 Like

thanks @jkuester for your detailed feedback …

I noticed that there is an outbound config push that runs every time this form is submitted having the details of the new phone number, which then starts a flow to PUT or POST to CHT api to update the contact document.

@jkuester I haven’t yet looked at the rapidpro configs but would like to ask if this is the api being used to update the contact phone number ?

I noticed that there is an outbound config push that runs every time this form is submitted

Ahh, yes! That might explain some things.

I haven’t yet looked at the rapidpro configs but would like to ask if this is the api being used to update the contact phone number ?

You should check your RapidPro config to be sure of exactly what it is doing, but I am pretty sure that endpoint is read-only. (Somewhat confusing since it accepts a POST, but I think that is just for sending the phone number to search for…)

Instead, I would think the POST /api/v1/people endpoint would be what you should use to update a person’s contact doc.

1 Like

thanks @jkuester , going to check this out in rapidpro

hello @jkuester
i noticed that they are posting the body of

{
  "urns": [ "@trigger.params.new_phone_number" ]
}

to https://<domain-name>/api/v2/contacts.json?uuid=@contact.uuid in the webhook.
@jkuester Am not seeing this endpoint in the api docs

:thinking: I believe that url path is actually for the RapidPro server and not the CHT api.

1 Like

thanks @jkuester …
I wanted to share with you the genesis i have received from the implementers of the reason for this form below …

  • ART patients may change their phone numbers during the course of follow-up.

  • The 2wT system should capture the new phone number while preserving the old number in the patient record. Ideally, the previous number should be voided, but retained for linkage purposes. Both the old number and associated time frame data should be used to connect messages from the Africa’s Talking platform to the 2wT data. The phone number capture feature should prevent duplicate entries of the same number.

  • Currently, when a phone number is updated through the form, the enrolment date is incorrectly changed to the date of the new number capture.

@jkuester @mrjones @diana any thoughts on the feasibilty of this ?

I am afraid I cannot be much help with troubleshooting the 2wT side of the system. I am not super familiar with RapidPro.

It is still not clear to me how the new phone number is getting entered into the CHT system. Is there an automated hook in RapidPro that is calling some CHT api? Your original screenshot shows a “Phone Number Capture” form which makes me think that maybe the phone number update is a manual process. If that is true, I think my previous comments still apply. Only contact edit forms can update data on a contact.

thanks @jkuester for your feedback

the submitting of the “Phone Number Capture” form triggers this outbound config below to run

"phone number capture workflow": {
            "relevant_to": "doc.type === 'data_record' && doc.form === 'phone_number_capture'",
            "destination": {
                "base_url": "https://<domain_name>",
                "auth": {
                    "type": "header",
                    "name": "Authorization",
                    "value_key": "rapidpro.app"
                },
                "path": "/api/v2/flow_starts.json"
            },
            "mapping": {
                "flow": {
                    "expr": "'436a229e-623c-41d2-9b48-1449b8e70dba'"
                },
                "contacts": {
                    "expr": "[ doc.fields.rapidpro.uuid ]"
                },
                "extra.new_phone_number": {
                    "expr": "'tel:' + doc.fields.new_phone_number",
                    "optional": false
                }
            }
        }

which posts the body of

{
  "urns": [ "@trigger.params.new_phone_number" ]
}

to https://<domain-name>/api/v2/contacts.json?uuid=@contact.uuid in the webhook in rapidpro.

:+1: Got it. So submitting that form should cause the patient’s phone number to be updated in RapidPro (which I guess is maintaining its own contact dataset). As far as I can tell, this should not cause the CHT contact doc to be updated with the new phone number. This might be fine (as long as RapidPro is the only thing that uses the phone number and it is no problem considering RapidPro as the source of truth for the patient phone numbers.)

This brings us back around to some question’s I had above about the"enrollment date" that is getting updated:

thanks alot @jkuester this is calculated in the contact-summary

if (thisContact.role === 'patient') {
    console.log(thisContact);
    latestVisitReport = getNewestReport(reports, ['appointment_date_rescheduled']);
    if (thisContact.rapidpro && thisContact.rapidpro.visit_date) {
        nextVisitDate = thisContact.rapidpro.visit_date;
    }
}

const cards = [
    {
        label: 'Schedules',
        appliesToType: ['person'],
        appliesIf: isPatient,
        fields: function () {
            const fields = [];

            fields.push(
                { label: 'Enrollment_date', value: thisContact.reported_date, filter: 'date', width: 6 }
            );

            if (nextVisitDate) {
                fields.push({ label: 'Next appointment (EMRs)', value: nextVisitDate, filter: 'date', width: 6 });
            }

            if (latestVisitReport && latestVisitReport.fields.n.new_date) {
                fields.push({ label: 'Next appointment (patient request)', value: latestVisitReport.fields.n.new_date, filter: 'date', width: 6 });
            }

            return fields;
        },
        modifyContext: function (ctx) {
            if (latestVisitReport && latestVisitReport.fields.n.new_date) {
                ctx.current_visit_date = new Date(latestVisitReport.fields.n.new_date).toLocaleString('en-US', { month: 'long', year: 'numeric', day: '2-digit' });
                if (nextVisitDate && new Date(nextVisitDate) > new Date(latestVisitReport.fields.n.new_date)) {
                    ctx.current_visit_date = new Date(nextVisitDate).toLocaleString('en-US', { month: 'long', year: 'numeric', day: '2-digit' });
                }
            } else if (nextVisitDate) {
                ctx.current_visit_date = new Date(nextVisitDate).toLocaleString('en-US', { month: 'long', year: 'numeric', day: '2-digit' });
            } 
        }
    }
];

hello @jkuester any more thoughts on this ?

Sorry! Somehow I missed the notification about your previous message.

{ label: 'Enrollment_date', value: thisContact.reported_date, filter: 'date', width: 6 }

Okay so the “Enrollment Date” is just the reported_date for your contact. This is good and bad. It is good because semantically that seems like the correct value to use. It is one guaranteed by the system to exist.

The bad thing is that this does not get us any closer to understanding what is going on here. The reported_date gets set automatically when creating a new contact. Then it should never be updated (even when editing the contact).

I think we need to back up a bit and go through your workflow/behavior in more detail since there is still something I am missing here. This is how I understand things to be based on what you have noted above:

  • When you create a new patient and view their profile page, you see the “Enrollment Date” field on the profile page display the date the patient was created.
  • Then, later you submit a “Phone Number Capture” form. This form triggers an outbound hook to send the given phone number to RapidPro.
  • Now, if you go back to the patient’s profile page in the CHT, you see the “Enrollment Date” field displaying the current data value (instead of the date the patient was created).

Is this depiction of events accurate? Am I missing any steps? Also, with all this in mind, I have several new questions:

  1. Is this reproducible? (Does it always happen for all users/contacts? Is it just sometimes? Is it just for some users/contacts?)
  2. Can you check the contact’s reported_date before and after submitting the “Phone Number Capture” form and confirm it is actually being updated to a new value?
  3. Does the phone field on the contact doc get updated at all as a result of this process?
1 Like

thanks @jkuester you are right about the workflow, in the screenshot below the date for the enrollment date switches to the date when the phone number capture form is submitted yet the client was enrolled 2 years back

  1. It does happen for all contacts where the form is submitted
  2. The contact’s reported_date is updated to reflect the date when the form is submitted
  3. Yes the phone field on the contact doc gets updated at all as a result of this process

For the contact in the screenshot below, i have shared to you in DM the contact_doc plus the phone_number_capture doc

Okay, thanks for the additional data. One thing that is interesting to me right away is that the reported_date for the contact is <1sec after the reported_date for the report. The date values are so close, but not exactly the same.

Do you know if there is some sort of external service running that might be automatically pushing changes back into the CHT? If not, we may need to check the audit log in HA Proxy and try to figure out if something is POSTing a new version of the contact doc straight into Couch…

thanks @jkuester

well there is integration code that runs in a nightly job to always update the Patient Art_outcome and Next Appointment date respectively …
How can i retrieve the full audit log for HA Proxy ,?