Document toolboxDocument toolbox

Bridge v2 Implementation Design

Note: I’ve combined some design documents into one document (this document), with the exception of assessments, scheduling, and consent (all three are separable from these core models).

The Evolution of the Bridge System is a public facing document which breaks our APIs down into the science and mobile app development domains. It will describe our plans to change the system for our partners, as these become clearer. Eventually this implementation documentation will be used to rewrite the more general domain design document as part of our documentation website.

 

This document is in the order that I propose to implement features.

Some notes about changes:

  • Going to eliminate “/self” endpoints from most of these API proposals. They add a lot of noise and our authorization checks are getting more complicated anyway, and should be hidden from the API. I’ve also made mistakes over the years in writing integration tests, that would be eliminated if these didn’t exist. They do still need to exist for participant-facing APIs where we don’t expect the client to track the user’s identity.

  • We are discussing whether data should be exported “by study” or “by organization.” There are pros and cons to each…Dwayne will make a decision about this.

APIs

Apps

The refactored study object now represents an app as a whole, with some fields migrating to the new Study object. Account, authentication, upload, and export configurations are still shared between studies and cannot be different between studies (templates might be an exception, where we add study-specific overrides if they are needed). Note that the export system is currently being revised, and we have not decided on how access to data will be managed by Synapse. Bridge’s responsibility is to ensure uploads have all possible metadata that is needed for analysis and management.

Apps are still a fundamental tenancy model for our system… no calls should ever operate on models outside of the caller’s app scope (unless the caller is a worker).

Organizations

Organizations will be added to the data model. Administrative accounts will be removed from the AccountsSubstudies table and associated to Organizations through a foreign key column on Accounts. There are about ~160 of these administrative accounts in production. This change will be visible to legacy studies.

A study can be associated to one or more organizations through a Sponsors table (see below). An administrative user is associated to the studies that are associated to their organization. With Substudy refactored to be Study, we can continue to filter accounts the same way we do now (by matching the studies accessible to the caller with the studies a participant is enrolled in). These studies will be stored in the administrative user’s session so they do not need to be resolved with every server request.

The legacy exporter will continue to export data to the Synapse project configured in the App object, and export substudy memberships. The next version of the exporter will export data to Synapse based on the configuration in an organization or in a study (TBD). If the export is “by organization,” we will need to continue to export the (sub)study associations. If we export “by study,” we do not need to export information about the organizations that own the studies, as we’d need to enforce the access rules (by organization) in Synapse. The study association is important to audit consent later (that is, “for this piece of data, under what consent from the user was it uploaded?” which requires the source study to answer).

Method

Path

Description

Access

Method

Path

Description

Access

GET

/v1/organizations

list organizations associated with an app

All admin users

POST

/v1/organizations

Create a new organization

app admins

GET

/v1/organizations/{guid}

Get a specific organization

All admin users

POST

/v1/organizations/{guid}

Update a specific organization

app admins

DELETE

/v1/organizations/{guid}

Delete an organization (logically or physically). Can’t leave a study without at least one associated organization.

app admins

GET

/v1/organizations/{guid}/studies

All the studies sponsored by this organization.

All admin users

Memberships

Administrative accounts can only be a member of one organization. We can associate multiple organizations to a study to give administrative user access to the study across organizations.

Thus, an account has an optional orgId foreign key reference to an organization (only administrative accounts are will be required to have this membership relationship, but we will need to migrate administrative accounts before we can require it on create and update).

The membership endpoints add and remove accounts from an organization. The accounts must be created first (though they don’t have to be verified), and they must be administrative accounts (they have the admin_user data group indicating at least one administrative role). Editing of accounts still happens through the participant APIs (even though these folks are not always participants), which can also be used to get a list of administrators, filtering for the admin_user tag.

Method

Path

Description

Access

Method

Path

Description

Access

GET

/v1/organizations/{guid}/members

Get the list of members (Paged)

app admins

POST

/v1/organizations/{guid}/members/{userId}

Add member of this organization

app admins

DELETE

/v1/organizations/{guid}/members/{userId}

Remove member of this organization

app admins

Permission Checks

TBD. Practically right now, many operations are restricted to app admins, and this may need to be changed.

Assessment Ownership

Assessments have a similar ownership model. When they are published to the shared repository, the owner ID has to be namespace with the appId from which the assessment was derived, to be examined later for some permission checks.

Accounts

