Code Monkey home page Code Monkey logo

redcap_oncore_client's Introduction

REDCap OnCore Client

This REDCap external module provides integration with Forte Research's OnCore. It allows REDCap project builders to associate a REDCap project with an OnCore protocol and import enrollment data into REDCap. It also allows users to select protocols via either the SIP interface or UF's OCR API, and read protocol data from OnCore via the SOAP API.

Current Limitations

  • Mapped fields are best configured as text fields with no validation in your REDCap project to prevent synchronization failures on that project.

Prerequisites

The UF OCR API for OnCore, https://github.com/UF-OCR/ocr-api, is recommended as it can provide access to protocols that are not yet enrolling. This allows configuration and testing before a protocol starts enrolling subjects. The ocr-api must be deployed as a service within the OnCore infrastructure. For details on how to do this see https://github.com/UF-OCR/ocr-api.

Easy installation

  • Install the REDCap Entity module from the Consortium REDCap Repo from the control center.
  • Install the REDCap OnCore Client module from the Consortium REDCap Repo from the control center.
  • Go to Control Center > External Modules, enable REDCap Entity, and then OnCore Client. REDCap Entity will be enabled globally, but the OnCore client has to be enabled on a per-project basis after Global Configuration is completed.

Manual Installation

  • Clone this repo into to <redcap-root>/modules/redcap_oncore_client_v0.0.0.
  • Clone redcap_entity repo into <redcap-root>/modules/redcap_entity_v0.0.0.
  • Go to Control Center > External Modules, enable REDCap Entity, and then OnCore Client. REDCap Entity will be enabled globally, but the OnCore client has to be enabled on a per-project basis after Global Configuration is completed.

Global Configuration

Go to Control Center > External Modules, click on OnCore Client's configure button, and fill the configuration form with your credentials and other details. Contact your site's OnCore team to get the URLs, usernames and passwords required to configure this module.

  • WSDL: The OnCore WSDL URL, e.g. https://example.edu/opas/OpasService?wsdl
  • Login: Your OnCore client user ID
  • Password: Your OnCore client password
  • Protocol lookup method: The method through which protocols are acquired from OnCore (SIP or UF OCR API) - one of these is required to associate projects with protocols
  • SIP URL: The URL of OnCore SIP (Study Information Portal), e.g. https://example.edu/sip/SIPMain. Returns only protocols open to enrollment
  • OCR API URL: The URL of UF OCR OnCore API (Application Programming Interface), e.g. https://example.edu/ocr/api/protocols. Returns all protocols, requires UF OCR API credentials
    • OCR API Username: Your UF OCR OnCore API user name
    • OCR API Key: Your UF OCR OnCore API key
  • Log requests: Check this field to log all API requests (see Logs Page section) - this is useful for development purposes and testing
  • Store User Institution IDs in REDCap User Attributes or Entity database?: The Oncore client needs a user's Institutional ID to identify them in OnCore data. Choose whether this data will be stored in and read from REDCap's built-in attribute or in a side table managed by REDCap Entity.
  • Auto-populate Institution ID from server?: If you use an authentication mechanism that provides the institutional ID in a server environment variable, the OnCore Client can automatically write that value to the lookup tables it uses to verify access. Note that this feature will overwrite the storage location selected in Store User Institution IDs in REDCap User Attributes or Entity database?.
  • Name of server variable used to populate Institution ID: If you use the Auto-populate Institution ID from server? feature, name the variable that holds the Institution ID here.

Config form

Institutional IDs

The REDCap OnCore Client displays enrollment data only to REDCap users who are on OnCore's list of protocol staff. To do this, it reads the protocol staff list from OnCore and compares the institional ID of the logged-in REDCap user against the institional ID field in the OnCore study staff data. If there is a match, it displays the enrollees, otherwise it hides them. Note that REDCap super-users can always see the list of enrollees.

