209 lines
6.8 KiB
Markdown
209 lines
6.8 KiB
Markdown
# PX Sources App
|
|
|
|
A standalone Django app for managing the origins of patient feedback (Complaints and Inquiries).
|
|
|
|
## Features
|
|
|
|
- **Full CRUD Operations**: Create, Read, Update, and Delete PX Sources
|
|
- **Bilingual Support**: Names and descriptions in both English and Arabic
|
|
- **Flexible Source Types**: Sources can be configured for complaints, inquiries, or both
|
|
- **Usage Tracking**: Track how sources are used across the system
|
|
- **Soft Delete**: Deactivate sources without deleting them (maintains data integrity)
|
|
- **Role-Based Access**: PX Admins have full access, others have restricted access
|
|
- **REST API**: Complete API endpoints for integration with other apps
|
|
- **Admin Interface**: Full Django admin interface for management
|
|
- **UI Templates**: Complete HTML interface following project conventions
|
|
|
|
## Models
|
|
|
|
### PXSource
|
|
|
|
The main model for managing feedback sources.
|
|
|
|
**Fields:**
|
|
- `code` (CharField): Unique code for programmatic reference (e.g., 'PATIENT', 'FAMILY')
|
|
- `name_en` (CharField): Source name in English
|
|
- `name_ar` (CharField): Source name in Arabic (optional)
|
|
- `description_en` (TextField): Description in English (optional)
|
|
- `description_ar` (TextField): Description in Arabic (optional)
|
|
- `source_type` (CharField): Type - 'complaint', 'inquiry', or 'both'
|
|
- `order` (IntegerField): Display order (lower numbers appear first)
|
|
- `is_active` (BooleanField): Active status (can be deactivated without deletion)
|
|
- `icon_class` (CharField): CSS class for icon display (optional)
|
|
- `color_code` (CharField): Hex color code for UI display (optional)
|
|
- `metadata` (JSONField): Additional configuration or metadata
|
|
|
|
**Methods:**
|
|
- `get_localized_name(language)`: Get name in specified language
|
|
- `get_localized_description(language)`: Get description in specified language
|
|
- `activate()`: Activate the source
|
|
- `deactivate()`: Deactivate the source
|
|
- `get_active_sources(source_type=None)`: Class method to get active sources
|
|
- `get_by_code(code)`: Class method to get source by code
|
|
|
|
### SourceUsage
|
|
|
|
Tracks usage of sources across the system for analytics.
|
|
|
|
**Fields:**
|
|
- `source` (ForeignKey): Reference to PXSource
|
|
- `content_type` (ForeignKey): Type of related object (Complaint, Inquiry, etc.)
|
|
- `object_id` (UUIDField): ID of related object
|
|
- `hospital` (ForeignKey): Hospital context (optional)
|
|
- `user` (ForeignKey): User who selected the source (optional)
|
|
|
|
## API Endpoints
|
|
|
|
### REST API
|
|
|
|
Base URL: `/px-sources/api/sources/`
|
|
|
|
**Endpoints:**
|
|
- `GET /px-sources/api/sources/` - List all sources
|
|
- `POST /px-sources/api/sources/` - Create a new source
|
|
- `GET /px-sources/api/sources/{id}/` - Retrieve source details
|
|
- `PUT /px-sources/api/sources/{id}/` - Update source (full)
|
|
- `PATCH /px-sources/api/sources/{id}/` - Update source (partial)
|
|
- `DELETE /px-sources/api/sources/{id}/` - Delete source
|
|
- `GET /px-sources/api/sources/choices/?source_type=complaint` - Get choices for dropdowns
|
|
- `POST /px-sources/api/sources/{id}/activate/` - Activate a source
|
|
- `POST /px-sources/api/sources/{id}/deactivate/` - Deactivate a source
|
|
- `GET /px-sources/api/sources/types/` - Get available source types
|
|
- `GET /px-sources/api/sources/{id}/usage/` - Get usage statistics
|
|
|
|
### UI Views
|
|
|
|
- `/px-sources/` - List all sources
|
|
- `/px-sources/new/` - Create a new source
|
|
- `/px-sources/{id}/` - View source details
|
|
- `/px-sources/{id}/edit/` - Edit source
|
|
- `/px-sources/{id}/delete/` - Delete source
|
|
- `/px-sources/{id}/toggle/` - Toggle active status (AJAX)
|
|
- `/px-sources/ajax/search/` - AJAX search endpoint
|
|
- `/px-sources/ajax/choices/` - AJAX choices endpoint
|
|
|
|
## Usage Examples
|
|
|
|
### Using the API
|
|
|
|
```python
|
|
import requests
|
|
|
|
# Get active sources for complaints
|
|
response = requests.get('http://localhost:8000/px-sources/api/sources/choices/?source_type=complaint')
|
|
sources = response.json()
|
|
print(sources)
|
|
|
|
# Create a new source
|
|
new_source = {
|
|
'code': 'NEW_SOURCE',
|
|
'name_en': 'New Source',
|
|
'name_ar': 'مصدر جديد',
|
|
'description_en': 'A new source for feedback',
|
|
'source_type': 'both',
|
|
'order': 10,
|
|
'is_active': True
|
|
}
|
|
response = requests.post('http://localhost:8000/px-sources/api/sources/', json=new_source)
|
|
print(response.json())
|
|
```
|
|
|
|
### Using in Code
|
|
|
|
```python
|
|
from apps.px_sources.models import PXSource, SourceType
|
|
|
|
# Get active sources for complaints
|
|
complaint_sources = PXSource.get_active_sources(source_type=SourceType.COMPLAINT)
|
|
|
|
# Get a source by code
|
|
patient_source = PXSource.get_by_code('PATIENT')
|
|
|
|
# Get localized name
|
|
name_ar = patient_source.get_localized_name('ar')
|
|
name_en = patient_source.get_localized_name('en')
|
|
|
|
# Deactivate a source
|
|
patient_source.deactivate()
|
|
```
|
|
|
|
### Integration with Other Apps
|
|
|
|
To integrate PX Sources with Complaint or Inquiry models:
|
|
|
|
```python
|
|
from django.contrib.contenttypes.fields import GenericForeignKey
|
|
from django.contrib.contenttypes.models import ContentType
|
|
from apps.px_sources.models import PXSource, SourceUsage
|
|
|
|
# In your model (e.g., Complaint)
|
|
class Complaint(models.Model):
|
|
source = models.ForeignKey(
|
|
PXSource,
|
|
on_delete=models.PROTECT,
|
|
related_name='complaints'
|
|
)
|
|
# ... other fields
|
|
|
|
def save(self, *args, **kwargs):
|
|
super().save(*args, **kwargs)
|
|
# Track usage
|
|
SourceUsage.objects.create(
|
|
source=self.source,
|
|
content_type=ContentType.objects.get_for_model(self.__class__),
|
|
object_id=self.id,
|
|
hospital=self.hospital,
|
|
user=self.created_by
|
|
)
|
|
```
|
|
|
|
## Default Sources
|
|
|
|
Common sources that can be seeded:
|
|
|
|
- `PATIENT` - Direct patient feedback
|
|
- `FAMILY` - Family member reports
|
|
- `STAFF` - Staff reports
|
|
- `SURVEY` - Survey responses
|
|
- `SOCIAL_MEDIA` - Social media feedback
|
|
- `CALL_CENTER` - Call center interactions
|
|
- `MOH` - Ministry of Health
|
|
- `CHI` - Council of Health Insurance
|
|
- `OTHER` - Other sources
|
|
|
|
## Permissions
|
|
|
|
- **PX Admins**: Full access (create, read, update, delete, activate/deactivate)
|
|
- **Hospital Admins**: Can create, read, update sources
|
|
- **Other Users**: Read-only access to active sources
|
|
|
|
## Templates
|
|
|
|
- `px_sources/source_list.html` - List view with filters
|
|
- `px_sources/source_form.html` - Create/Edit form
|
|
- `px_sources/source_detail.html` - Detail view with usage statistics
|
|
- `px_sources/source_confirm_delete.html` - Delete confirmation
|
|
|
|
## Admin Configuration
|
|
|
|
The app includes a full Django admin interface with:
|
|
- List view with filters (source type, active status, date)
|
|
- Search by code, names, and descriptions
|
|
- Inline editing of order field
|
|
- Detailed fieldsets for organized display
|
|
- Color-coded badges for source type and status
|
|
|
|
## Database Indexes
|
|
|
|
Optimized indexes for performance:
|
|
- `is_active`, `source_type`, `order` (composite)
|
|
- `code` (unique)
|
|
- `created_at` (timestamp)
|
|
|
|
## Audit Logging
|
|
|
|
All source operations are logged via the AuditService:
|
|
- Creation events
|
|
- Update events
|
|
- Deletion events
|
|
- Activation/Deactivation events |