Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Initially we referred to this as compliance, but because “compliance” also has meaning in a governance context, so we’re using “adherence” to describe the measurement of the extent to which a participant performs all the assessments they are asked to perform as part of their participation in a study member participation in the study.

Table of Contents
minLevel1
maxLevel7

...

  1. For the first time the server will need to have knowledge of the participant’s time and time zone;

  2. Because this information depends on the time of the request, it is not very cacheable;

  3. Nevertheless, the reports probably update infrequently (the exact amount depends on many factors), while they may be read frequently in a couple of different formats.

Event Day Adherence Report API

Given the designs I have seen so far, I would suggest an “event by day” report which would be available via a single API:

...

Method

...

Path

...

Description

...

GET

APIs

Method

Path (Under /v5/studies/{studyId}

Description

GET

/participants/{userId}/adherence/

eventday
?activeOnly=true|false

activeOnly = show only currently available days. This can be expanded to show days before or after, etc. as useful to clients.

...

eventstream

List of SessionStream reports for one user. The only view that shows scheduling for events the user does not have, this is a detailed view for one user of the whole schedule.

GET

/participants/{userId}/adherence/daterange

Paginated list of SessionsOnDate objects. Date range-based with local dates spanning 14 or less days. Does not show sessions that are not applicable to the user.

GET

/participants/adherence/daterange

A paged list where each record is a set of SessionsOnDate reports for a specific user with 1-7 SessionsOnDate reports. Date-range-based with local dates spanning 7 days or less. Does not show sessions that are not applicable to the user.

The last report is a very large amount of information (basically 7 pages of information per page). I think we’ll need to write the SessionsOnDate reports to a store like Dynamo or MySQL, and regenerate them with a worker process, since it’s such a large amount of information. We may also need to cache the resulting JSON on the web side.

SessionStream Report

Given the designs I have seen so far, I would suggest a set of records that show the sessions to be performed N days after each event, available as a single report that’ll be similar in size to the Timeline. In the array, each record shows one event time stream, and the sessions that should be performed under the “days since event N” key of the entries map. Right now, that day has an array with each session holding its own set of windows, since they are graphed together in designs I have seen (and the completion state is recorded for each window—that’s really the session).

Code Block
languagejson
[
  {
    "startEventId":"study_burst:ClinicVisit:01",
    "eventTimestamp":"2021-10-27T19:00:00.000Z",
    "entries":{
      "1":[
        {
          "sessionGuid":"vZBHBVv_H2_1TBbELF48czjS",
          "label": "Session #1",
          "symbol": "circle",
          "timeWindows":[
            {
              "sessionInstanceGuid":"ePcCf6VmfIiVuU0ckdBeRw",
              "timeWindowGuid":"sUaNAasy_LiT3_IYa1Fx_dSv",
              "state":"not_yet_available",
              "type":"EventDayWindowSessionStreamWindow"
            },
            {
              "sessionInstanceGuid":"DB13D4mO72j6S-g7PIkI2Q",
              "timeWindowGuid":"Bw6rAAeG6zotqes4cLSgKjh5",
              "state":"not_yet_available",
              "type":"EventDayWindowSessionStreamWindow"
            }
          ],
          "type":"EventDaySessionStream"
        }
      ],
      "2":[
        {
          "sessionGuid":"vZBHBVv_H2_1TBbELF48czjS",
          "label": "Session #1",
          "symbol": "circle",
          "timeWindows":[
            {
              "sessionInstanceGuid":"wvEV4fJZQ0nfgY-TN2LekA",
              "timeWindowGuid":"sUaNAasy_LiT3_IYa1Fx_dSv",
              "state":"not_yet_available",
              "type":"EventDayWindowSessionStreamWindow"
            },
            {
              "sessionInstanceGuid":"IHDTSoj552vGDv1Qt7nXkg",
              "timeWindowGuid":"Bw6rAAeG6zotqes4cLSgKjh5",
              "state":"not_yet_available",
              "type":"EventDayWindowSessionStreamWindow"
            }
          ],
          "type":"EventDaySessionStream"
        }
      ]
    },
    "type":"EventDayAdherenceReportSessionStreamReport"
  },
  {
    "startEventId":"study_burst:ClinicVisit:02",
    "eventTimestamp":"2021-11-16T19:00:00.000Z",
    "entries":{
      "1":[
        {
          "sessionGuid":"vZBHBVv_H2_1TBbELF48czjS",
          "label": "Session #1",
          "symbol": "circle",
          "timeWindows":[
            {
              "sessionInstanceGuid":"zk7X4dQCy7Nvnuo2PcnSCA",
              "timeWindowGuid":"sUaNAasy_LiT3_IYa1Fx_dSv",
              "state":"not_yet_available",
              "type":"EventDayWindowSessionStreamWindow"
            },
            {
              "sessionInstanceGuid":"rMRne-cbwIN5mkGZLymxzg",
              "timeWindowGuid":"Bw6rAAeG6zotqes4cLSgKjh5",
              "state":"not_yet_available",
              "type":"EventDayWindowSessionStreamWindow"
            }
          ],
          "type":"EventDaySessionStream"
        }
      ],
      "2":[
        {
          "sessionGuid":"vZBHBVv_H2_1TBbELF48czjS",
          "label": "Session #1",
          "symbol": "circle",          
          "timeWindows":[
            {
              "sessionInstanceGuid":"QXM1cO6yb0gSPWzRwRD8eA",
              "timeWindowGuid":"sUaNAasy_LiT3_IYa1Fx_dSv",
              "state":"not_yet_available",
              "type":"EventDayWindowSessionStreamWindow"
            },
            {
              "sessionInstanceGuid":"hCXFevxbBnpaUYjH212dsQ",
              "timeWindowGuid":"Bw6rAAeG6zotqes4cLSgKjh5",
              "state":"not_yet_available",
              "type":"EventDayWindowSessionStreamWindow"
            }
          ],
          "type":"EventDaySessionStream"
        }
      ]
    },
    "type":"EventDayAdherenceReportSessionStreamReport"
  }
]

All sessions in the timeline are grouped in this view by the event that triggers them, and then the number of days since that event. All potential events in the schedule are included in this report whether they exist for the user or not (we don’t currently have a way to say “count this part of the schedule if the event exists for the user, but don’t count it if the event doesn’t exist for the user). Then the actual “days since each event” are calculated to determine what the state of each time window is (the window state is a session-level measure of the state, derived from the adherence records of the assessments in that session).

...