HH/apps/accounts/management/commands/create_default_roles.py
ismail c5f76b3855
Some checks are pending
Build and Push Docker Image / build (push) Waiting to run
updates
2026-05-11 14:45:30 +03:00

209 lines
8.2 KiB
Python

"""
Management command to create default roles and groups for PX360.
"""
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
from django.core.management.base import BaseCommand
from apps.accounts.models import Role
class Command(BaseCommand):
help = "Create default roles and groups for PX360 system"
def handle(self, *args, **options):
"""Create default roles"""
roles_config = [
{
"name": "px_admin",
"display_name": "PX Admin",
"description": "Full system access. Can manage all hospitals, departments, and configurations.",
"level": 100,
},
{
"name": "hospital_admin",
"display_name": "Hospital Admin",
"description": "Hospital-level access. Can manage their hospital and its departments.",
"level": 80,
},
{
"name": "department_manager",
"display_name": "Department Manager",
"description": "Department-level access. Can manage their department.",
"level": 60,
},
{
"name": "champion",
"display_name": "Champion",
"description": "Can respond to inquiries and view complaints for their assigned department.",
"level": 55,
},
{
"name": "director",
"display_name": "Director",
"description": "Multi-department access. Can view data for departments where their direct reports (via report_to) work.",
"level": 70,
},
{
"name": "px_management",
"display_name": "PX Management",
"description": "Can manage PX actions, complaints, and surveys.",
"level": 50,
},
{
"name": "px_employee",
"display_name": "PX Employee",
"description": "Can work with complaints, inquiries, observations, appreciation, suggestions, QI projects, departments, staff surveys, physician dashboard, government tickets, communication requests, and reports. View-only access to references and standards.",
"level": 40,
},
{
"name": "staff",
"display_name": "Staff",
"description": "Basic staff access.",
"level": 20,
},
{
"name": "viewer",
"display_name": "Viewer",
"description": "Read-only access to reports and dashboards.",
"level": 10,
},
{
"name": "executive",
"display_name": "Executive",
"description": "C-Suite and top management. System-wide analytics, executive summaries, and predictive insights access.",
"level": 90,
},
{
"name": "px_source_user",
"display_name": "PX Source User",
"description": "External source users who can create complaints and inquiries from their assigned source. Limited access to their own created data only.",
"level": 5,
},
]
created_count = 0
updated_count = 0
for role_data in roles_config:
# Get or create group
group, group_created = Group.objects.get_or_create(name=role_data["display_name"])
if group_created:
self.stdout.write(self.style.SUCCESS(f"Created group: {group.name}"))
# Get or create role
role, role_created = Role.objects.get_or_create(
name=role_data["name"],
defaults={
"display_name": role_data["display_name"],
"description": role_data["description"],
"group": group,
"level": role_data["level"],
},
)
if role_created:
created_count += 1
self.stdout.write(self.style.SUCCESS(f"✓ Created role: {role.display_name} (level {role.level})"))
else:
# Update existing role
role.display_name = role_data["display_name"]
role.description = role_data["description"]
role.level = role_data["level"]
role.group = group
role.save()
updated_count += 1
self.stdout.write(self.style.WARNING(f"↻ Updated role: {role.display_name}"))
# Assign permissions based on role level
self._assign_permissions(role, group)
self.stdout.write(
self.style.SUCCESS(f"\n✓ Roles setup complete: {created_count} created, {updated_count} updated")
)
self.stdout.write(self.style.SUCCESS(f"Total roles: {Role.objects.count()}"))
def _assign_permissions(self, role, group):
"""
Assign permissions to group based on role level.
This is a basic implementation - expand as needed.
"""
# Clear existing permissions
group.permissions.clear()
# Get all permissions
all_permissions = Permission.objects.all()
# PX Admin gets all permissions
if role.name == "px_admin":
group.permissions.set(all_permissions)
return
# Hospital Admin gets most permissions except user management
if role.name == "hospital_admin":
permissions = Permission.objects.exclude(
content_type__app_label="auth", codename__in=["add_user", "delete_user", "change_user"]
)
group.permissions.set(permissions)
return
# Department Manager gets department-level permissions
if role.name == "department_manager":
# Add view permissions for most models
view_permissions = Permission.objects.filter(codename__startswith="view_")
group.permissions.set(view_permissions)
return
# Director gets view permissions (same as Department Manager)
if role.name == "director":
view_permissions = Permission.objects.filter(codename__startswith="view_")
group.permissions.set(view_permissions)
return
# Department Respondent gets view + inquiry response permissions
if role.name == "department_respondent":
respondent_permissions = Permission.objects.filter(
content_type__app_label__in=["complaints", "organizations", "observations"],
codename__startswith="view_",
)
group.permissions.set(respondent_permissions)
return
# PX Employee gets complaint and action permissions
if role.name == "px_employee":
staff_permissions = Permission.objects.filter(
content_type__app_label__in=["complaints", "px_action_center", "surveys"]
)
group.permissions.set(staff_permissions)
return
# Executive gets view permissions system-wide + executive_summary access
if role.name == "executive":
view_permissions = Permission.objects.filter(codename__startswith="view_")
exec_perms = Permission.objects.filter(content_type__app_label="executive_summary")
group.permissions.set(list(view_permissions) + list(exec_perms))
return
# PX Source User gets limited complaint/inquiry permissions
if role.name == "px_source_user":
source_user_perms = Permission.objects.filter(
content_type__app_label__in=["complaints"],
codename__in=[
"add_complaint",
"view_complaint",
"change_complaint",
"add_inquiry",
"view_inquiry",
"change_inquiry",
],
)
group.permissions.set(source_user_perms)
return
# Others get basic view permissions
view_permissions = Permission.objects.filter(codename__startswith="view_")
group.permissions.set(view_permissions)