14 KiB
Staff User Account Feature - Implementation Summary
Overview
This document provides a comprehensive summary of the Staff User Account feature implementation, including the optional one-to-one relation with the User model, CRUD operations, and login functionality for staff members.
Feature Components
1. Staff-User One-to-One Relation
File: apps/organizations/models.py
The Staff model has an optional one-to-one relation with the User model:
class Staff(UUIDModel, TimeStampedModel):
# Link to User (Keep it optional for external/temp staff)
user = models.OneToOneField(
'accounts.User',
on_delete=models.SET_NULL,
null=True, blank=True,
related_name='staff_profile'
)
Key Features:
- Optional relation (allows external/temp staff without user accounts)
- Uses
SET_NULLon delete (staff profile remains if user is deleted) - Provides reverse relation via
user.staff_profile
2. Custom UserManager
File: apps/accounts/models.py
Implemented a custom UserManager to support email-based authentication:
class UserManager(BaseUserManager):
"""Custom user manager for email-based authentication."""
def create_user(self, email, password=None, **extra_fields):
"""Create and save a regular user with the given email and password."""
if not email:
raise ValueError('The Email field must be set')
email = self.normalize_email(email)
user = self.model(email=email, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_superuser(self, email, password=None, **extra_fields):
"""Create and save a superuser with the given email and password."""
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(email, password, **extra_fields)
3. StaffService
File: apps/organizations/services.py
Provides comprehensive staff user account management:
Key Methods:
-
create_user_for_staff()
- Creates a user account for a staff member
- Generates username and password
- Assigns appropriate role
- Links user to staff profile
- Logs the action for audit trail
-
link_user_to_staff()
- Links an existing user account to a staff member
- Updates user's organization data
-
unlink_user_from_staff()
- Removes user account association from staff member
-
send_credentials_email()
- Sends login credentials email to staff member
- Includes generated password and login URL
-
generate_username()
- Generates unique username from staff name
- Format:
first.last(lowercase) - Appends number if duplicate exists
-
generate_password()
- Generates secure random password (12 characters)
- Includes letters, numbers, and special characters
-
get_staff_type_role()
- Maps staff type to role name
- Currently all staff get 'staff' role
4. API Endpoints
File: apps/organizations/views.py
StaffViewSet - CRUD Operations
Base CRUD:
GET /api/staff/- List all staff (filtered by user role)POST /api/staff/- Create new staff memberGET /api/staff/{id}/- Retrieve staff detailsPUT /api/staff/{id}/- Update staff memberPATCH /api/staff/{id}/- Partially update staff memberDELETE /api/staff/{id}/- Delete staff member
User Account Actions:
-
Create User Account
POST /api/staff/{id}/create_user_account/- Creates a user account for staff member
- Auto-generates username and password
- Sends credentials email
- Body:
{ "role": "staff" }(optional)
-
Link Existing User
POST /api/staff/{id}/link_user/- Links an existing user account to staff
- Body:
{ "user_id": "uuid" }
-
Unlink User
POST /api/staff/{id}/unlink_user/- Removes user account association
-
Send Invitation
POST /api/staff/{id}/send_invitation/- Generates new password
- Sends credentials email
Filtering & Search:
- Filter by:
status,hospital,department,staff_type,specialization,job_title,hospital__organization - Search by:
first_name,last_name,first_name_ar,last_name_ar,employee_id,license_number,job_title - Order by:
last_name,created_at
Permissions:
- PX Admins: Full access to all staff
- Hospital Admins: Full access to staff in their hospital
- Department Managers: Read-only access to staff in their department
- Others: Read-only access to staff in their hospital
5. Management Commands
File: apps/organizations/management/commands/seed_staff.py
Command Options:
python manage.py seed_staff [options]
Options:
--hospital-code: Target hospital code (default: all hospitals)--count: Number of staff to create per type (default: 10)--physicians: Number of physicians to create (default: 10)--nurses: Number of nurses to create (default: 15)--admin-staff: Number of admin staff to create (default: 5)--create-users: Create user accounts for staff--send-emails: Send credential emails to newly created users--clear: Clear existing staff first--dry-run: Preview without making changes
Examples:
# Create staff without users
python manage.py seed_staff --physicians 5 --nurses 10
# Create staff with user accounts
python manage.py seed_staff --physicians 5 --nurses 10 --create-users
# Create staff with user accounts and send emails
python manage.py seed_staff --physicians 5 --nurses 10 --create-users --send-emails
# Dry run to preview
python manage.py seed_staff --physicians 5 --dry-run
# Clear and recreate staff
python manage.py seed_staff --clear --physicians 5
6. Email Templates
File: templates/organizations/emails/staff_credentials.html
Professional HTML email template for sending staff credentials.
Template Variables:
staff: Staff instanceuser: User instancepassword: Generated passwordlogin_url: Absolute login URL
7. Database Migrations
Migration: apps/accounts/migrations/0004_alter_user_managers_and_more.py
Changes applied:
- Changed manager on User model to custom UserManager
- Made
usernamefield optional and non-unique - Updated
acknowledgement_completed_atfield
User Authentication Flow
Staff Login Process
-
Account Creation:
- Staff member is created in the system
- Admin creates user account via API or management command
- Password is generated and sent via email
-
Login:
- Staff member logs in using their email address
- Password is verified against hashed password in database
- Session is established
-
Access:
- User's role determines permissions
- Staff profile is accessible via
request.user.staff_profile - Organization context is available via
request.user.hospital
Permission Model
Staff User Roles
All staff members are assigned to the 'staff' role by default. The role system is flexible and can be extended to support:
- Physicians
- Nurses
- Administrative staff
- Department managers
- Hospital administrators
Role-Based Access Control
PX Admin:
- Can manage all organizations, hospitals, departments, and staff
- Can create user accounts for any staff member
Hospital Admin:
- Can manage their hospital, departments, and staff
- Can create user accounts for staff in their hospital
Department Manager:
- Can view staff in their department
- Cannot create user accounts
Staff:
- Can view other staff in their hospital
- Cannot create user accounts
Usage Examples
Creating Staff and User Account
Via API:
# 1. Create staff member
curl -X POST http://localhost:8000/api/staff/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"first_name": "John",
"last_name": "Doe",
"first_name_ar": "جون",
"last_name_ar": "دو",
"staff_type": "physician",
"job_title": "Cardiologist",
"specialization": "Cardiology",
"license_number": "MOH-LIC-1234567",
"employee_id": "DR-HOSP-12345",
"email": "john.doe@hospital.sa",
"hospital": "<hospital_id>",
"department": "<department_id>",
"status": "active"
}'
# 2. Create user account for staff
curl -X POST http://localhost:8000/api/staff/<staff_id>/create_user_account/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"role": "staff"
}'
Via Management Command:
python manage.py seed_staff --physicians 1 --create-users --send-emails
Via Python Code:
from apps.organizations.models import Staff, Hospital
from apps.organizations.services import StaffService
# Create staff
hospital = Hospital.objects.get(code="HOSPITAL001")
staff = Staff.objects.create(
first_name="John",
last_name="Doe",
staff_type=Staff.StaffType.PHYSICIAN,
job_title="Cardiologist",
specialization="Cardiology",
license_number="MOH-LIC-1234567",
employee_id="DR-HOSP-12345",
email="john.doe@hospital.sa",
hospital=hospital,
status="active"
)
# Create user account
user = StaffService.create_user_for_staff(staff, role='staff')
# Send credentials email
password = StaffService.generate_password()
user.set_password(password)
user.save()
StaffService.send_credentials_email(staff, password, request)
Linking Existing User
from apps.accounts.models import User
from apps.organizations.services import StaffService
# Get existing user and staff
user = User.objects.get(email="existing.user@hospital.sa")
staff = Staff.objects.get(employee_id="DR-HOSP-12345")
# Link user to staff
StaffService.link_user_to_staff(staff, user.id, request)
Staff Login
Staff members can log in using:
- Email: Their email address (required field)
- Password: The password sent via email or set via password reset
The login URL is: /accounts/login/
Testing
Test Superuser Creation
python manage.py createsuperuser
Prompts for:
- Email (required)
- First name (required)
- Last name (required)
- Password (required)
Test Staff Seeding
# Dry run
python manage.py seed_staff --physicians 3 --nurses 5 --dry-run
# Create staff
python manage.py seed_staff --physicians 3 --nurses 5
# Create staff with users
python manage.py seed_staff --physicians 3 --nurses 5 --create-users
# Create staff with users and send emails
python manage.py seed_staff --physicians 3 --nurses 5 --create-users --send-emails
Test API Endpoints
# Create staff
curl -X POST http://localhost:8000/api/staff/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"first_name": "Test", "last_name": "User", ...}'
# List staff
curl http://localhost:8000/api/staff/ \
-H "Authorization: Bearer <token>"
# Create user account
curl -X POST http://localhost:8000/api/staff/<id>/create_user_account/ \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{"role": "staff"}'
# Send invitation
curl -X POST http://localhost:8000/api/staff/<id>/send_invitation/ \
-H "Authorization: Bearer <token>"
Security Considerations
-
Password Generation:
- Secure random passwords (12 characters)
- Includes letters, numbers, and special characters
- Sent via email (should be changed on first login)
-
Email Security:
- Credentials sent only to staff email
- Email is required for user creation
- Unique email constraint enforced
-
Permissions:
- Only PX Admins and Hospital Admins can create user accounts
- Hospital Admins can only create accounts for staff in their hospital
- Staff can only view other staff in their hospital
-
Audit Trail:
- All user creation/linking/unlinking actions logged
- Email sending logged
- Request context captured
Troubleshooting
Issue: "The Email field must be set"
Solution: Ensure staff member has an email address before creating user account.
Issue: "Staff member already has a user account"
Solution: Staff already has a user linked. Use link_user to link a different user or unlink_user first.
Issue: "You do not have permission to create user accounts"
Solution: User must be a PX Admin or Hospital Admin.
Issue: "You can only create accounts for staff in your hospital"
Solution: Hospital Admins can only create accounts for staff in their hospital.
Issue: Email not sending
Solution: Check email configuration in settings and ensure SMTP server is configured correctly.
Related Documentation
- UserManager Implementation
- Staff User Account Implementation
- Staff Seed Command Update
- Login/Logout Functionality Check
Summary
The Staff User Account feature provides:
- ✅ Optional one-to-one relation between Staff and User models
- ✅ Custom UserManager for email-based authentication
- ✅ Complete CRUD operations for staff management
- ✅ User account creation, linking, and unlinking
- ✅ Credential email sending
- ✅ Role-based access control
- ✅ Audit logging
- ✅ Bilingual support (English/Arabic)
- ✅ Management command for bulk staff creation
- ✅ RESTful API endpoints with filtering and search
The implementation follows Django best practices, maintains backward compatibility, and provides a secure, scalable solution for staff user account management.