There are few changes to accounts. Test users will continue to be marked with the test_user data group, and can be filtered out of APIs that return AccountSummary objects. Administrative users can be identified the same way through an admin_user data group. This data group will only be present if the user has one or more administrative roles. Administrative users can then be associated to organizations through an orgId foreign key field. There will be separate APIs to retrieve enrollees in a study, and to retrieve administrative users by their organization (the participant APIs will continue to exist, and continue to return both kinds of accounts).

We will change the account status flag so that an account is enabled if it has any path to authentication (verified email, verified phone, external ID or Synapse user ID). This simplifies the logic around Synapse ID and external ID-based accounts.

Studies

Substudy will be refactored to be a Study. A Study object describes one of the studies being run in an App. The substudy APIs can be removed and replaced with new /v5/studies APIs.

Method

Path

Description

Access

Method

Path

Description

Access

GET

/v5/studies

List all studies in an app context, either public or private and associated to the caller’s organization. Shows follow-on studies, closed studies, etc.

all admin users

POST

/v5/studies

Create a new study

app admins

GET

/v5/studies/{studyId}

Get a study record

app admins

POST

/v5/studies/{studyId}

Update the study.

app admins

DELETE

/v5/studies/{studyId}

Delete the study if it is in the UNRELEASED state.

app admins

The study object:

public class Study { appId: String; identifier: String; name: String; description: String; website: String; deleted: boolean; createdOn: DateTime; modifiedOn: DateTime; phase: StudyPhase; clientData: JsonNode; version: Long; }

The clientData field can be used to store implementation-specific data. For example, the MTB app intends to note the type of credentials it is collecting for a specific study (phone-based sign in or external ID + password) so it can tailor the UI accordingly.

Study Phases

A StudyPhase describes the current phase a study is in as part of the whole study lifecycle. This can be referenced to enforce lifecycle constraints, tailor study UIs to fit the tasks appropriate to that stage of the study, etc. Note that how the study enrolls participants (via email or phone, external ID or through public and anonymous sign ups) is specified separately, and is just a hint to UI tools (unless we decide to enforce them).

StudyPhase

Comment

Transition Into Verb

StudyPhase

Comment

Transition Into Verb

LEGACY

All legacy studies will be set in LEGACY, which cannot be changed from LEGACY, and which which prevents all lifecycle constraints from being enforced.

DESIGN

Studies are created in DESIGN

  • schedule can be edited

  • study can be updated

  • schedule association to study can be changed

  • study not visible in public registries

  • all accounts created are test_user accounts

  • study can be deleted, logically or physically

RECRUITMENT

  • study must be in DESIGN to transition to RECRUITMENT

  • IRB information must be filled out and attested to

  • schedule is published and cannot be changed

  • schedule association cannot be changed

  • study visible in public registries if enrollment type specifies it

  • accounts now created normally

  • study cannot be deleted

recruit

IN_FLIGHT

  • study must be in RECRUITMENT to transition to IN_FLIGHT, either by study coordinator or by system upon achieving recruitment targets

  • no more enrollments can be created for this study

  • study no longer visible in public registries if it was visible

  • App still needs to be in App Store in case a participant needs to reinstall, or it’s a multi-study app

  • study cannot be deleted

execute

ANALYSIS

  • study should have at least one enrollee and no active participants in order to be moved to ANALYSIS

  • App can be removed from the App Store if the app hosted only this study

  • Study still available for IRB reporting

  • Study cannot be changed, at all

  • study cannot be deleted

analyze

COMPLETED

  • study must be in ANALYSIS to transition to COMPLETED

  • study cannot be changed, at all

  • study can be logically deleted

closeout

WITHDRAWN

  • study can be in any phase except COMPLETED to transition to WITHDRAWN

  • study cannot be changed, at all

  • study can be logically deleted

withdraw

These rules apply to the entire graph of objects that define a study.

Studies need to manage a few change-related use cases, which is why some key aspects of a study are dependent objects with their own APIs:

Model

Owner

Description

Model

Owner

Description

Consent(s)

Org that owns the study

One or more, only one can be required (although multiple consents may be marked as required if they are in different languages). Informed consent, comprehension, and signature. Not normally assigned to two studies, but this is possible if a new study should not reconsent participants. However, there’s only one “state” of the consent in terms of noting IRB approval, duration, etc.

Recruitment

Public

One and only one. Baseline characteristics, an arm allocation strategy including allocation state, and an initial assessment to present prior to allocation. Like consents, these can be shared between studies.

Protocol

Public

One and only one. Can be shared between studies and across organizations.

