518 lines
14 KiB
Markdown
518 lines
14 KiB
Markdown
# Phase 1: Models Implementation - Progress Report
|
|
|
|
## ✅ Completed Models (5 of 11 apps - 45% complete)
|
|
|
|
### 1. Core App ✅ COMPLETE
|
|
**File:** `core/models.py`
|
|
**Models:** 9 models + 5 base mixins
|
|
- Base Mixins: UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin, SoftDeleteMixin
|
|
- Tenant, User (8 roles), Patient (bilingual), Clinic (5 specialties)
|
|
- File, SubFile, Consent (e-signature), Attachment (GenericFK), AuditLog
|
|
|
|
### 2. Appointments App ✅ COMPLETE
|
|
**File:** `appointments/models.py`
|
|
**Models:** 5 models
|
|
- Provider, Room, Schedule (weekly recurring)
|
|
- Appointment (8-state machine with properties)
|
|
- AppointmentReminder
|
|
|
|
### 3. Finance App ✅ COMPLETE
|
|
**File:** `finance/models.py`
|
|
**Models:** 7 models
|
|
- Service, Package, Payer
|
|
- Invoice (with properties), InvoiceLineItem, Payment
|
|
- PackagePurchase (usage tracking)
|
|
|
|
### 4. Notifications App ✅ COMPLETE
|
|
**File:** `notifications/models.py`
|
|
**Models:** 4 models
|
|
- MessageTemplate (bilingual with render method)
|
|
- Message (delivery tracking)
|
|
- NotificationPreference (with can_send method)
|
|
- MessageLog
|
|
|
|
### 5. Nursing App ✅ COMPLETE
|
|
**File:** `nursing/models.py`
|
|
**Models:** 3 models
|
|
- NursingEncounter (MD-N-F-1 with BMI calculation, abnormal vitals detection)
|
|
- GrowthChart (percentiles, auto-population)
|
|
- VitalSignsAlert
|
|
|
|
---
|
|
|
|
## 📋 Remaining Models to Implement (6 apps - 55%)
|
|
|
|
### 6. Medical App - TO DO NEXT
|
|
**File:** `medical/models.py` (to be created)
|
|
**Based on:** MD-F-1 and MD-F-2 forms
|
|
|
|
**Models Required:**
|
|
|
|
#### MedicalConsultation (MD-F-1)
|
|
```python
|
|
class MedicalConsultation(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""Medical consultation form MD-F-1"""
|
|
patient FK, appointment FK, consultation_date, provider FK
|
|
|
|
# History Sections
|
|
chief_complaint (TextField)
|
|
present_illness_history (TextField)
|
|
past_medical_history (TextField)
|
|
vaccination_status (TextField)
|
|
family_history (TextField)
|
|
social_history (TextField)
|
|
pregnancy_history (TextField)
|
|
neonatal_history (TextField)
|
|
|
|
# Developmental Milestones (TextFields)
|
|
developmental_motor_milestones
|
|
developmental_language_milestones
|
|
developmental_social_milestones
|
|
developmental_cognitive_milestones
|
|
|
|
# Behavioral Symptoms (JSONField - checklist)
|
|
behavioral_symptoms
|
|
|
|
# Physical Exam (JSONField - structured)
|
|
physical_exam
|
|
|
|
# Assessment & Plan
|
|
clinical_summary (TextField)
|
|
recommendations (TextField)
|
|
referrals_needed (TextField)
|
|
lab_orders (JSONField)
|
|
radiology_orders (JSONField)
|
|
|
|
history = HistoricalRecords()
|
|
```
|
|
|
|
#### MedicationPlan
|
|
```python
|
|
class MedicationPlan(UUIDPrimaryKeyMixin):
|
|
"""Medication details for consultation"""
|
|
consultation FK
|
|
drug_name, dose
|
|
frequency: TextChoices (DAILY, BID, TID, QID, PRN, OTHER)
|
|
frequency_other
|
|
compliance: TextChoices (GOOD, PARTIAL, BAD)
|
|
gains (TextField)
|
|
side_effects (TextField)
|
|
target_behavior (TextField)
|
|
improved (BooleanField)
|
|
```
|
|
|
|
#### MedicalFollowUp (MD-F-2)
|
|
```python
|
|
class MedicalFollowUp(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""Medical follow-up form MD-F-2"""
|
|
patient FK, appointment FK
|
|
previous_consultation FK (to MedicalConsultation)
|
|
followup_date, provider FK
|
|
|
|
# Previous complaints status (JSONField: complaint → RESOLVED/STATIC/WORSE)
|
|
previous_complaints_status
|
|
new_complaints (TextField)
|
|
|
|
# Links
|
|
nursing_vitals FK (to nursing.NursingEncounter)
|
|
|
|
# Assessment
|
|
assessment (TextField)
|
|
recommendations (TextField)
|
|
family_satisfaction: TextChoices (ZERO, FIFTY, HUNDRED)
|
|
medication_snapshot (JSONField)
|
|
|
|
history = HistoricalRecords()
|
|
```
|
|
|
|
---
|
|
|
|
### 7. ABA App - TO DO
|
|
**File:** `aba/models.py` (to be created)
|
|
**Based on:** ABA-F-1 form
|
|
|
|
**Models Required:**
|
|
|
|
#### ABAConsult
|
|
```python
|
|
class ABAConsult(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""ABA consultation form ABA-F-1"""
|
|
patient FK, appointment FK, consultation_date, provider FK
|
|
|
|
reason_of_referral: TextChoices (from form options)
|
|
parental_concern (TextField)
|
|
school_concern (TextField)
|
|
respondents (CharField)
|
|
interviewer (CharField)
|
|
diagnosed_condition (CharField)
|
|
interaction_hours_per_day (PositiveIntegerField)
|
|
|
|
# Factors (JSONField with booleans)
|
|
physiological_factors
|
|
medical_factors
|
|
|
|
recommendations (TextField)
|
|
|
|
history = HistoricalRecords()
|
|
```
|
|
|
|
#### ABABehavior
|
|
```python
|
|
class ABABehavior(UUIDPrimaryKeyMixin):
|
|
"""Behavior details for ABA consult"""
|
|
consult FK
|
|
behavior_description (TextField)
|
|
frequency: TextChoices (HOURLY, DAILY, WEEKLY, LESS_THAN_WEEKLY)
|
|
duration (CharField)
|
|
intensity: TextChoices (MILD, MODERATE, SEVERE)
|
|
antecedents_likely (TextField)
|
|
antecedents_least_likely (TextField)
|
|
consequences (TextField)
|
|
order (PositiveIntegerField for sorting)
|
|
```
|
|
|
|
---
|
|
|
|
### 8. OT App - TO DO
|
|
**File:** `ot/models.py` (to be created)
|
|
**Based on:** OT-F-1 and OT-F-3 forms
|
|
|
|
**Models Required:**
|
|
|
|
#### OTConsult (OT-F-1)
|
|
```python
|
|
class OTConsult(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""OT consultation form OT-F-1"""
|
|
patient FK, appointment FK, consultation_date, provider FK
|
|
|
|
reasons (ArrayField or JSONField with choices)
|
|
top_difficulty_areas (JSONField: 3 text fields)
|
|
|
|
# Developmental & skills (JSONField matrices)
|
|
developmental_motor_milestones
|
|
self_help_skills
|
|
feeding_participation
|
|
|
|
# Behavior descriptors (JSONField)
|
|
infant_behavior_descriptors
|
|
current_behavior_descriptors
|
|
|
|
recommendation: TextChoices (CONTINUE, DISCHARGE, REFER_TO_OTHER)
|
|
recommendation_notes (TextField)
|
|
|
|
history = HistoricalRecords()
|
|
```
|
|
|
|
#### OTSession (OT-F-3)
|
|
```python
|
|
class OTSession(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""OT session notes form OT-F-3"""
|
|
patient FK, appointment FK (nullable), session_date, provider FK
|
|
|
|
session_type: TextChoices (CONSULT, INDIVIDUAL, GROUP, PARENT_TRAINING)
|
|
cooperative_level (PositiveSmallIntegerField 1-4)
|
|
distraction_tolerance (PositiveSmallIntegerField 1-4)
|
|
|
|
activities_checklist (JSONField: "Today we work on...")
|
|
observations (TextField)
|
|
activities_performed (TextField)
|
|
recommendations (TextField)
|
|
|
|
history = HistoricalRecords()
|
|
```
|
|
|
|
#### OTTargetSkill
|
|
```python
|
|
class OTTargetSkill(UUIDPrimaryKeyMixin):
|
|
"""Target skills with 0-10 scoring"""
|
|
session FK
|
|
skill_name (CharField)
|
|
score (PositiveSmallIntegerField 0-10)
|
|
notes (TextField)
|
|
order (PositiveIntegerField)
|
|
```
|
|
|
|
---
|
|
|
|
### 9. SLP App - TO DO
|
|
**File:** `slp/models.py` (to be created)
|
|
**Based on:** SLP-F-1, F-2, F-3, F-4 forms
|
|
|
|
**Models Required:**
|
|
|
|
#### SLPConsult (SLP-F-1)
|
|
```python
|
|
class SLPConsult(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""SLP consultation form SLP-F-1 with variants"""
|
|
patient FK, appointment FK, consultation_date, provider FK
|
|
|
|
consult_variant: TextChoices (ASD, LANGUAGE_DELAY, FLUENCY)
|
|
primary_concern (TextField)
|
|
suspected_areas (JSONField)
|
|
type_of_service: TextChoices (CONSULT, EVAL, INTERVENTION, PARENT_TRAINING)
|
|
|
|
communication_modes (JSONField checklist)
|
|
screen_time_hours (PositiveIntegerField)
|
|
|
|
# Variant-specific questionnaires (JSONField)
|
|
variant_questionnaire
|
|
|
|
# Skills to observe (JSONField matrix)
|
|
skills_to_observe
|
|
|
|
# Oral motor screening (JSONField)
|
|
oral_motor_screening
|
|
|
|
recommendations (TextField)
|
|
|
|
history = HistoricalRecords()
|
|
```
|
|
|
|
#### SLPAssessment (SLP-F-2)
|
|
```python
|
|
class SLPAssessment(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""SLP assessment form SLP-F-2"""
|
|
patient FK, appointment FK, assessment_date, provider FK
|
|
|
|
diagnosis_statement (TextField)
|
|
case_history (TextField)
|
|
|
|
# History sections
|
|
prenatal_history (TextField)
|
|
perinatal_history (TextField)
|
|
postnatal_history (TextField)
|
|
developmental_history (TextField)
|
|
medical_status (TextField)
|
|
|
|
# Speech/Language detail (JSONField)
|
|
speech_language_detail
|
|
|
|
# Test scores
|
|
gfta3_score (CharField)
|
|
jat_score (CharField)
|
|
ssi_score (CharField)
|
|
|
|
# Oral mechanism (JSONField)
|
|
oral_mechanism
|
|
|
|
# Rossetti domains (JSONField: domain → age level)
|
|
rossetti_domains
|
|
|
|
# Joint attention skills (JSONField)
|
|
joint_attention_skills
|
|
|
|
# Summary & Plan
|
|
clinical_summary (TextField)
|
|
recommendations (TextField)
|
|
frequency_per_week (PositiveIntegerField)
|
|
session_duration_minutes (PositiveIntegerField)
|
|
referral_rules (JSONField)
|
|
|
|
history = HistoricalRecords()
|
|
```
|
|
|
|
#### SLPIntervention (SLP-F-3)
|
|
```python
|
|
class SLPIntervention(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""SLP intervention session form SLP-F-3"""
|
|
patient FK, appointment FK
|
|
session_number (PositiveIntegerField)
|
|
session_date, session_time
|
|
provider FK
|
|
previous_session FK (self-referential, nullable)
|
|
|
|
history = HistoricalRecords()
|
|
```
|
|
|
|
#### SLPTarget
|
|
```python
|
|
class SLPTarget(UUIDPrimaryKeyMixin):
|
|
"""Intervention targets (SOAP format)"""
|
|
intervention FK
|
|
target_number (PositiveSmallIntegerField 1 or 2)
|
|
subjective (TextField)
|
|
objective (TextField)
|
|
assessment (TextField)
|
|
plan (TextField)
|
|
prompt_strategies (JSONField)
|
|
```
|
|
|
|
#### SLPProgressReport (SLP-F-4)
|
|
```python
|
|
class SLPProgressReport(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin, ClinicallySignableMixin):
|
|
"""SLP progress report form SLP-F-4"""
|
|
patient FK, report_date, provider FK
|
|
|
|
sessions_scheduled (PositiveIntegerField)
|
|
sessions_attended (PositiveIntegerField)
|
|
final_diagnosis (TextField)
|
|
|
|
# Objectives & progress (JSONField: objective → % accuracy)
|
|
objectives_progress
|
|
|
|
# Plan details (JSONField)
|
|
plan_details
|
|
|
|
overall_progress (TextField)
|
|
participation_level (TextField)
|
|
attendance_rate (DecimalField)
|
|
carryover_level (TextField)
|
|
prognosis (TextField)
|
|
recommendations (TextField)
|
|
|
|
package_sessions_count (PositiveIntegerField)
|
|
reassessment_needed (BooleanField)
|
|
|
|
history = HistoricalRecords()
|
|
```
|
|
|
|
---
|
|
|
|
### 10. Referrals App - TO DO
|
|
**File:** `referrals/models.py` (to be created)
|
|
|
|
**Models Required:**
|
|
|
|
#### Referral
|
|
```python
|
|
class Referral(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin):
|
|
"""Inter-discipline and external referrals"""
|
|
patient FK
|
|
from_clinic FK, to_clinic FK (nullable)
|
|
from_provider FK, to_provider FK (nullable)
|
|
external_provider_name (CharField)
|
|
|
|
reason (TextField)
|
|
urgency: TextChoices (ROUTINE, URGENT, EMERGENCY)
|
|
status: TextChoices (PENDING, ACCEPTED, REJECTED, COMPLETED)
|
|
|
|
created_at, responded_at
|
|
notes (TextField)
|
|
```
|
|
|
|
---
|
|
|
|
### 11. Integrations App - TO DO
|
|
**File:** `integrations/models.py` (to be created)
|
|
|
|
**Models Required:**
|
|
|
|
#### ExternalOrder (Lab/Radiology)
|
|
```python
|
|
class ExternalOrder(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin):
|
|
"""Lab and radiology orders"""
|
|
patient FK
|
|
order_type: TextChoices (LAB, RADIOLOGY)
|
|
order_details (JSONField)
|
|
status: TextChoices (ORDERED, IN_PROGRESS, COMPLETED, CANCELLED)
|
|
result_url (URLField)
|
|
result_data (JSONField)
|
|
ordered_by FK, ordered_at, completed_at
|
|
```
|
|
|
|
#### NphiesMessage (Insurance e-Claims)
|
|
```python
|
|
class NphiesMessage(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin):
|
|
"""NPHIES FHIR messages"""
|
|
direction: TextChoices (OUTBOUND, INBOUND)
|
|
resource_type: TextChoices (ELIGIBILITY, PRIOR_AUTH, CLAIM, PAYMENT_NOTICE, PAYMENT_RECONCILIATION)
|
|
fhir_json (JSONField)
|
|
status: TextChoices (QUEUED, SENT, ACK, ERROR)
|
|
correlation_id (CharField)
|
|
response_http_status (PositiveIntegerField)
|
|
error_code, error_message
|
|
created_at, sent_at
|
|
```
|
|
|
|
#### NphiesEncounterLink
|
|
```python
|
|
class NphiesEncounterLink(UUIDPrimaryKeyMixin, TenantOwnedMixin):
|
|
"""Link appointments to NPHIES encounters"""
|
|
patient FK, appointment FK
|
|
encounter_id, claim_id, claim_response_id (CharField)
|
|
```
|
|
|
|
#### PayerContract
|
|
```python
|
|
class PayerContract(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin):
|
|
"""Insurance payer configurations"""
|
|
payer_code, payer_name
|
|
credentials (JSONField encrypted)
|
|
endpoints (JSONField)
|
|
supports_eligibility, supports_prior_auth, supports_claims (BooleanField)
|
|
is_active
|
|
```
|
|
|
|
#### EInvoice (ZATCA)
|
|
```python
|
|
class EInvoice(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin):
|
|
"""ZATCA e-invoices"""
|
|
invoice FK (to finance.Invoice)
|
|
uuid (UUIDField)
|
|
xml_payload (TextField)
|
|
qr_base64 (TextField)
|
|
clearance_status: TextChoices (PENDING, CLEARED, REJECTED, REPORTED)
|
|
zatca_document_type (CharField)
|
|
submission_mode: TextChoices (CLEARANCE, REPORTING)
|
|
response_payload (JSONField)
|
|
error_code, error_message
|
|
submitted_at
|
|
```
|
|
|
|
#### ZatcaCredential
|
|
```python
|
|
class ZatcaCredential(UUIDPrimaryKeyMixin, TimeStampedMixin, TenantOwnedMixin):
|
|
"""ZATCA credentials (CSIDs)"""
|
|
environment: TextChoices (SIMULATION, COMPLIANCE, PRODUCTION)
|
|
csid, certificate, private_key (TextField encrypted)
|
|
is_active, expires_at
|
|
```
|
|
|
|
---
|
|
|
|
## Summary Statistics
|
|
|
|
**Total Models Across All Apps:** ~50 models
|
|
**Completed:** 28 models (56%)
|
|
**Remaining:** 22 models (44%)
|
|
|
|
**Apps Complete:** 5 of 11 (45%)
|
|
**Apps Remaining:** 6 of 11 (55%)
|
|
|
|
---
|
|
|
|
## Next Steps
|
|
|
|
1. ✅ Create medical app models (3 models)
|
|
2. ✅ Create aba app models (2 models)
|
|
3. ✅ Create ot app models (3 models)
|
|
4. ✅ Create slp app models (5 models)
|
|
5. ✅ Create referrals app models (1 model)
|
|
6. ✅ Create integrations app models (6 models)
|
|
7. Run `python manage.py makemigrations`
|
|
8. Run `python manage.py migrate`
|
|
9. Create signals for auto-generation (MRN, file numbers, etc.)
|
|
10. Begin Phase 2 (Forms)
|
|
|
|
---
|
|
|
|
## Key Features Implemented So Far
|
|
|
|
✅ UUID primary keys throughout
|
|
✅ Multi-tenancy support
|
|
✅ Role-based access control (8 roles)
|
|
✅ Bilingual support (Arabic/English)
|
|
✅ Audit trail with simple_history
|
|
✅ E-signature support
|
|
✅ State machines (Appointments)
|
|
✅ Auto-calculations (BMI, totals, percentiles)
|
|
✅ Property methods for business logic
|
|
✅ Comprehensive indexes
|
|
✅ Proper relationships and on_delete rules
|
|
✅ JSONField for flexible data structures
|
|
✅ MoneyField for currency handling
|
|
✅ Template rendering for notifications
|
|
✅ Growth chart tracking
|
|
✅ Vital signs alerts
|
|
✅ Package usage tracking
|