To do the comparison, REDCap needs to know the institutional ID for the logged-in user. If you use an authentication mechanism that provides the institutional ID in a server environment variable, the OnCore Client can automatically write that value to the lookup tables it uses to verify access. Sites that use Shibboleth or LDAP for authentication are likely to have this functionality, but its implementation is site-specific. Whether your site provides an institutional for successfully-authenticated staff and what variable would hold that value are questions for your site's system staff.

Additionally, admins can configure the storage location the OnCore Client will use for the institutional ID. It can be read from REDCap's Institution ID field of the User Attributes or from a side table managed by the OnCore Client via REDCap Entity. If you already have the correct data in the REDCap User Attributes, just use that field. If you have other data in REDCap User Attributes, use the Entity database to store the Institutional ID. The auto-population feature can populate which every storage location you choose.

If you are not using the auto-population feature, you will need to provide that ID for each user to allow them to access the protocol data. If you chose to store the Institution ID in the REDCap User Attributes, simply update that page. If you chose to use the Entity database, set the Institutional ID at Control Center > Enter User Institution IDs. Users will only be allowed to access protocol subject data if OnCore lists them as currently active staff on a protocol or if they have Super User privileges.

Note that the institutional ID used on your site's OnCore system is a site-specific decision. It could be the same ID as the REDCap username or some other ID unique to each staff member. Ask your OnCore team which person identifier they store in the institutional ID field.

Project level configuration

If you already set a valid SIP URL or API credentials, you may associate a project with a protocol.

To do that, access the External Modules section of your project, make sure OnCore Client is enabled, and then click on its configure button.

Protocol association

On this page you must select a protocol, check at least one enrollment status, the event to map on and the REDCap field name where the OnCore PrimaryIdentifier will be stored. You have the option of mapping other OnCore demographic fields to REDCap fields as well.

When specifying the field mapping, we strongly recommend you only map fields OnCore Fields to REDCap fields that are defined as free text fields with no validation. If you do map OnCore fields to REDCap fields that use validation, the OnCore data must match the REDCap validaiton rules precisely. Failing to do so will cause records to not synchronize and you will be notified of the fields causing conflict. Documenting the OnCore field encoding is outside the scope of this document at this time.

All that said, there is bug in the OnCore API that returns the ethnicity as a coded value instead of the human-friendly label. These are the codes returned from Oncore and their corresponding labels:

Code Description
3163 Hispanic or Latino
3164 Non-Hispanic
15519 Subject Refused
3165 Unknown

If you want ethnicity data from OnCore to display with labels in REDCap, make ethnicity a radio button field with these codes:

3163,Hispanic or Latino
3164,Non-Hispanic
15519,Subject Refused
3165,Unknown

To prevent modification of fields that should be set by the OnCore Client, add the @READONLY action tag to the fields. The @READONLY action tag will prevent modification of the those fields via REDap forms, but will still allow the OnCore client to set them.

Note also that while the OnCore client supports non-longitudinal projects, the event name must still be specified.

REDCap Record ID

The OnCore Client will set a REDCap Record ID for any record it creates. If no field is mapped to Record ID in the field mapping, the OnCore Client will generate an automatic number incrementing the highest record ID in the system.

You have the option of mapping any field in OnCore to REDCap's Record ID. Note that when mapping OnCore fields to Record ID, REDCap records will be overwritten if a field contains a non-unique value or rejected if a field contains no data; uniqueness of the field mapped to Record ID is neither checked nor enforced by the OnCore Client. You are expected to use a field with unique values (a good option is SequenceNumber if it is provided for every subject).

Synch OnCore subjects

You can use the Pull OnCore Subjects feature to copy enrollees into REDCap from the OnCore enrollment records.

Pull OnCore Subjects Link

The same feature can update fields in REDCap that do not match the data in OnCore. The interface uses color queues to show which records subjects are only in OnCore (yellow), which records are in REDCap and Oncore but have mis-matched data (green) and which REDCap records are not linked to an OnCore subject (blue).

