HH/docs/STAFF_USER_ACCOUNT_FEATURE_SUMMARY.md

11 KiB

Staff User Account Feature - Complete Implementation Summary

Overview

The Staff model has an optional one-to-one relation with the User model, enabling staff members to have user accounts for system login and access. This document provides a complete overview of the implementation.

Database Model

Staff Model (apps/organizations/models.py)

class Staff(UUIDModel, TimeStampedModel):
    # Optional one-to-one relation with User
    user = models.OneToOneField(
        'accounts.User',
        on_delete=models.SET_NULL,
        null=True, blank=True,
        related_name='staff_profile'
    )
    
    # Staff details
    first_name = models.CharField(max_length=100)
    last_name = models.CharField(max_length=100)
    first_name_ar = models.CharField(max_length=100, blank=True)
    last_name_ar = models.CharField(max_length=100, blank=True)
    
    staff_type = models.CharField(max_length=20, choices=StaffType.choices)
    job_title = models.CharField(max_length=200)
    license_number = models.CharField(max_length=100, unique=True, null=True, blank=True)
    specialization = models.CharField(max_length=200, blank=True)
    email = models.EmailField(blank=True)
    employee_id = models.CharField(max_length=50, unique=True, db_index=True)
    
    hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, related_name='staff')
    department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True, blank=True, related_name='staff')
    status = models.CharField(max_length=20, choices=StatusChoices.choices, default=StatusChoices.ACTIVE)

Key Points:

  • The user field is optional (null=True, blank=True)
  • Uses SET_NULL on deletion to preserve staff records if user is deleted
  • Staff without user accounts can exist in the system

CRUD Operations

API Endpoints (/organizations/api/staff/)

Method Endpoint Description Permissions
GET /api/staff/ List all staff (filtered by user role) Authenticated
POST /api/staff/ Create new staff (with optional user account) PX/Hospital Admin
GET /api/staff/{id}/ Get staff details Authenticated
PUT/PATCH /api/staff/{id}/ Update staff PX/Hospital Admin
DELETE /api/staff/{id}/ Delete staff PX/Hospital Admin

Special Actions

Method Endpoint Description Permissions
POST /api/staff/{id}/create_user_account/ Create user account for staff PX/Hospital Admin
POST /api/staff/{id}/link_user/ Link existing user to staff PX/Hospital Admin
POST /api/staff/{id}/unlink_user/ Unlink user from staff PX/Hospital Admin
POST /api/staff/{id}/send_invitation/ Resend credentials email PX/Hospital Admin

User Account Creation

Methods

1. Create User Account via API

POST /organizations/api/staff/{staff_id}/create_user_account/

Response:

{
  "message": "User account created and credentials emailed successfully",
  "staff": { ... },
  "email": "staff@example.com"
}

2. Create User Account during Staff Creation

POST /organizations/api/staff/

Request Body:

{
  "first_name": "John",
  "last_name": "Doe",
  "staff_type": "physician",
  "job_title": "Cardiologist",
  "hospital": "uuid",
  "department": "uuid",
  "email": "john.doe@example.com",
  "employee_id": "EMP123",
  "create_user": true,
  "send_email": true
}

3. Create User Account via Serializer (Backend)

from apps.organizations.services import StaffService

# Create user account
user, password = StaffService.create_user_for_staff(
    staff, 
    role='staff', 
    request=request
)

# Send credentials email
StaffService.send_credentials_email(staff, password, request)

StaffService Methods

StaffService.create_user_for_staff(staff, role='staff', request=None)

Creates a user account for a staff member.

Process:

  1. Validates staff doesn't already have a user account
  2. Checks staff has an email address
  3. Generates unique username: {first_name}.{last_name} (lowercase)
  4. Generates secure random password (12 characters)
  5. Creates User account with email as username
  6. Assigns appropriate role (staff)
  7. Links User to Staff
  8. Logs audit event

Returns: User instance

Raises: ValueError if staff already has user account or no email

Links an existing user account to a staff member.

Process:

  1. Validates staff doesn't already have a user account
  2. Finds user by ID
  3. Links user to staff
  4. Updates user's organization data (hospital, department, employee_id)
  5. Logs audit event

Returns: Updated Staff instance

Raises: ValueError if staff has user account or user not found

Removes user account association from a staff member.

Process:

  1. Validates staff has a user account
  2. Unlinks user (sets staff.user = None)
  3. Logs audit event

Returns: Updated Staff instance

Raises: ValueError if staff has no user account

StaffService.send_credentials_email(staff, password, request)

Sends login credentials email to staff member.

Process:

  1. Validates staff has email and user account
  2. Builds login URL
  3. Renders email template
  4. Sends email via Django's send_mail
  5. Logs audit event

Raises: ValueError if no email or user account

StaffService.generate_username(staff)

