Notifications Models ==================== Notification ------------ A message sent to a user via a specific communication channel. .. list-table:: :header-rows: 1 :widths: 20 20 20 40 * - Field - Type - Constraints - Description * - id - UUIDField - PK, default=uuid4 - Primary key * - recipient - ForeignKey(User) - not null, on_delete=CASCADE - Message recipient * - channel - CharField(20) - choices: ``sms``, ``email``, ``whatsapp``, ``push``, ``call`` - Delivery channel * - template - ForeignKey(NotificationTemplate) - nullable, on_delete=SET_NULL - Template used (if any) * - subject - CharField(255) - blank - Subject line (email only) * - body - TextField - not null - Message body * - context_type - CharField(30) - choices: ``lead``, ``survey``, ``installation``, ``payment``, ``emergency`` - What triggered this notification * - context_id - UUIDField - nullable - ID of the related object * - status - CharField(20) - choices: ``queued``, ``sent``, ``delivered``, ``failed`` - Delivery state * - sent_at - DateTimeField - nullable - When message was sent * - delivered_at - DateTimeField - nullable - When delivery was confirmed * - created_at - DateTimeField - auto_now_add - Creation timestamp **Indexes**: ``recipient``, ``status``, ``context_type``, ``created_at`` NotificationTemplate -------------------- Reusable message templates with dynamic placeholders. .. list-table:: :header-rows: 1 :widths: 20 20 20 40 * - Field - Type - Constraints - Description * - id - AutoField - PK - Primary key * - name - CharField(100) - unique - Template identifier (e.g., ``survey_confirmation_sms``) * - channel - CharField(20) - choices: ``sms``, ``email``, ``whatsapp``, ``push`` - Target channel * - subject_template - CharField(255) - blank - Subject with ``{{ placeholders }}`` (email only) * - body_template - TextField - not null - Body with Django template syntax * - is_active - BooleanField - default=True - Whether template is currently in use CallLog ------- Records every phone call made within ChargeSol workflows. .. list-table:: :header-rows: 1 :widths: 20 20 20 40 * - Field - Type - Constraints - Description * - id - UUIDField - PK, default=uuid4 - Primary key * - caller - ForeignKey(User) - not null, on_delete=PROTECT - Who made the call * - callee_phone - CharField(15) - not null - Phone number called * - call_type - CharField(30) - choices: ``introductory``, ``survey_confirmation``, ``installation_confirmation``, ``post_install``, ``emergency``, ``reschedule`` - Purpose of the call * - context_type - CharField(30) - not null - Related entity type (lead, survey, installation) * - context_id - UUIDField - not null - Related entity ID * - outcome - CharField(30) - choices: ``connected``, ``no_answer``, ``busy``, ``voicemail``, ``callback_requested`` - Call result * - duration_seconds - IntegerField - nullable - Call duration in seconds * - notes - TextField - blank - Call notes / summary * - called_at - DateTimeField - auto_now_add - When call was made **Indexes**: ``call_type``, ``context_type``, ``called_at`` DeliveryReceipt --------------- Webhook-driven delivery confirmations from SMS/WhatsApp gateways. .. list-table:: :header-rows: 1 :widths: 20 20 20 40 * - Field - Type - Constraints - Description * - id - UUIDField - PK, default=uuid4 - Primary key * - notification - ForeignKey(Notification) - not null, on_delete=CASCADE - Parent notification * - status - CharField(20) - choices: ``sent``, ``delivered``, ``read``, ``failed`` - Delivery status from gateway * - gateway_message_id - CharField(100) - nullable - External gateway reference * - error_code - CharField(50) - nullable - Error code if failed * - error_message - TextField - blank - Error description * - received_at - DateTimeField - auto_now_add - When receipt was received