Pull OnCore Subjects Page

The data synchronization work has to be done on a regular basis by study staff as new subjects are enrolled. Make sure to press Refresh OnCore data at the beginning of a synch session. You can view the data relevant OnCore data for each record by pressing View OnCore data or see the difference between two records by pressing View Diff.

Select the records you want to synchronize, then press Pull OnCore Subjects bring those OnCore records and fields into REDCap. As you synchronize enrollees, they will disappear from the list. When the list is empty, your REDCap data is in synch with your OnCore data.

Synch Done

Supported services

This module is still under construction so the supported operations so far are:

  • getProtocol
  • getProtocolSubjects
  • getProtocolStaff
  • createProtocol
  • registerNewSubjectToProtocol
  • registerExistingSubjectToProtocol

Logs page

You may track your API calls by accessing the logs page. Go to Control Center and click on OnCore Logs at the left menu.

Logs page list Request

You may clear the logs by clicking on Clean logs button.

Developer notes

If you want extend the OnCore client to support other OnCore data types, you might find the Developer's Notes helpful.

redcap_oncore_client's People

Contributors

chemikyle avatar pbchase avatar tbembersimeao avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

redcap_oncore_client's Issues

Pull OnCore Subjects does not support DAGs

This is not a high priority item, but it needs to be documented.

The Pull OnCore Subjects features does not support DAGs. In a multi-site trial, the Pull OnCore Subjects feature will likely expose PII from OnCore to every site defined in the project. A better design would allow the OnCore Study Site to be associated with each DAG in a project. The OnCore Enrollment data includes Study Site in a StudyData object. The OnCore enrollment data should be subsetted by the current user's DAG's Study Site to display only enrollees for their site. Data read from REDCap should be similarly subsetted. Any record's added from OnCore must set the DAG for the new record.

REDCap 9.0.1 causes records to not be entered

Upgrading to REDCap 9.0.1 causes a never-ending wait after selecting records and attempting to Pull OnCore Subjects, user can only cancel or leave page and no records are added. However, all redcap_entity databases fill as expected.

Also makes the computer running the VM's fan turn on, even after cancelling.

Verify the logged in user is on the study staff

The REDCap OnCore Client needs to verify that users attempting to access the enrollment data for a study are listed as study staff on that study. Study staff data can be provided by the OnCore API via the GetProtocolStaff method. Staff needs to be looked up via UFID. Study staff data should be cached like any other data fetched form OnCore. Managing queries of a user's UFID requires that we store that attribute as an extension of the REDCap user information.

To achieve these goals, I recommend these functions be implemented:

  1. Add a new entity named user_attributes with redcap_entity. This entity needs 2 attributes: username, staff_id
  2. For each user that opens the Pull OnCore Subjects page, test for a server environment variable named HTTP_GLID. If it exists, store/update it in the staff_id attribute with a username equal to the $REDCAP_USER.
  3. Add a new entity named protocol_staff. The entity should have 3 attributes: protocol_id (or whatever we called this attribute in the protocols table), staff_id, and stop_date
  4. Add an action to the existing actions that execute when the Refresh OnCore data button is pressed. The new action should use the getProtocolStaff OnCore API method to fetch the protocolStaff for this one protocol, store that data in the protocol_staff entity.
  5. Modify the actions that present data on the Pull OnCore Subjects plugin page to check the authorization of the currently logged in user before presenting enrollment data. Only users whose staff_id is listed in the current protocol's protocol_staff table with a stop date in the future are authorized to see enrollment data.
  6. Make sure the Refresh OnCore data button is visible and works at all times. This will allow people to refresh cached protocol staff data that might be blocking their access to the enrollment data.

Here's the workflow of a normal interaction with the new features that verify the logged in user is on staff:

ocr ctsit- meeting - workflow for authorized access to oncore enrollment data and forte EDC 2019-05-15 14 36 28_1