I am not sure if eligibility is part of a consent, part of a recruitment strategy, or directly associated to a study.

Christine Suver on eligibility: “What I see is the same study using different consents for different sub-populations.  For example, in ADRC Wisconsin, the participation of under-represented  participants comes with a small reimbursement and fewer mandatory activities. Same study, 2 sets of consents. When the study wants to rebalance its representation, the researchers are temporarily modifying eligibility criteria to only recruit within the desired populations.”

A new study can be created that shares these aspects of another study, helping us to manage the following scenarios:

Changing a study in progress. This might be a bug fix or an enhancement.

  • Change through configuration only. Changes to the study object graph should be detectable by the client so it can retrieve and update the client, or the app config can be used to manage upgrades (as we currently do now).

  • Change requires app release. A new study will need to be created and referenced by the new release, however, the study can include the consent(s), recruitment and/or protocol of the original study so the state of enrollment and consent need not be lost. If the consent is different than the enrollment consent, the new consent can indicate whether or not the user should be forced to reconsent (or if, as long as there is an enrollment record, the user can continue to participate in the study).

Extending a study in time. There are two ways to do this.

  • Add to the existing timelines. Even after a study starts, study designers can extend the days in the study. Particularly if this doesn’t involve re-consent, this can work well.

  • Create a follow-on study. A new study can be created, and an assessment can be added to the end of the first study’s timeline that prompts the user to join the next study. This can support re-consent or not. This second study would not be public (you cannot directly enroll in it, you get to it by completing the first study).

Following up one study with another study. After the user authenticates, it should be possible to consent to other public studies that are available in the app. If we want to direct users of one study to consider joining a specific follow-on study, client logic will need to be introduced, looking at a user’s consents to determine what to display to the user. (Consent has never been fully automated.) There is one possible API for this:

Method

Path

Description

Access

Method

Path

Description

Access

GET

/v5/studies/research

A list of public studies available to the caller, minus the studies they are already in

authenticated users

Multisite studies. Each site will need to be treated as a separate study, sharing the parts that are common and customizing the rest. For example, you might choose to differ consents, but use the same protocol. Designers will also have to decide if these studies share one allocation system, or if they will track recruitment on a site-by-site basis. For multisite studies, an umbrella organization should be associated to all the studies, so that one organization receives all the data in one Synapse repository.

Sponsors

Studies will be associated to one or more organizations as Sponsors (to be accessible to anyone but super admins, they will need to be associated to at least one organization). Members of organizations that have sponsored a study can edit that study and see its participants (appropriate to their roles; roles remain global). Studies are otherwise publicly visible (we may eventually given them a private flag, where only members of sponsoring organizations would be able to read the study).

With an organization model, Sage Bionetworks can cease to be a weird global default…instead we can associate Sage accounts to all studies in an app by associating our organization to all studies (perhaps it’s set as a default and cannot be removed).

When an administrative user signs in, we should collect all the studies they have access to as a result of their organizational memberships. We can then continue matching account searches against a list of (sub)studies. This is how we ensure that study administrators cannot see participants enrolled from other organizations.

Method

Path

Description

Access

Method

Path

Description

Access

GET

/v5/studies/{studyId}/sponsors

All the studies associated to this organization

All admin users

POST

/v5/studies/{studyId}/sponsors/{orgId}

Give an organization access to a study

App admin in an org already sponsoring the study

DELETE

/v5/studies/{studyId}/sponsors/{orgId}

Remove study access from an organization

App admin in an org already sponsoring the study

Enrollments

The current participation of an account in a study is called an enrollment. And enrollment record is an associative entity between Account and Study. This record can be created in one of two ways:

By signing a consent. The participant can sign the required consent for a study, which will enroll them in the study. (Subpopulations already have optional logic to place a person into a study; this will become mandatory). On withdrawing from a study, the participant updates the consent signature record and the enrollment record (it is not deleted because we wish to track withdrawals from a study).

By a study administrator. There are also APIs for a third party to enroll and withdraw accounts from a study. The most common use case is when adding an account to a study through an external ID. When enrolling another account, the person doing the enrolling is recorded in the enrollment record. The caller can optionally bypass any further consent requirements for the account (were it to enroll itself). Similarly, a third party can withdraw an account from the study, and the caller will be recorded (along with an optional note about why).

An account is considered enrolled in a study if there is an enrollment record for the study, withdrewOn is null, and consentRequired is false. consentRequired can be false because it was explicitly set that way by a third party caller, because the participant signed a required consent, or because there was no required consent when they enrolled. This flag is not changed by later changes to the consent system.

