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 Name | Description | Primary Responsibilities |
|---|---|---|
| Platform Administrator | Full system access | System configuration, user management, all study operations |
| Study Designer | Study setup and configuration | Create studies, design CRFs, define protocols |
| Study Coordinator | Day-to-day study operations | Subject enrollment, data entry, visit scheduling |
| Data Manager | Data quality and exports | Query resolution, data validation, exports |
| Medical Monitor | Safety oversight | Review adverse events, medical data review |
| Auditor | Read-only access for compliance | View 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.
| Action | Description | Typical Usage |
|---|---|---|
create | Create new records | Add buttons, new record forms |
read | View records | Page access, data display |
update | Modify existing records | Edit buttons, inline editing |
delete | Remove single records | Delete button in table rows |
bulk_delete | Remove multiple records | Bulk delete with checkboxes |
export | Export data | Export to CSV/Excel buttons |
generate | Generate records/reports | Generate 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.
| Resource | Description | Example Permissions |
|---|---|---|
study | Clinical studies/trials | Create studies, update status, delete |
site | Trial sites/locations | Add sites, assign personnel |
personnel | Study team members | Add coordinators, investigators |
report | System reports | Generate enrollment reports |
2. Design Resources
Study design and protocol configuration resources.
| Resource | Description | Example Permissions |
|---|---|---|
events | Study events/visits | Define screening, week 1, etc. |
eligibility | Inclusion/exclusion criteria | Configure eligibility rules |
ecrf_designer | Electronic CRF builder | Design data collection forms |
overview | Study overview/dashboard | View study summary |
3. Execution Resources
Day-to-day study operations resources.
| Resource | Description | Example Permissions |
|---|---|---|
subject | Study subjects (participants) | Enroll, update status, withdraw |
patient | Patient master records | Create patient records |
crf | Case Report Form data | Enter CRF data |
consent | Consent forms | Record consent |
demographics | Subject demographics | View/edit demographics |
vitals | Vital signs | Record vitals |
physical_examination | Physical exam findings | Record exam data |
adverse_events | Adverse event reports | Report AEs, update severity |
family_medical_history | Family health history | Record family history |
social_history | Social history | Record lifestyle data |
medical_history | Medical history | Record past conditions |
concomitant_medications | Concurrent medications | Record medications |
prescriptions | Study drug prescriptions | Issue prescriptions |
lab_orders | Laboratory orders | Order lab tests |
lab_results | Laboratory results | View/enter results |
study_site | Study-site relationships | Assign sites to studies |
study_subject | Study-subject relationships | Manage 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-createStudy Designer-events-updateStudy Coordinator-subject-bulk_deleteData Manager-crf-exportAuditor-adverse_events-read
Key Rules
| Rule | Description | Example |
|---|---|---|
| Role names | Use display name with spaces | "Study Coordinator" not "study_coordinator" |
| Resource names | Use snake_case | "adverse_events" not "AdverseEvents" |
| Action names | Use snake_case | "bulk_delete" not "bulkDelete" |
| Separator | Single hyphen between parts | Role-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:
| Resource | create | read | update | delete | bulk_delete | export |
|---|---|---|---|---|---|---|
| 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,personnelvitals,adverse_events,prescriptionslab_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
| Column | Type | Description |
|---|---|---|
| name | VARCHAR(140) | Primary key (role name) |
| description | TEXT | Role description |
| creation | DATETIME | Created timestamp |
| modified | DATETIME | Last modified |
tabCTMS Resource
| Column | Type | Description |
|---|---|---|
| name | VARCHAR(140) | Primary key (resource name) |
| description | TEXT | Resource description |
| category | VARCHAR(140) | Administration, Design, Execution |
| display_order | INT | Sort order in UI |
tabCTMS Action
| Column | Type | Description |
|---|---|---|
| name | VARCHAR(140) | Primary key (action name) |
| description | TEXT | Action description |
tabCTMS Permission
| Column | Type | Description |
|---|---|---|
| name | VARCHAR(140) | Primary key (Role-resource-action) |
| role | VARCHAR(140) | Foreign key to CTMS Role |
| resource | VARCHAR(140) | Foreign key to CTMS Resource |
| action | VARCHAR(140) | Foreign key to CTMS Action |
| is_enabled | INT | 0 = 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":
- Check if the record exists in Frappe
- Run the sync script to create missing records
- Verify the naming convention matches
Permission Not Working
If permission changes don't take effect:
- Clear browser cache (permissions are cached)
- Check API response for cache headers
- Verify is_enabled is set to 1 (not 0)
Missing Resource in UI
If a resource doesn't appear in the permission management UI:
- Create the CTMS Resource record in Frappe
- Assign a category (Administration, Design, or Execution)
- Run the sync script to create permission records
Related Documentation
- RBAC System Architecture - Technical implementation details
- Permission Management - User guide for managing permissions
- CTMS Domain Model - Entity relationships