Add a feature to save a server vars value as institutional ID

Add a feature to save a server variable's value as the Institutional ID.

Apache sets a number of variables and hands them to the called application via the server environment. In a shibboleth environment, one of these could be the institutional ID that we would like to see in the staff_id field of the oncore_staff_identifier entity. We need to read that environment variable and write its value and the current username into a record of the oncore_staff_identifier entity. That should allow us to lookup the staff_id when checking if the currently logged in user is in the protocol_staff entity for the current protocol. To make this feature work at different sites, sites without shibboileth, and development environments, the environment variables read should be configurable.

To that end, do these things:

  1. Add a configuration field to the system-level configuration of the redcap_oncore_client. Name that field something like "staff_id_variable_name". It should be a text field.
  2. Modify the subjectsPull plugin page or its included classes to read the name of the environment variable in the above config entry, read the value of that environment variable and write/update a record in the oncore_staff_identifier with that value as the staff_id attribute and the currently logged in REDCap user's username as the user_id attribute.

A good place to do this step might be just before

$sql = "SELECT * FROM redcap_entity_oncore_protocol_staff

Make sure you test that the var exists. Also, test that the value stored in the var has non-zero length. Also, verify that this feature does not insert an additional record on each page load lest oncore_staff_identifier grow unchecked.

Note: To test this feature any server environment variable that is constant across page reloads will provide suitable input. One can see all the vars using the phpInfo() command. These variables would be suitable: HTTP_HOST, SERVER_ADDR, SERVER_NAME

Unused variables

The PHPMD static analyzer pointed out the following minor issues that you might want to address:

classes/entity/list/SubjectsDiffList.php
Line 179: $inline set but never used

classes/entity/SubjectDiff.php
Line 125: $new_record used but never set.

ExternalModule.php
Line 376: $client set but never used
Line 379: $no set but never used
Line 398: $mappings set but never used
Line 472: $key set but never used
Line 528: $id set but never used

Cannot have multiple projects using redcap_oncore_client

Steps to recreate:

  1. Login as admin
  2. Create a new project, enable and configure the OnCore Client module
  3. Go to the Pull Oncore Subjects page
  4. Click the Refresh OnCore data button
  5. Create another new project, enable and configure its OnCore Client module (Protocol does not matter, it can be the same or different as the first project)
  6. Navigate to the newest projects Pull OnCore Subjects page
  7. Click the Refresh OnCore data button and observe a PHP error

To solve, navigate to Control Center, External Modules > EntityDB Manager. Drop the table redcap_entity_oncore_subject_diff and create it again. Module will work as long as another project is not created using the OnCore Client module.

Adding new subject field mappings after already pulling OnCore subjects makes new records instead of updating old ones

Steps to recreate:

  1. Create a new project, configure OnCore Client, under Subject Field Mappings, use at least one OnCore variable to populate a REDCap variable
  2. Navigate to Pull OnCore Subjects, select any number of subjects and click the Pull OnCore Subjects button
  3. Navigate back to the configuration page, select at least one more OnCore variable to populate another REDCap variable and save changes
  4. Navigate back to Pull OnCore Subjects, select any number of OnCore subjects which show they need an update, click the Pull OnCore Subjects button again
  5. Observe table is now populated with "Not linked" records whose REDCap Record IDs correspond to those of the updated subjects
  6. Navigate to Add/Edit Records, observe that "Not linked" records contain all data except that which was just brought in; updated records have been appended to existing records

OnCore client can only see open protocols

The OnCore client only sees open protocols. In using the SIP URL, the OnCore client is only seeing protocols that are open to accrual. REDCap project builders using this module would be unable to configure their project before accrual starts. We need an alternative way to enumerate the protocols.

As the protocol numbers are sequential, we could allow the specification of some combination of naming pattern, base name, and starting number that would allow the ONCore client to guess protocol numbers. E.g., it could start at number 00042, using a prefix of "OCR-", to query for OCR-00042, OCR-00043, etc. until it could not locate OCR-NNNNN at which point it would stop assuming it had reached the highest allocated protocol ID.

