Skip to main content

CTMS RBAC Data Model

This document provides a comprehensive reference for the RBAC (Role-Based Access Control) data model used in the HB Life Science CTMS platform. It covers all roles, resources, actions, and the conventions used for permission record naming.


Overview

The RBAC system is built on four core DocTypes in Frappe that work together to create a flexible permission matrix:

🔐 Permission = Role + Resource + Action + is_enabled

A permission record defines whether a specific role can perform a specific action on a specific resource.


Core DocTypes

CTMS Role

Defines the user roles in the system. Each user is assigned exactly one role.

Role NameDescriptionPrimary Responsibilities
Platform AdministratorFull system accessSystem configuration, user management, all study operations
Study DesignerStudy setup and configurationCreate studies, design CRFs, define protocols
Study CoordinatorDay-to-day study operationsSubject enrollment, data entry, visit scheduling
Data ManagerData quality and exportsQuery resolution, data validation, exports
Medical MonitorSafety oversightReview adverse events, medical data review
AuditorRead-only access for complianceView all data without modification

CTMS Resource

Resources are the protected entities in the system. Each resource maps to a module or feature area.

CTMS Action

Actions are the operations that can be performed on resources.

ActionDescriptionTypical Usage
createCreate new recordsAdd buttons, new record forms
readView recordsPage access, data display
updateModify existing recordsEdit buttons, inline editing
deleteRemove single recordsDelete button in table rows
bulk_deleteRemove multiple recordsBulk delete with checkboxes
exportExport dataExport to CSV/Excel buttons
generateGenerate records/reportsGenerate CRF, Generate Report

CTMS Permission

The junction table that combines Role + Resource + Action with an enabled/disabled flag.


Resource Categories

Resources are organized into three functional categories for easier navigation:

1. Administration Resources

System-wide configuration and management resources.

ResourceDescriptionExample Permissions
studyClinical studies/trialsCreate studies, update status, delete
siteTrial sites/locationsAdd sites, assign personnel
personnelStudy team membersAdd coordinators, investigators
reportSystem reportsGenerate enrollment reports

2. Design Resources

Study design and protocol configuration resources.

ResourceDescriptionExample Permissions
eventsStudy events/visitsDefine screening, week 1, etc.
eligibilityInclusion/exclusion criteriaConfigure eligibility rules
ecrf_designerElectronic CRF builderDesign data collection forms
overviewStudy overview/dashboardView study summary

3. Execution Resources

Day-to-day study operations resources.

ResourceDescriptionExample Permissions
subjectStudy subjects (participants)Enroll, update status, withdraw
patientPatient master recordsCreate patient records
crfCase Report Form dataEnter CRF data
consentConsent formsRecord consent
demographicsSubject demographicsView/edit demographics
vitalsVital signsRecord vitals
physical_examinationPhysical exam findingsRecord exam data
adverse_eventsAdverse event reportsReport AEs, update severity
family_medical_historyFamily health historyRecord family history
social_historySocial historyRecord lifestyle data
medical_historyMedical historyRecord past conditions
concomitant_medicationsConcurrent medicationsRecord medications
prescriptionsStudy drug prescriptionsIssue prescriptions
lab_ordersLaboratory ordersOrder lab tests
lab_resultsLaboratory resultsView/enter results
study_siteStudy-site relationshipsAssign sites to studies
study_subjectStudy-subject relationshipsManage subject enrollment

Complete Resource Reference

All resources currently defined in the system:

const ALL_RESOURCES = [
// Administration
'study',
'site',
'personnel',
'report',

// Design
'events',
'eligibility',
'ecrf_designer',
'overview',

// Execution
'subject',
'patient',
'crf',
'consent',
'demographics',
'vitals',
'physical_examination',
'adverse_events',
'family_medical_history',
'social_history',
'medical_history',
'concomitant_medications',
'prescriptions',
'lab_orders',
'lab_results',
'study_site',
'study_subject'
];

Naming Conventions

Permission Record Names

Each permission record follows a strict naming convention:

{Role}-{resource}-{action}

Examples:

  • Platform Administrator-study-create
  • Study Designer-events-update
  • Study Coordinator-subject-bulk_delete
  • Data Manager-crf-export
  • Auditor-adverse_events-read

Key Rules

RuleDescriptionExample
Role namesUse display name with spaces"Study Coordinator" not "study_coordinator"
Resource namesUse snake_case"adverse_events" not "AdverseEvents"
Action namesUse snake_case"bulk_delete" not "bulkDelete"
SeparatorSingle hyphen between partsRole-resource-action

Name Parsing

The permission name can be parsed to extract components:

function parsePermissionName(name: string) {
// Find last two hyphens (action is last, resource is second-to-last)
const lastHyphen = name.lastIndexOf('-');
const secondLastHyphen = name.lastIndexOf('-', lastHyphen - 1);

return {
role: name.substring(0, secondLastHyphen), // "Study Coordinator"
resource: name.substring(secondLastHyphen + 1, lastHyphen), // "subject"
action: name.substring(lastHyphen + 1) // "bulk_delete"
};
}

Permission Matrix

Matrix Structure

Permissions are organized into a 3-dimensional matrix:

Role → Resource → Action → is_enabled

Example for Study Coordinator:

Resourcecreatereadupdatedeletebulk_deleteexport
subject
crf
vitals
study

Total Permission Records

The total number of permission records is calculated as:

Total = Roles × Resources × Actions
= 6 × 21 × 8
= ~1,008 possible combinations

However, not all combinations are meaningful. The actual number of records depends on which resources support which actions.


Action Availability by Resource

Not all actions apply to all resources. Here's the typical action availability:

Full CRUD Resources

Resources that support all actions:

  • subject, patient, site, personnel
  • vitals, adverse_events, prescriptions
  • lab_orders, lab_results
Actions: create, read, update, delete, bulk_delete, export

Read-Heavy Resources

Resources with limited write actions:

  • report (read, generate)
  • overview (read only)

Design Resources

Resources for study configuration:

  • events, eligibility, ecrf_designer
  • Actions: create, read, update, delete

Role Permission Patterns

Platform Administrator

Full access to everything:

All Resources → All Actions → is_enabled: true

Study Designer

Focus on study setup and design:

Administration: Full CRUD
Design: Full CRUD
Execution: Read only (mostly)

Study Coordinator

Focus on day-to-day operations:

Administration: Read only
Design: Read only
Execution: Full CRUD (except delete for sensitive data)

Auditor

Read-only across the board:

All Resources → read → is_enabled: true
All Resources → other actions → is_enabled: false

API Reference

Fetch All Permissions

GET /api/v1/doctype/CTMS Permission
?limit_page_length=0
&fields=["name","role","resource","action","is_enabled"]

Fetch Permissions by Role

GET /api/v1/doctype/CTMS Permission
?filters=[["role","=","Study Coordinator"]]
&limit_page_length=0

Update Permission

PUT /api/v1/doctype/CTMS Permission/{name}
Content-Type: application/json

{
"is_enabled": 1
}

Batch Create Permissions

# Using the bot_sync_permissions_to_frappe.py script
python scripts/bot_sync_permissions_to_frappe.py

Database Schema

The underlying Frappe database tables:

tabCTMS Role

ColumnTypeDescription
nameVARCHAR(140)Primary key (role name)
descriptionTEXTRole description
creationDATETIMECreated timestamp
modifiedDATETIMELast modified

tabCTMS Resource

ColumnTypeDescription
nameVARCHAR(140)Primary key (resource name)
descriptionTEXTResource description
categoryVARCHAR(140)Administration, Design, Execution
display_orderINTSort order in UI

tabCTMS Action

ColumnTypeDescription
nameVARCHAR(140)Primary key (action name)
descriptionTEXTAction description

tabCTMS Permission

ColumnTypeDescription
nameVARCHAR(140)Primary key (Role-resource-action)
roleVARCHAR(140)Foreign key to CTMS Role
resourceVARCHAR(140)Foreign key to CTMS Resource
actionVARCHAR(140)Foreign key to CTMS Action
is_enabledINT0 = disabled, 1 = enabled

Seeding Permissions

When setting up a new environment, permissions are seeded using the sync script:

# Run the permission seeder
cd scripts
python bot_sync_permissions_to_frappe.py

The seeder creates all required permission records based on the ACTION_PERMISSIONS configuration.

Seeder Configuration

ACTION_PERMISSIONS = {
'study': {
'create': [ADMIN, STUDY_DESIGNER],
'read': [], # Empty = all roles
'update': [ADMIN, STUDY_DESIGNER],
'delete': [ADMIN],
'export': [ADMIN, STUDY_DESIGNER, DATA_MANAGER],
},
'subject': {
'create': [ADMIN, STUDY_DESIGNER, STUDY_COORDINATOR],
'read': [],
'update': [ADMIN, STUDY_DESIGNER, STUDY_COORDINATOR],
'delete': [ADMIN],
'bulk_delete': [ADMIN],
},
# ... more resources
}

Troubleshooting

Permission Record Not Found

If the UI shows "Permission record not found":

  1. Check if the record exists in Frappe
  2. Run the sync script to create missing records
  3. Verify the naming convention matches

Permission Not Working

If permission changes don't take effect:

  1. Clear browser cache (permissions are cached)
  2. Check API response for cache headers
  3. Verify is_enabled is set to 1 (not 0)

Missing Resource in UI

If a resource doesn't appear in the permission management UI:

  1. Create the CTMS Resource record in Frappe
  2. Assign a category (Administration, Design, or Execution)
  3. Run the sync script to create permission records