811 lines
22 KiB
Markdown
811 lines
22 KiB
Markdown
# Staff User Account Feature - Complete Implementation
|
|
|
|
## Overview
|
|
|
|
The Staff User Account feature enables administrators to create optional user accounts for staff members, allowing them to log into the PX360 system. This implementation provides a complete CRUD interface with user account management capabilities.
|
|
|
|
## Architecture
|
|
|
|
### Model Relationship
|
|
|
|
The `Staff` model has an optional one-to-one relationship with the `User` model:
|
|
|
|
```python
|
|
# apps/organizations/models.py
|
|
class Staff(models.Model):
|
|
# ... other fields ...
|
|
user = models.OneToOneField(
|
|
settings.AUTH_USER_MODEL,
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name='staff_profile'
|
|
)
|
|
```
|
|
|
|
**Key Features:**
|
|
- Optional: Staff can exist without a user account
|
|
- SET_NULL: If user is deleted, staff record is preserved
|
|
- Related name: `user.staff_profile` allows reverse lookup
|
|
|
|
## Core Components
|
|
|
|
### 1. StaffService (`apps/organizations/services.py`)
|
|
|
|
The `StaffService` class provides all business logic for user account management:
|
|
|
|
#### Methods
|
|
|
|
##### `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. Requires staff to have an email address
|
|
3. Generates unique username (format: `firstname.lastname` or `firstname.lastnameN`)
|
|
4. Generates secure 12-character password
|
|
5. Creates User with staff information:
|
|
- Email as primary identifier
|
|
- Username (optional, for backward compatibility)
|
|
- First/last name
|
|
- Employee ID
|
|
- Hospital and Department
|
|
- Active status
|
|
6. Assigns role via group membership
|
|
7. Links user to staff
|
|
8. Logs audit trail
|
|
|
|
**Returns:** Created User instance
|
|
|
|
**Raises:** ValueError if staff already has user or no email
|
|
|
|
##### `link_user_to_staff(staff, user_id, request=None)`
|
|
Links an existing User account to a Staff member.
|
|
|
|
**Process:**
|
|
1. Validates staff doesn't have a user account
|
|
2. Retrieves user by ID
|
|
3. Links user to staff
|
|
4. Updates user's organization data if missing
|
|
5. Logs audit trail
|
|
|
|
**Returns:** Updated Staff instance
|
|
|
|
**Raises:** ValueError if staff has user or user not found
|
|
|
|
##### `unlink_user_from_staff(staff, request=None)`
|
|
Removes User account association from a Staff member.
|
|
|
|
**Process:**
|
|
1. Validates staff has a user account
|
|
2. Sets staff.user to None
|
|
3. Logs audit trail
|
|
|
|
**Returns:** Updated Staff instance
|
|
|
|
**Raises:** ValueError if staff has no user account
|
|
|
|
##### `send_credentials_email(staff, password, request)`
|
|
Sends login credentials email to staff member.
|
|
|
|
**Process:**
|
|
1. Validates staff has email and user account
|
|
2. Builds absolute login URL
|
|
3. Renders HTML email template
|
|
4. Sends email via Django's send_mail
|
|
5. Logs audit trail
|
|
|
|
**Raises:** ValueError if no email or user account
|
|
|
|
##### `generate_username(staff)`
|
|
Generates a unique username from staff name.
|
|
|
|
**Format:** `firstname.lastname` (lowercase)
|
|
**Duplicate Handling:** Appends incremental number (e.g., `john.smith2`)
|
|
|
|
**Returns:** Unique username string
|
|
|
|
##### `generate_password(length=12)`
|
|
Generates a secure random password.
|
|
|
|
**Characters:** ASCII letters + digits + punctuation
|
|
**Length:** 12 characters (configurable)
|
|
|
|
**Returns:** Secure random password string
|
|
|
|
##### `get_staff_type_role(staff_type)`
|
|
Maps staff_type to role name.
|
|
|
|
**Current Mapping:** All staff types map to 'staff' role
|
|
**Extensible:** Can be enhanced for role-based permissions
|
|
|
|
**Returns:** Role name string
|
|
|
|
### 2. API ViewSet (`apps/organizations/views.py`)
|
|
|
|
The `StaffViewSet` provides REST API endpoints:
|
|
|
|
#### Standard CRUD Operations
|
|
|
|
- `GET /api/organizations/staff/` - List staff (filtered by user role)
|
|
- `POST /api/organizations/staff/` - Create new staff
|
|
- `GET /api/organizations/staff/{id}/` - Retrieve staff details
|
|
- `PUT /api/organizations/staff/{id}/` - Update staff
|
|
- `PATCH /api/organizations/staff/{id}/` - Partial update staff
|
|
- `DELETE /api/organizations/staff/{id}/` - Delete staff
|
|
|
|
#### Custom Actions
|
|
|
|
##### `POST /api/organizations/staff/{id}/create_user_account/`
|
|
Creates a user account for staff member.
|
|
|
|
**Permissions:** PX Admin or Hospital Admin
|
|
**Body:** Optional `role` parameter (defaults to staff type role)
|
|
**Process:**
|
|
1. Validates staff doesn't have user account
|
|
2. Checks user permissions
|
|
3. Creates user via StaffService
|
|
4. Generates password
|
|
5. Sends credentials email
|
|
6. Returns success message with staff data
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"message": "User account created and credentials emailed successfully",
|
|
"staff": { ...staff data... },
|
|
"email": "staff@example.com"
|
|
}
|
|
```
|
|
|
|
##### `POST /api/organizations/staff/{id}/link_user/`
|
|
Links existing user account to staff member.
|
|
|
|
**Permissions:** PX Admin or Hospital Admin
|
|
**Body:** Required `user_id` parameter
|
|
**Process:**
|
|
1. Validates staff doesn't have user account
|
|
2. Checks user permissions
|
|
3. Links user via StaffService
|
|
4. Returns success message
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"message": "User account linked successfully",
|
|
"staff": { ...staff data... }
|
|
}
|
|
```
|
|
|
|
##### `POST /api/organizations/staff/{id}/unlink_user/`
|
|
Removes user account association from staff member.
|
|
|
|
**Permissions:** PX Admin or Hospital Admin
|
|
**Process:**
|
|
1. Validates staff has user account
|
|
2. Checks user permissions
|
|
3. Unlinks user via StaffService
|
|
4. Returns success message
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"message": "User account unlinked successfully",
|
|
"staff": { ...staff data... }
|
|
}
|
|
```
|
|
|
|
##### `POST /api/organizations/staff/{id}/send_invitation/`
|
|
Sends credentials email to staff member.
|
|
|
|
**Permissions:** PX Admin or Hospital Admin
|
|
**Process:**
|
|
1. Validates staff has user account
|
|
2. Checks user permissions
|
|
3. Generates new password
|
|
4. Updates user password
|
|
5. Sends email via StaffService
|
|
6. Returns success message
|
|
|
|
**Response:**
|
|
```json
|
|
{
|
|
"message": "Invitation email sent successfully",
|
|
"staff": { ...staff data... }
|
|
}
|
|
```
|
|
|
|
### 3. Admin Interface (`apps/organizations/admin.py`)
|
|
|
|
The Django admin interface is enhanced with user account management:
|
|
|
|
#### StaffAdmin Features
|
|
|
|
**List Display:**
|
|
- Staff name, type, job title, employee ID
|
|
- Hospital, department
|
|
- User account status (✓ Yes / ✗ No)
|
|
- Status
|
|
|
|
**Custom Column:**
|
|
- `has_user_account`: Displays user account status with color coding
|
|
|
|
**Bulk Actions:**
|
|
1. **"Create user accounts for selected staff"**
|
|
- Creates user accounts for multiple staff members
|
|
- Sends credentials emails
|
|
- Reports success/failure count
|
|
|
|
2. **"Send credential emails to selected staff"**
|
|
- Resends credentials to staff with existing accounts
|
|
- Generates new passwords
|
|
- Reports success/failure count
|
|
|
|
**Filtering & Search:**
|
|
- Filter by status, hospital, staff type, specialization
|
|
- Search by name, Arabic names, employee ID, license, job title
|
|
|
|
**Autocomplete Fields:**
|
|
- Hospital, Department, User (for linking)
|
|
|
|
### 4. UI Templates
|
|
|
|
#### Staff List (`templates/organizations/staff_list.html`)
|
|
|
|
**Features:**
|
|
- Filters: Hospital, status, staff type, search
|
|
- Table displays user account status with badge
|
|
- Quick actions for user account management:
|
|
- Create user account (for staff without accounts)
|
|
- Send invitation email (for staff with accounts)
|
|
- Unlink user account (for staff with accounts)
|
|
- Modals for confirmation dialogs
|
|
- Pagination support
|
|
|
|
**Actions Column:**
|
|
- View details (always available)
|
|
- Create user account (if no user and has email)
|
|
- Send invitation (if has user)
|
|
- Unlink user (if has user)
|
|
- Actions restricted to PX Admin and Hospital Admin
|
|
|
|
#### Staff Detail (`templates/organizations/staff_detail.html`)
|
|
|
|
**User Account Card:**
|
|
- Displays user account status (alert box)
|
|
- Shows user details (username, email, active status, created date)
|
|
- Action buttons:
|
|
- "Create User Account" (if no account)
|
|
- "Resend Invitation Email" (if account exists)
|
|
- "Unlink User Account" (if account exists)
|
|
- Confirmation modals for each action
|
|
|
|
**Other Cards:**
|
|
- Personal Information
|
|
- Organization Information
|
|
- Contact Information
|
|
- Status Information
|
|
|
|
**JavaScript Functions:**
|
|
- `createUserAccount()` - Shows modal and triggers API call
|
|
- `confirmCreateUser()` - Executes create user account
|
|
- `sendInvitation()` - Shows modal and triggers API call
|
|
- `confirmSendInvitation()` - Executes send invitation
|
|
- `unlinkUserAccount()` - Shows modal and triggers API call
|
|
- `confirmUnlinkUser()` - Executes unlink user
|
|
|
|
### 5. Email Template (`templates/organizations/emails/staff_credentials.html`)
|
|
|
|
**Design:**
|
|
- Professional HTML email with gradient header
|
|
- Clean, readable layout
|
|
- Responsive design
|
|
|
|
**Content:**
|
|
- Welcome message
|
|
- Credentials box with:
|
|
- Username
|
|
- Password
|
|
- Email
|
|
- Security notice (change password after first login)
|
|
- Login button (links to system)
|
|
- Footer with copyright
|
|
|
|
**Styling:**
|
|
- Purple gradient theme (matches PX360 branding)
|
|
- Color-coded credentials box
|
|
- Warning banner for security notice
|
|
- Mobile-friendly
|
|
|
|
### 6. Forms (`apps/organizations/forms.py`)
|
|
|
|
**StaffForm:**
|
|
- All standard staff fields
|
|
- Hospital filtering based on user role
|
|
- Department filtering based on selected hospital
|
|
- Email validation (lowercase, trimmed)
|
|
- Employee ID uniqueness validation
|
|
|
|
**No User Management in Form:**
|
|
- User account creation handled via separate actions
|
|
- Keeps form focused on staff data
|
|
- User management in detail view for better UX
|
|
|
|
## Permission Model
|
|
|
|
### Access Control
|
|
|
|
**PX Admin:**
|
|
- Can create user accounts for any staff
|
|
- Can link/unlink users for any staff
|
|
- Can send invitations to any staff
|
|
- Full access to all staff management features
|
|
|
|
**Hospital Admin:**
|
|
- Can create user accounts for staff in their hospital
|
|
- Can link/unlink users for staff in their hospital
|
|
- Can send invitations to staff in their hospital
|
|
- Cannot manage staff from other hospitals
|
|
|
|
**Department Manager:**
|
|
- Can view staff in their department
|
|
- Cannot create/link/unlink user accounts
|
|
- Cannot manage user accounts
|
|
|
|
**Regular Staff:**
|
|
- Can view staff in their hospital
|
|
- Cannot create/link/unlink user accounts
|
|
- Cannot manage user accounts
|
|
|
|
### Implementation
|
|
|
|
Permissions enforced in:
|
|
- API ViewSet actions
|
|
- Admin actions
|
|
- UI templates (buttons hidden for unauthorized users)
|
|
|
|
## Workflow Examples
|
|
|
|
### Example 1: Creating Staff and User Account
|
|
|
|
**Step 1: Create Staff Profile**
|
|
```
|
|
POST /api/organizations/staff/
|
|
{
|
|
"first_name": "Ahmed",
|
|
"last_name": "Al-Saud",
|
|
"email": "ahmed.alsaud@hospital.com",
|
|
"employee_id": "EMP001",
|
|
"hospital": "...",
|
|
"department": "...",
|
|
"staff_type": "physician"
|
|
}
|
|
```
|
|
|
|
**Step 2: Create User Account**
|
|
```
|
|
POST /api/organizations/staff/{id}/create_user_account/
|
|
{
|
|
"role": "staff"
|
|
}
|
|
```
|
|
|
|
**Result:**
|
|
- User created with username: `ahmed.alsaud`
|
|
- Password generated: `Xk9#mP2$vL5!`
|
|
- Email sent to ahmed.alsaud@hospital.com
|
|
- Staff.user linked to new user
|
|
|
|
### Example 2: Linking Existing User
|
|
|
|
**Step 1: Create Staff Profile** (same as above)
|
|
|
|
**Step 2: Link Existing User**
|
|
```
|
|
POST /api/organizations/staff/{id}/link_user/
|
|
{
|
|
"user_id": "123e4567-e89b-12d3-a456-426614174000"
|
|
}
|
|
```
|
|
|
|
**Result:**
|
|
- Staff.user linked to existing user
|
|
- User's organization data updated if missing
|
|
|
|
### Example 3: Resending Credentials
|
|
|
|
**Scenario:** Staff member forgot their password
|
|
|
|
**Action:**
|
|
```
|
|
POST /api/organizations/staff/{id}/send_invitation/
|
|
```
|
|
|
|
**Result:**
|
|
- New password generated: `Qw7$rT3!nK9#`
|
|
- User password updated in database
|
|
- Email sent with new credentials
|
|
|
|
### Example 4: Removing Login Access
|
|
|
|
**Scenario:** Staff member leaves organization
|
|
|
|
**Action:**
|
|
```
|
|
POST /api/organizations/staff/{id}/unlink_user/
|
|
```
|
|
|
|
**Result:**
|
|
- Staff.user set to None
|
|
- User account still exists but no longer linked
|
|
- Staff member cannot log in
|
|
|
|
### Example 5: Bulk User Account Creation
|
|
|
|
**Scenario:** Onboarding 10 new staff members
|
|
|
|
**Action:**
|
|
1. Go to Django Admin > Staff
|
|
2. Select 10 staff members (all have emails)
|
|
3. Choose "Create user accounts for selected staff"
|
|
4. Click "Go"
|
|
|
|
**Result:**
|
|
- 10 user accounts created
|
|
- 10 emails sent with credentials
|
|
- Admin message: "Created 10 user accounts. Failed: 0"
|
|
|
|
## Technical Details
|
|
|
|
### Username Generation Algorithm
|
|
|
|
```python
|
|
base_username = f"{first_name.lower()}.{last_name.lower()}"
|
|
username = base_username
|
|
counter = 1
|
|
|
|
while User.objects.filter(username=username).exists():
|
|
username = f"{base_username}{counter}"
|
|
counter += 1
|
|
```
|
|
|
|
**Examples:**
|
|
- John Smith → `john.smith`
|
|
- Duplicate John Smith → `john.smith2`
|
|
- Another duplicate → `john.smith3`
|
|
|
|
### Password Generation
|
|
|
|
```python
|
|
alphabet = string.ascii_letters + string.digits + string.punctuation
|
|
password = ''.join(secrets.choice(alphabet) for _ in range(12))
|
|
```
|
|
|
|
**Character Set:**
|
|
- Uppercase: A-Z
|
|
- Lowercase: a-z
|
|
- Digits: 0-9
|
|
- Punctuation: !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~
|
|
|
|
**Strength:** Cryptographically secure (uses `secrets` module)
|
|
|
|
### Email Sending
|
|
|
|
**Configuration Required (settings.py):**
|
|
```python
|
|
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
|
EMAIL_HOST = 'smtp.example.com'
|
|
EMAIL_PORT = 587
|
|
EMAIL_USE_TLS = True
|
|
EMAIL_HOST_USER = 'noreply@px360.com'
|
|
EMAIL_HOST_PASSWORD = 'password'
|
|
DEFAULT_FROM_EMAIL = 'PX360 <noreply@px360.com>'
|
|
```
|
|
|
|
**Alternative:** Use Email Backend services (SendGrid, Mailgun, etc.)
|
|
|
|
### Audit Logging
|
|
|
|
All user account operations are logged via `AuditService.log_from_request()`:
|
|
|
|
**Logged Events:**
|
|
- `user_creation` - When user account is created
|
|
- `other` - For link/unlink/send invitation actions
|
|
|
|
**Metadata Includes:**
|
|
- Staff ID and name
|
|
- User ID (for link/unlink)
|
|
- Role (for creation)
|
|
- Timestamp
|
|
- User who performed action
|
|
|
|
## Security Considerations
|
|
|
|
### 1. Password Security
|
|
- Passwords are hashed using Django's PBKDF2 algorithm
|
|
- Generated passwords are only sent via email (never stored in plain text)
|
|
- Staff should be instructed to change password after first login
|
|
|
|
### 2. Email Security
|
|
- Credentials are sent via SMTP with TLS
|
|
- Email templates include security warnings
|
|
- Passwords are not included in any logs
|
|
|
|
### 3. Access Control
|
|
- Role-based permissions enforced at all levels
|
|
- Hospital admins can only manage their hospital's staff
|
|
- Actions require proper CSRF tokens
|
|
|
|
### 4. Data Integrity
|
|
- Foreign key constraints prevent orphaned records
|
|
- SET_NULL on delete preserves staff if user is deleted
|
|
- Validation prevents duplicate user accounts
|
|
|
|
### 5. Audit Trail
|
|
- All user account operations are logged
|
|
- Logs include who, when, and what
|
|
- Metadata stored for analysis
|
|
|
|
## Database Schema
|
|
|
|
### Staff Model Fields
|
|
|
|
```python
|
|
class Staff(models.Model):
|
|
# Personal Information
|
|
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)
|
|
|
|
# Role Information
|
|
staff_type = models.CharField(max_length=20, choices=STAFF_TYPE_CHOICES)
|
|
job_title = models.CharField(max_length=100)
|
|
license_number = models.CharField(max_length=50, blank=True)
|
|
specialization = models.CharField(max_length=100, blank=True)
|
|
|
|
# Employee Information
|
|
employee_id = models.CharField(max_length=50, unique=True)
|
|
email = models.EmailField(blank=True, null=True)
|
|
|
|
# Organization
|
|
hospital = models.ForeignKey(Hospital, on_delete=models.PROTECT)
|
|
department = models.ForeignKey(Department, on_delete=models.SET_NULL, null=True, blank=True)
|
|
|
|
# User Account (Optional)
|
|
user = models.OneToOneField(
|
|
settings.AUTH_USER_MODEL,
|
|
on_delete=models.SET_NULL,
|
|
null=True,
|
|
blank=True,
|
|
related_name='staff_profile'
|
|
)
|
|
|
|
# Status
|
|
status = models.CharField(max_length=20, choices=STATUS_CHOICES, default='active')
|
|
|
|
# Metadata
|
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
updated_at = models.DateTimeField(auto_now=True)
|
|
```
|
|
|
|
### Indexes
|
|
|
|
- `employee_id`: Unique index
|
|
- `user`: Unique index (OneToOne)
|
|
- `hospital`: Foreign key index
|
|
- `department`: Foreign key index
|
|
- `email`: Index for lookups
|
|
|
|
## Testing Recommendations
|
|
|
|
### Unit Tests
|
|
|
|
```python
|
|
# Test StaffService methods
|
|
def test_create_user_for_staff():
|
|
staff = create_test_staff(email="test@example.com")
|
|
user = StaffService.create_user_for_staff(staff)
|
|
assert staff.user == user
|
|
assert user.email == "test@example.com"
|
|
|
|
def test_generate_username():
|
|
staff = create_test_staff(first_name="John", last_name="Smith")
|
|
username = StaffService.generate_username(staff)
|
|
assert username == "john.smith"
|
|
|
|
def test_generate_password():
|
|
password = StaffService.generate_password()
|
|
assert len(password) == 12
|
|
# Verify contains characters from each class
|
|
|
|
def test_link_user_to_staff():
|
|
staff = create_test_staff()
|
|
user = create_test_user()
|
|
result = StaffService.link_user_to_staff(staff, user.id)
|
|
assert staff.user == user
|
|
|
|
def test_unlink_user_from_staff():
|
|
staff = create_test_staff_with_user()
|
|
result = StaffService.unlink_user_from_staff(staff)
|
|
assert staff.user is None
|
|
```
|
|
|
|
### Integration Tests
|
|
|
|
```python
|
|
# Test API endpoints
|
|
def test_create_user_account_api():
|
|
client = authenticate_as_admin()
|
|
staff = create_test_staff()
|
|
response = client.post(f'/api/organizations/staff/{staff.id}/create_user_account/')
|
|
assert response.status_code == 201
|
|
assert staff.user is not None
|
|
|
|
def test_send_invitation_api():
|
|
client = authenticate_as_admin()
|
|
staff = create_test_staff_with_user()
|
|
response = client.post(f'/api/organizations/staff/{staff.id}/send_invitation/')
|
|
assert response.status_code == 200
|
|
# Verify email was sent
|
|
|
|
def test_permissions():
|
|
# Test that non-admins cannot create user accounts
|
|
client = authenticate_as_staff()
|
|
staff = create_test_staff()
|
|
response = client.post(f'/api/organizations/staff/{staff.id}/create_user_account/')
|
|
assert response.status_code == 403
|
|
```
|
|
|
|
### UI Tests
|
|
|
|
```python
|
|
# Test UI interactions
|
|
def test_create_user_button_visible_for_admins():
|
|
staff = create_test_staff()
|
|
admin_user = create_admin_user()
|
|
response = client.get(f'/staff/{staff.id}/')
|
|
assert 'Create User Account' in response.content
|
|
|
|
def test_create_user_button_hidden_for_staff():
|
|
staff = create_test_staff()
|
|
regular_user = create_regular_user()
|
|
response = client.get(f'/staff/{staff.id}/')
|
|
assert 'Create User Account' not in response.content
|
|
```
|
|
|
|
## Future Enhancements
|
|
|
|
### Potential Improvements
|
|
|
|
1. **Role-Based Permissions**
|
|
- Different roles for different staff types
|
|
- More granular permissions per role
|
|
|
|
2. **Bulk Import**
|
|
- Import staff from CSV/Excel
|
|
- Auto-create user accounts during import
|
|
|
|
3. **Self-Service**
|
|
- Allow staff to request user account
|
|
- Approval workflow for requests
|
|
|
|
4. **Password Reset**
|
|
- Integration with Django's password reset
|
|
- Self-service password reset
|
|
|
|
5. **2FA Support**
|
|
- Two-factor authentication for staff
|
|
- Enhanced security options
|
|
|
|
6. **Session Management**
|
|
- Track active sessions
|
|
- Force logout from all devices
|
|
|
|
7. **Audit Reports**
|
|
- Generate audit reports
|
|
- Export to PDF/Excel
|
|
|
|
8. **Email Customization**
|
|
- Customizable email templates
|
|
- Multi-language support
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**Issue:** "Staff member already has a user account"
|
|
- **Cause:** Attempting to create duplicate user account
|
|
- **Solution:** Check staff.user before creating, or unlink first
|
|
|
|
**Issue:** "Staff member must have an email address"
|
|
- **Cause:** Creating user account without email
|
|
- **Solution:** Add email to staff profile first
|
|
|
|
**Issue:** Email not sent
|
|
- **Cause:** Email configuration issue
|
|
- **Solution:** Check EMAIL_* settings, verify SMTP credentials
|
|
|
|
**Issue:** Username already exists
|
|
- **Cause:** Non-unique username generation
|
|
- **Solution:** The service handles this automatically by appending numbers
|
|
|
|
**Issue:** Permission denied
|
|
- **Cause:** User lacks required role
|
|
- **Solution:** Ensure user is PX Admin or Hospital Admin
|
|
|
|
**Issue:** User account creation failed
|
|
- **Cause:** Invalid data, constraints, or service error
|
|
- **Solution:** Check error message, validate staff data
|
|
|
|
## API Reference
|
|
|
|
### StaffViewSet Endpoints
|
|
|
|
| Method | Endpoint | Description | Auth |
|
|
|--------|----------|-------------|------|
|
|
| GET | /api/organizations/staff/ | List staff | Required |
|
|
| POST | /api/organizations/staff/ | Create staff | PX Admin / Hospital Admin |
|
|
| GET | /api/organizations/staff/{id}/ | Get staff details | Required |
|
|
| PUT | /api/organizations/staff/{id}/ | Update staff | PX Admin / Hospital Admin |
|
|
| PATCH | /api/organizations/staff/{id}/ | Partial update | PX Admin / Hospital Admin |
|
|
| DELETE | /api/organizations/staff/{id}/ | Delete staff | PX Admin / Hospital Admin |
|
|
| POST | /api/organizations/staff/{id}/create_user_account/ | Create user account | PX Admin / Hospital Admin |
|
|
| POST | /api/organizations/staff/{id}/link_user/ | Link existing user | PX Admin / Hospital Admin |
|
|
| POST | /api/organizations/staff/{id}/unlink_user/ | Unlink user | PX Admin / Hospital Admin |
|
|
| POST | /api/organizations/staff/{id}/send_invitation/ | Send invitation | PX Admin / Hospital Admin |
|
|
|
|
### Response Formats
|
|
|
|
**Success (201 Created):**
|
|
```json
|
|
{
|
|
"message": "User account created and credentials emailed successfully",
|
|
"staff": {
|
|
"id": "...",
|
|
"first_name": "Ahmed",
|
|
"last_name": "Al-Saud",
|
|
"user": {
|
|
"id": "...",
|
|
"email": "ahmed.alsaud@hospital.com",
|
|
"username": "ahmed.alsaud"
|
|
}
|
|
},
|
|
"email": "ahmed.alsaud@hospital.com"
|
|
}
|
|
```
|
|
|
|
**Error (400 Bad Request):**
|
|
```json
|
|
{
|
|
"error": "Staff member already has a user account"
|
|
}
|
|
```
|
|
|
|
**Error (403 Forbidden):**
|
|
```json
|
|
{
|
|
"error": "You do not have permission to create user accounts"
|
|
}
|
|
```
|
|
|
|
## Conclusion
|
|
|
|
The Staff User Account feature provides a complete, production-ready solution for managing staff access to the PX360 system. With robust security, comprehensive audit logging, and a user-friendly interface, administrators can efficiently manage staff user accounts from creation to termination.
|
|
|
|
### Key Features Summary
|
|
|
|
✅ Optional one-to-one relationship with User model
|
|
✅ Automatic username and password generation
|
|
✅ Secure credential delivery via email
|
|
✅ Link/unlink existing user accounts
|
|
✅ Bulk operations in admin interface
|
|
✅ Role-based access control
|
|
✅ Complete audit trail
|
|
✅ RESTful API with comprehensive endpoints
|
|
✅ User-friendly web interface
|
|
✅ Internationalization support
|
|
✅ Professional email templates
|
|
|
|
The implementation follows Django best practices and is ready for production use.
|