With these guessed protocol IDs, the OnCore client can query the WSDL interface to get full details about the protocol and its enrollment. It can use a limited set of this data to populate the "select protocol" drop down.

Pull OnCore Subjects and Link to subject are not working

The Pull OnCore Subjects and Link to subject buttons are not working reliably. These features need some review. They worked on Tiago's dev instance, but they did not work on my dev instance. Everything surrounding them did, but the actually link and import operations failed.

Curious data diff problem

@ChemiKyle, I got a weird synch problem in my Oncore client testing today. Testing with Protocol OCR20388 in the https://oncore-test.ahc.ufl.edu host, one record would not synchronize right.

mysql> select * from redcap_entity_oncore_subject_diff;
+----+------------+------------+------------+-----------+------------+--------------+-------------+-----------+----------+---------------------------------+
| id | created    | updated    | subject_id | record_id | project_id | subject_name | subject_dob | type      | status   | diff                            |
+----+------------+------------+------------+-----------+------------+--------------+-------------+-----------+----------+---------------------------------+
| 75 | 1565000765 | 1565000765 |        200 | 989       |         14 | Pup Pluto    | -1406577600 | data_diff | on_study | {"LastName":["Pluto","Pluto "]} |
+----+------------+------------+------------+-----------+------------+--------------+-------------+-----------+----------+---------------------------------+

The problem is a trailing space on the LastName field. We must be trimming the data before we write it. We need to not trim it. We need to honor whatever garbage they offer us. :-)

OnCore data contained in nested objects or arrays can not be pulled

If the OnCore API delivers any of its values in a nested array or object, they will not be inserted into the REDCap entity db. In SubjectDiff.php, converting the data to json, and converting it back casts all nested objects as arrays which can then be iterated over using array_walk_recursive, allowing them to be brought into REDCap via Pull OnCore Subjects, but it is not recognized by oncore_subjects_diff, resulting in users seeing that a record needs update.

Allow use of REDCap "Institution ID" field in place of the RCE side table

It would be helpful to other sites--and perhaps even UF-- if they/we could choose whether they want to use the REDCap "Institution ID" field in place of the side table managed by REDCap Entity. I see three use cases:

  1. You are using REDCap's "Institution ID" field and it has the right info to align with OnCore.
  2. You are using REDCap's "Institution ID" field and it has the wrong info for aligning with OnCore.
  3. You are not using REDCap's "Institution ID" field.

For option 1, you'd probably use the REDCap "Institution ID" field so you can keep your existing business process.

For option 2, you'd probably want to use the side table. Again, this would let you keep your existing business process.

For option 3, you could go either way.

This could be implemented with a checkbox in the system configuration the redcap_oncore_client. The code that writes the Institutional ID would need to check this value. The code that reads it would also need to check this value. Alternatively, abstract those set and get operations into a small class.

Unused parameter

classes/entity/list/SubjectsDiffList.php

method getRowAttributes

$data is unused

User Attributes entity is alternately broad and specific

The User Attributes entity is alternately broad and specific. The entity goes by these monikers in the ExternalModules.php

        $types['user_attributes'] = [
            'label' => 'Local User Information',
            'label_plural' => 'Local Users Information',

Yet for the plugin page (in config.json) we refer to it with Enter Study Staff. i.e.

                "name": "Enter Study Staff",
                "icon": "group_gear",
                "url": "plugins/user_attributes.php"

Are these "study staff" details or are we defining a large list of user attributes? I am conflicted here. At UF, the study staff ID is the local UFID. It could be useful in other modules. Yet we are collecting it only within the context of the OnCore Client. 'user_attributes' feels more like system-wide service.

My inclination is to rename this entity study_staff_attributes or oncore_study_staff_attributes. I welcome input on this matter.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.