Generates a unique username from staff name.

Format: {first_name}.{last_name} (lowercase) Duplicate Handling: Appends number if duplicate exists

Example:

  • john.doe
  • john.doe1 (if duplicate)
  • john.doe2 (if two duplicates)

StaffService.generate_password(length=12)

Generates a secure random password.

Characters: Letters (uppercase/lowercase), digits, punctuation Default Length: 12 characters

Staff Login

Login Process

Staff members with user accounts can log in through the standard authentication system:

  1. Login URL: /accounts/login/
  2. Credentials:
    • Username: Email address
    • Password: Generated password (or changed password)

Access Control

Staff user accounts have the following characteristics:

  • Role: Automatically assigned 'staff' role
  • Permissions: Can view complaints, hospitals, departments relevant to their organization
  • Hospital/Department: Automatically populated from staff profile
  • Employee ID: Automatically populated from staff profile

Email Template

Template: templates/organizations/emails/staff_credentials.html

Content:

  • Professional welcome message
  • Login credentials (username, password, email)
  • Security notice to change password
  • Direct login button
  • Professional styling with purple gradient

Example Email:

Subject: Your PX360 Account Credentials

Dear John Doe,

Your PX360 account has been created successfully. Below are your login credentials:

Username: john.doe
Password: Abc123!@#XyZ
Email: john.doe@example.com

⚠️ Security Notice: Please change your password after your first login.

[Login to PX360 Button]

Best regards,
The PX360 Team

Permissions

Creating/Managing Staff User Accounts

  • PX Admins: Can create/manage user accounts for any staff
  • Hospital Admins: Can create/manage user accounts for staff in their hospital only
  • Others: View-only access

Data Access

  • PX Admins: Can view all staff
  • Hospital Admins: Can view staff in their hospital
  • Department Managers: Can view staff in their department
  • Staff: Can view staff in their hospital

Example Workflows

Workflow 1: Create Staff with User Account

# 1. Create staff with user account
POST /organizations/api/staff/
{
  "first_name": "Sarah",
  "last_name": "Smith",
  "staff_type": "nurse",
  "job_title": "Senior Nurse",
  "hospital": "uuid",
  "department": "uuid",
  "email": "sarah.smith@example.com",
  "employee_id": "NURSE001",
  "create_user": true,
  "send_email": true
}

# Response: User account created and email sent automatically

Workflow 2: Create Staff, Then Add User Account Later

# 1. Create staff without user account
POST /organizations/api/staff/
{
  "first_name": "Dr. Ahmed",
  "last_name": "Al-Rashid",
  "staff_type": "physician",
  "job_title": "Cardiologist",
  "hospital": "uuid",
  "department": "uuid",
  "email": "ahmed.alrashid@example.com",
  "employee_id": "PHYS001"
}

# 2. Later, create user account
POST /organizations/api/staff/{staff_id}/create_user_account/

# Response: User account created and credentials emailed
# If user account already exists separately
POST /organizations/api/staff/{staff_id}/link_user/
{
  "user_id": "existing-user-uuid"
}

# Response: User linked successfully

Workflow 4: Staff Login

# Staff member receives email with credentials
# They login at /accounts/login/

# After first login, they should change password
# via /accounts/password_change/ or settings page

Security Considerations

  1. Password Generation: Uses cryptographically secure random generation
  2. Email Security: Credentials sent via email (consider requiring password change on first login)
  3. Access Control: Role-based permissions prevent unauthorized access
  4. Audit Logging: All user account operations are logged for audit trail
  5. Unique Email: Email addresses must be unique across user accounts

Testing

Test Creating Staff with User Account

from apps.organizations.models import Staff, Hospital, Department
from apps.organizations.services import StaffService

# Create staff
staff = Staff.objects.create(
    first_name="Test",
    last_name="User",
    staff_type="physician",
    job_title="Test Doctor",
    hospital=hospital,
    department=department,
    email="test@example.com",
    employee_id="TEST001"
)

# Create user account
user, password = StaffService.create_user_for_staff(staff, role='staff')

# Verify
assert staff.user == user
assert user.email == "test@example.com"
assert user.is_staff  # or appropriate role

Test Staff Login

from django.contrib.auth import authenticate
from apps.accounts.models import User

# Authenticate
user = authenticate(username="test@example.com", password=password)

# Verify
assert user is not None
assert user.staff_profile == staff

Summary

The Staff-User relationship implementation provides:

Optional one-to-one relation between Staff and User models Full CRUD operations for staff management via API Multiple methods to create user accounts:

  • During staff creation
  • Via dedicated endpoint
  • Via backend service Automatic credential generation (username and password) Email notification with credentials Role-based permissions for access control Audit logging for all operations Staff login capability via standard authentication Professional email template for credentials delivery Link/unlink functionality for existing users

All functionality is production-ready and tested.