A user is withdrawn from a study if withdrewOn is not null. Note that consent signatures and signature histories will remain as is, but changes to the consent history will update the enrollment record, which is the final state of the user’s presence in the study.

Allocation to a study arm is also recorded in an enrollment record, and should be part of the baseline characteristics information.

The AccountsSubstudies table will be renamed Enrollments.

Enrollment { String appId; String studyId; String accountId; // optional String externalId; // at time of enrollment, is there a required consent for the study boolean consentRequired; // timestamp user has signed the consent, or record creation timestamp DateTime enrolledOn; // user withdrew consent DateTime withdrawnOn; // who enrolled this person, if not the person themself String enrolledBy; // who withdrew this persion, if not the person themself String withdrawnBy; // study arm allocation (may be supplied as part of enrollment record, // eventually, or we can run an allocation algorithm) Study studyArm; // sharing scope currently remains global to the account, but if it is // different by study, it would be stored here. SharingScope sharingScope; }

Currently it appears we can retrofit the existing consent system to support enrollment records. In addition, the following API will be introduced:

Method

Path

Description

Access

Method

Path

Description

Access

GET

/v5/studies/{studyId}/enrollments

List all the individuals who have enrolled in the study. Paged.

Researcher in a sponsoring org

POST

/v5/studies/{studyId}/enrollments

Enroll an account in a study (almost always with an externalId).

Researcher in a sponsoring org

DELETE

/v5/studies/{studyId}/enrollments/{userId}

Withdraw the user from the study

Researcher in a sponsoring org

This API replaces the external identifier APIs which will be removed. External IDs will no longer be created separately from an account. The create participant API will continue to take an external ID so it can create an account with an enrollment record (otherwise we lose the ability to identify an account solely by an external ID). We continue to have no secure way to authenticate this type of account.

Recruitment (formerly baseline characteristics)

The Recruitment model covers a couple of interrelated capabilities:

  • Collecting specific “baseline characteristics” during onboarding that are either important for recruiting, study analysis, or both;

  • Using these characteristics to allocate participants to study arms, using one of a few industry standard allocation practices for clinical studies. (Allocation strategies will operate on any number of arms, and can be assigned to any protocol);

  • Holding the state of allocation.

Like other aspects of a study, recruitment may need to be carried over to another study configuration, or it may need to be changed while maintaining the rest of the study design.

Method

Path

Description

Method

Path

Description

GET

/v1/recruitments

Get a list of recruitment objects for this app

POST

/v1/recruitments

Create a recruitment object

GET

/v1/recruitments/{guid}

Get a recruitment object

POST

/v1/recruitments/{guid}

Update a recruitment object

GET

/v5/studies/{studyId}/recruitment

Get the recruitment object associated to this study

POST

/v5/studies/{studyId}/recruitment/{guid}

Associate recruitment to this study, replacing one if it exists.

Baseline characteristics

Note: I would not implement this until protocols and study arms are complete. It isn’t useful without these.

A recruitment object will reference an assessment the user should perform after consent, but before they are allocated to a study arm. This assessment collects the baseline characteristics (the client may choose to retrieve characteristics from the answers to an eligibility step, as well). The total set of characteristics is thus dynamic, and will change if a user consents to further studies.

Where two studies collect the same information, it is up to the study designers to coordinate and address naming conflicts/duplication/duplicated effort on the part of the user (e.g. asking for “sex” and “gender” for two different studies in the same app).

The v2 exporter will export information about a participant every time that record changes, to a normalized table in Synapse. So this appears to be an ideal mechanism to centralize and export the baseline characteristic data.

There is some information that we should probably always export with the participant record:

  • study enrollments (and their external IDs);

  • study arm assignment for each study (using the arm pseudonym);

  • data groups;

  • sharing scope for each study.

Note that some data is per study and the user can be enrolled in multiple studies.

Allocation Strategy

These are the allocation strategies we should aim to support (we can support others, like non-randomized assignment strategies):

Blocked randomization - the set of study arms (A) is put into a list N times (3-4 times would be typical and we might just pick a value at random), and then the list item order is randomized. Each allocation pulls sequentially from this list until it is exhausted, and the process is repeated. This ensures that after A*N allocations, the study arms will be equal in size (and the arm size difference will never be more than (A*N)/2), yet researchers cannot easily predict the next allocation.

Stratified randomization - in addition to assuring even distribution between study arms, this strategy ensures even distribution of baseline characteristics between arms. The first challenge of using this strategy is that characteristics need to be discrete and not continuous (so the client would need to convert values, e.g. 125/84 to “pre-hypertension”). The product of all discrete values by all characteristics being randomized is used to generate a set of strata. Each enrollee is assigned to one of these strata, then block randomization is used within that single strata. In this case, blocks should be smaller (1-2 sets of study arms).

For example, if you were randomizing by country (the 3 in North America) and blood pressure (5 categories), each user could be assigned to one of 15 strata, and the block randomization would be tracked separately for each strata.

If a study design has no baseline characteristics, we can default to blocked randomization, and it if has baseline characteristics and some are marked for allocation, we can use stratified randomization. This is pretty robust.

However one downside to these two strategies is that the numbers of people who are noncompliant, or just drop out of a study, can be such that imbalances will still appear between arms of the study. If this becomes an issue, we can examine algorithms that examine participation data, and tweak allocation to restore balance with new enrollees (e.g. “response adaptive randomization”).

Each strategy can be encapsulated in an AllocationStrategy that can be parameterized at execution, and that will return state (we’ll only be able to allocate one person at a time and will have to write code accordingly).

public interface AllocationStrategy { /** * * @param allocationState * the allocation state loaded from persistence. State is stored * in the Recruitment object with an optimistic lock, so it will be * necessary to retry until allocation succeeds. * @param characteristicDefs * definitions of the characteristics that were marked for allocation. * This should include a listing of all possible categorical values. * @param userCharacteristics * the values collected for the user being allocated * @param studyArms * study arms of the protocol from which one study arm should be selected * @return * an object encompassing the selected study arm and the changed state that * should be persisted. */ Allocation allocate( Map<String, Object> allocationState, List<CharacteristicDef> characteristicDefs, List<Characteristic> userCharacteristics, List<StudyArm> studyArms); } // The study arm selection and a new map with updated allocation state // are persisted in a transaction that includes the study participant // and the recruitment object. Encompassing code will need to retry on // concurrent modification exceptions. class Allocation { StudyArm studyArm; Map<String,String> newAllocationState; }

The entire load state, allocate, and persist needs to happen in a database transaction. If the transaction fails, it’ll need to start over, reloading the current state. I don’t think this will require a distributed lock as the database can serve this purpose, but a queue might reduce or eliminate retries.

Here is an example of a randomized but stateless (and therefore pretty useless) allocation strategy:

Protocols

Protocol objects exist globally for all studies in an app. They are global because they can be shared between studies (for example, the mPower 2 study was used by external organizations as part of their larger studies… they would use the same protocol, but the enrollment process for participants coming from that study is different). One organization is marked as the owning organization of a protocol. Only users associated to that organization can edit or delete that protocol. However, protocols can only be edited or deleted when they are not associated to a Study that is in use. For this reason, associating a protocol to multiple studies could be somewhat rare in practice (but it remains our solution for cases like mPower 2 where organizations enroll participants in different ways).

Method

Path

Description

Method

Path

Description

GET

/v1/protocols

Get a list of protocols in app context (either public or associated to an organization the caller is associated to, or all organizations for “global” caller accounts

POST

/v1/protocols

Create a protocol

GET

/v1/protocols/{guid}

Get full protocol record

POST

/v1/protocols/{guid}

Update a protocol

DELETE

/v1/protocols/{guid}

Delete a protocol (subject to limitations based on the states of the studies currently using this protocol).

Study Arms / Provisos / Timelines

Protocols are associated to StudyArm and Proviso objects. Scheduling happens through study arms and provisos, so scheduling is shareable between studies in an app context. Study administrators can manually assign participants to study arms, but a protocol will also contain an allocation strategy to do this (see Allocation below).

Method

Path

Description

Method

Path

Description

GET

/v1/protocols/{guid}/timelines

Get a list of study arms or provisos for this protocol

POST

/v1/protocols/{guid}/timelines

Add a study arm or proviso to this protocol

DELETE

/v1/protocols/{guid}/timelines/{id}

Delete a study arm or proviso (subject to the state of the studies that include this protocol)

GET

/v1/protocols/{guid}/timelines/{id}/members

Get a paged list of accounts assigned to this study arm or protocol

POST

/v1/protocols/{guid}/timelines/{id}/members

Add an account to this study arm or proviso

DELETE

/v1/protocols/{guid}/timelines/{id}/members/{userId}

Remove an account from this study arm or proviso

POST

/v1/protocols/{guid}/provisos/{id}/self

API for a client to add participant to a proviso. Returns user session.

DELETE

/v1/protocols/{guid}/provisos/{id}/self

API for a client to remove a participant from a proviso. Returns user session.

GET

/v1/protocols/{guid}/studyarms/pseudonyms

Get the mapping from pseudonyms to actual study arms, once study blinding is no longer necessary. We can enforce role or lifecycle limitations to accessing this API, if desired. Pseudonyms are not available from any other API; all data is exported using only the pseudonym.

Note: study arms and protocols use human-entered and human-readable identifiers, so their IDs are scoped to a specific protocol. Hence they must be nested under protocols in the API.

Assessments

Assessments have been described in Assessments, shared assessments, and their resources and tags and in Assessment Configuration API. Assessments are mostly done with the caveat that there will be requests for changes as they are put to use.

Scheduling

Scheduling has been described in Scheduling API (Bridge v2; API v5). Scheduling requires everything in this document to be implemented that is not related to consent.

Java Domain Model

After a couple of years of using Hibernate for a REST-based API, I’ve developed the opinion that while the database should express all the relationships and constraints between entities, the Hibernate-managed Java objects probably shouldn’t map the relationships. Rather than updating a dependent object in an object graph, there should be a separate REST API. The models reflect this in ignoring many cases where we could use @OneToMany or @ManyToOne, etc. relationships.

App

Organization

Membership

This is probably a simple associative table and not a domain model (unless we end up assigning roles as part of membership):

Study

Where we have already used the word “Study” in database or DynamoDB tables, I would propose we use “AppStudy” to differentiate this new version of a study. Everywhere else, we use study.

Recruitment, characteristic definitions, and characteristics.

Enrollment

Protocol

Finally, Timeline subclasses (StudyArm and Proviso) are stored using single table inheritance:

Security Changes

App Administrator

Very few people should have this capability, but more people than Dwayne and Alx. This person can change the shared configuration of an app, which for some apps could be disruptive to other studies or organizations. We have also called this person a “study administrator” but we may need to differentiate these two things.

Organization Administrators

This is a study administrator who can build out and control their organization’s capabilities in Bridge. They do not see study participants and they cannot edit study/app configuration:

Capabilities:

  1. create a new account attached to an organization;

  2. add an account to an organization that's not currently affiliated with an org;

  3. edit an account in the org admin's organization;

  4. remove an account from the org admin’s organization;

  5. delete an account IF it's associated to the org admin's organization;

  6. create a new study that is sponsored by the org admin's organization (developers in an organization presumably can do this as well).

Study Coordinators

Study coordinators are researchers who can only act on participants in studies they are associated to through their organizational membership. They have a distinct set of participant APIs under the /v5/studies/{studyId}/participants pathway for this purpose (initially, all the relevant APIs from the /v3/participants pathway, scoped accordingly…researchers can also use these APIs as they are conceived to be a superset of all study coordinators in an app). It also appears from MTB designs that study coordinators may be able to set up aspects of a study’s protocol, such as the schedules and study arms (TBD).

SDK Changes

We’re ready to remove a few APIs, either because they’re unused, or because they have been replaced:

  • shared modules

  • compound tasks

  • substudy APIs

I am maintaining a document on developer.sagebridge.org that explains what we are doing during this transition period.

SQL

The SQL for these elements:

Questions

  • What are the visibility and access rules for studies, consents, requirement, and protocols? I am indifferent to a solution here, it just needs to work for researchers.

  • I’m proposing roles remain global for an app… if you are a developer, you are a developer in all studies your organization has access to. Refactoring this would be very significant for us across all existing APIs, but let’s discuss this.

  • Where should eligibility be associated? To a study, to recruitment, or even to a consent? Is it reusable in any way?

  • Is there one org that “owns” the study vs. more than one that contributes to it (participants, analysis)? There’s usually at least two organizations: Sage and a partner.

  • If email/phone number could be provided when signing in, could we stop creating accounts with external ID + password? (I don’t have a problem with them except for the fact that the password is usually static and reused across accounts, rendering it pointless.)

  • Is it necessary to maintain different sharing scopes for different studies, or can this remain global to a user?

  • Have we ever had a case where accounts 1) used external IDs only; and also 2) consented through Bridge’s electronic consent system? I don’t believe this has ever come up, and would change the proposed Enrollment record design.

  • Are we collecting the information we need to really aid recruitment (requirements on this are weak);

  • How will this interact with the new exporter system. In particular, are we carrying over enough metadata to meet the highest bar of tracing.