5.9 KiB
PX Sources Migration Summary
Overview
Successfully migrated the system from hardcoded source enums to a flexible PXSource model that supports bilingual naming and dynamic source management.
Changes Made
1. Updated PXSource Model
File: apps/px_sources/models.py
Removed fields:
icon_class- CSS class for icon display (no longer needed)color_code- Color code for UI display (no longer needed)
Simplified fields:
code- Unique identifier (e.g., 'PATIENT', 'FAMILY', 'STAFF')name_en,name_ar- Bilingual namesdescription_en,description_ar- Bilingual descriptionssource_type- 'complaint', 'inquiry', or 'both'order- Display orderis_active- Active statusmetadata- JSON field for additional configuration
2. Updated Complaint Model
File: apps/complaints/models.py
Before:
source = models.CharField(
max_length=50,
choices=ComplaintSource.choices, # Hardcoded enum
default=ComplaintSource.PATIENT
)
After:
source = models.ForeignKey(
'px_sources.PXSource',
on_delete=models.PROTECT,
related_name='complaints',
null=True,
blank=True,
help_text="Source of the complaint"
)
3. Updated Feedback Model
File: apps/feedback/models.py
Before:
source = models.CharField(
max_length=50,
default='web',
help_text="Source of feedback (web, mobile, kiosk, etc.)"
)
After:
source = models.ForeignKey(
'px_sources.PXSource',
on_delete=models.PROTECT,
related_name='feedbacks',
null=True,
blank=True,
help_text="Source of feedback"
)
4. Removed Hardcoded Enums
File: apps/complaints/models.py
Removed:
ComplaintSourceenum class with hardcoded choices:- PATIENT
- FAMILY
- STAFF
- SURVEY
- SOCIAL_MEDIA
- CALL_CENTER
- MOH
- CHI
- OTHER
5. Updated Serializers
File: apps/complaints/serializers.py
Added to ComplaintSerializer:
source_name = serializers.CharField(source='source.name_en', read_only=True)
source_code = serializers.CharField(source='source.code', read_only=True)
6. Updated Call Center Views
File: apps/callcenter/ui_views.py
Changed:
# Before
from apps.complaints.models import ComplaintSource
source=ComplaintSource.CALL_CENTER
# After
from apps.px_sources.models import PXSource
call_center_source = PXSource.get_by_code('CALL_CENTER')
source=call_center_source
7. Created Data Migration
File: apps/px_sources/migrations/0003_populate_px_sources.py
Created 13 default PXSource records:
- PATIENT - Patient (complaint)
- FAMILY - Family Member (complaint)
- STAFF - Staff Report (complaint)
- SURVEY - Survey (both)
- SOCIAL_MEDIA - Social Media (both)
- CALL_CENTER - Call Center (both)
- MOH - Ministry of Health (complaint)
- CHI - Council of Health Insurance (complaint)
- OTHER - Other (both)
- WEB - Web Portal (inquiry)
- MOBILE - Mobile App (inquiry)
- KIOSK - Kiosk (inquiry)
- EMAIL - Email (inquiry)
All sources include bilingual names and descriptions.
Migrations Applied
-
px_sources.0002_remove_pxsource_color_code_and_more.py- Removed
icon_classandcolor_codefields
- Removed
-
complaints.0004_alter_complaint_source.py- Changed Complaint.source from CharField to ForeignKey
-
feedback.0003_alter_feedback_source.py- Changed Feedback.source from CharField to ForeignKey
-
px_sources.0003_populate_px_sources.py- Created 13 default PXSource records
Benefits
1. Flexibility
- New sources can be added without code changes
- Sources can be activated/deactivated dynamically
- Bilingual support out of the box
2. Maintainability
- Single source of truth for all feedback sources
- No need to modify enums in multiple files
- Centralized source management
3. Consistency
- Same source model used across Complaints, Feedback, and other modules
- Unified source tracking and reporting
- Consistent bilingual naming
4. Data Integrity
- ForeignKey relationships ensure referential integrity
- Can't accidentally use invalid source codes
- Proper cascade behavior on deletion
Usage Examples
Get a source by code:
from apps.px_sources.models import PXSource
call_center_source = PXSource.get_by_code('CALL_CENTER')
Get active sources for complaints:
sources = PXSource.get_active_sources(source_type='complaint')
Get localized name:
# In Arabic context
source_name = source.get_localized_name(language='ar')
Activate/deactivate a source:
source.activate()
source.deactivate()
Testing Results
✅ All migrations applied successfully ✅ 13 PXSource records created ✅ Complaint source field is now ForeignKey ✅ Feedback source field is now ForeignKey ✅ No data loss during migration ✅ Call center views updated and working
Files Modified
apps/px_sources/models.py- Removed icon_class, color_codeapps/px_sources/serializers.py- Updated fields listapps/px_sources/admin.py- Removed display options fieldsetapps/complaints/models.py- Changed source to ForeignKey, removed ComplaintSource enumapps/complaints/serializers.py- Added source_name, source_code fieldsapps/feedback/models.py- Changed source to ForeignKeyapps/callcenter/ui_views.py- Updated to use PXSource modelapps/px_sources/migrations/0003_populate_px_sources.py- New migration
Next Steps
- Update any custom forms that reference ComplaintSource
- Update API documentation to reflect new structure
- Add PXSource management UI if needed (admin interface already exists)
- Consider adding source usage analytics
- Train users on managing sources through admin interface
Rollback Plan
If needed, you can rollback migrations:
python manage.py migrate px_sources 0001
python manage.py migrate complaints 0003
python manage.py migrate feedback 0002
This will revert to the hardcoded enum system.