agdar/PHASE5_PATIENT_CONFIRMATION_SUMMARY.md
2025-11-02 14:35:35 +03:00

10 KiB

Phase 5: Patient Confirmation Workflow - IN PROGRESS

Overview

Implementing patient self-service appointment confirmation system with secure token generation, confirmation tracking, and automated reminder management.

Implementation Date

October 14, 2025

Status: PARTIALLY COMPLETE (60%)

Completed Components

1. AppointmentConfirmation Model

Location: appointments/models.py

Features:

  • Secure token storage (64-character hex)
  • Status tracking (PENDING, CONFIRMED, DECLINED, EXPIRED)
  • Confirmation method tracking (LINK, SMS, PHONE, IN_PERSON)
  • Metadata capture (IP, user agent, timestamps)
  • Expiration management
  • Reminder tracking (count, last sent)

Properties:

  • is_expired - Check if token expired
  • is_valid - Check if token still usable
  • get_confirmation_url() - Generate confirmation URL

2. ConfirmationService

Location: appointments/confirmation_service.py

Key Methods:

  1. generate_token() - Secure random token generation
  2. create_confirmation(appointment, expiration_days) - Create confirmation token
  3. get_confirmation_by_token(token) - Retrieve by token
  4. confirm_appointment(confirmation, method, ip, user_agent) - Process confirmation
  5. decline_appointment(confirmation, reason) - Process decline/cancellation
  6. send_confirmation_request(confirmation, request) - Send initial request
  7. send_confirmation_reminder(confirmation, request) - Send reminder
  8. get_pending_confirmations(days_ahead) - Get unconfirmed appointments
  9. expire_old_confirmations() - Cleanup expired tokens

Configuration:

  • Default expiration: 7 days
  • Maximum reminders: 3
  • Multi-channel delivery (Email + SMS)

🔄 Remaining Components

3. Confirmation Views (TODO)

Need to create:

  • confirm_appointment_view(request, token) - Handle confirmation page
  • decline_appointment_view(request, token) - Handle decline
  • Template for confirmation page

4. URL Routing (TODO)

Need to add to appointments/urls.py:

path('confirm/<str:token>/', views.confirm_appointment_view, name='confirm_appointment'),
path('decline/<str:token>/', views.decline_appointment_view, name='decline_appointment'),

5. Integration with Booking Flow (TODO)

Need to update appointments/signals.py:

  • Auto-create confirmation token on appointment booking
  • Send confirmation request automatically

6. Celery Tasks (TODO)

Need to create in appointments/tasks.py:

  • send_confirmation_reminders() - Daily task to send reminders
  • expire_old_confirmations() - Daily cleanup task

PRD Requirements Addressed

Section 5 - Notification & Reminder Flow

  • Requirement: Confirmation sent to patient
  • Status: PARTIAL - Service created, needs integration
  • Implementation: ConfirmationService.send_confirmation_request()

Section 7 - Appointment Lifecycle

  • Requirement: Confirmed stage
  • Status: PARTIAL - Confirmation logic ready, needs views
  • Implementation: ConfirmationService.confirm_appointment()

🔄 Section 12 - KPIs

  • Requirement: % of appointments confirmed before day of visit
  • Status: PENDING - Tracking ready, reporting needed
  • Implementation: Can query AppointmentConfirmation.status

Technical Details

Token Generation

# Secure 64-character hexadecimal token
token = secrets.token_hex(32)
# Example: "a1b2c3d4e5f6...64 characters"

Confirmation Flow

1. Appointment Booked
         ↓
2. Create Confirmation Token (expires in 7 days)
         ↓
3. Send Confirmation Request (Email + SMS)
         ↓
4. Patient Clicks Link
         ↓
5. Validate Token
         ↓
6. Confirm Appointment
         ↓
7. Update Status to CONFIRMED

Decline Flow

1. Patient Clicks Decline Link
         ↓
2. Validate Token
         ↓
3. Mark Confirmation as DECLINED
         ↓
4. Cancel Appointment
         ↓
5. Send Cancellation Confirmation

Reminder Logic

# Send up to 3 reminders
if confirmation.reminder_count < 3:
    send_confirmation_reminder(confirmation)
    confirmation.reminder_count += 1

Database Schema

AppointmentConfirmation Fields

  • id (UUID) - Primary key
  • appointment (FK) - Related appointment
  • token (CharField, unique) - Confirmation token
  • status (CharField) - PENDING/CONFIRMED/DECLINED/EXPIRED
  • confirmation_method (CharField) - How confirmed
  • confirmed_at (DateTime) - When confirmed
  • confirmed_by_ip (IP) - IP address
  • confirmed_by_user_agent (Text) - Browser info
  • expires_at (DateTime) - Expiration time
  • sent_at (DateTime) - When request sent
  • reminder_count (Int) - Number of reminders sent
  • last_reminder_at (DateTime) - Last reminder time

Security Features

Token Security

  • 64-character hexadecimal (256-bit entropy)
  • Unique constraint in database
  • Single-use (marked as used after confirmation)
  • Time-limited (7-day expiration)

Metadata Tracking

  • IP address capture
  • User agent logging
  • Timestamp recording
  • Audit trail complete

Validation

  • Token existence check
  • Expiration validation
  • Status validation
  • Appointment status check

Usage Examples

Create Confirmation

from appointments.confirmation_service import ConfirmationService

# Create token
confirmation = ConfirmationService.create_confirmation(appointment)

# Send request
ConfirmationService.send_confirmation_request(confirmation, request)

Process Confirmation

# Get by token
confirmation = ConfirmationService.get_confirmation_by_token(token)

# Confirm
success, message = ConfirmationService.confirm_appointment(
    confirmation,
    method='LINK',
    ip_address=request.META.get('REMOTE_ADDR'),
    user_agent=request.META.get('HTTP_USER_AGENT')
)

Send Reminder

# Check pending confirmations
pending = ConfirmationService.get_pending_confirmations(days_ahead=3)

for confirmation in pending:
    if confirmation.reminder_count < 3:
        ConfirmationService.send_confirmation_reminder(confirmation)

Next Steps to Complete Phase 5

1. Create Confirmation Views

# appointments/views.py
def confirm_appointment_view(request, token):
    confirmation = ConfirmationService.get_confirmation_by_token(token)
    # Handle GET (show page) and POST (process confirmation)
    
def decline_appointment_view(request, token):
    confirmation = ConfirmationService.get_confirmation_by_token(token)
    # Handle decline

2. Create Templates

  • templates/appointments/confirm_appointment.html
  • Success/error messages
  • Mobile-friendly design

3. Add URL Routes

# appointments/urls.py
urlpatterns = [
    path('confirm/<str:token>/', views.confirm_appointment_view, name='confirm_appointment'),
    path('decline/<str:token>/', views.decline_appointment_view, name='decline_appointment'),
]

4. Integrate with Booking

# appointments/signals.py - in appointment_post_save
if created and instance.status == 'BOOKED':
    # Create confirmation
    confirmation = ConfirmationService.create_confirmation(instance)
    # Send request
    ConfirmationService.send_confirmation_request(confirmation)

5. Add Celery Tasks

# appointments/tasks.py
@shared_task
def send_pending_confirmation_reminders():
    """Send reminders for unconfirmed appointments"""
    pending = ConfirmationService.get_pending_confirmations(days_ahead=3)
    for confirmation in pending:
        if confirmation.reminder_count < 3:
            ConfirmationService.send_confirmation_reminder(confirmation)

@shared_task
def expire_old_confirmation_tokens():
    """Mark expired tokens as EXPIRED"""
    ConfirmationService.expire_old_confirmations()

6. Configure Celery Beat

CELERY_BEAT_SCHEDULE = {
    'send-confirmation-reminders': {
        'task': 'appointments.tasks.send_pending_confirmation_reminders',
        'schedule': crontab(hour=9, minute=0),  # Daily at 9 AM
    },
    'expire-confirmation-tokens': {
        'task': 'appointments.tasks.expire_old_confirmation_tokens',
        'schedule': crontab(hour=0, minute=0),  # Daily at midnight
    },
}

Files Created

  1. appointments/models.py - Added AppointmentConfirmation model
  2. appointments/confirmation_service.py - Complete confirmation service

Files To Create

  1. templates/appointments/confirm_appointment.html - Confirmation page
  2. Views in appointments/views.py - Confirmation handlers
  3. Routes in appointments/urls.py - URL patterns
  4. Tasks in appointments/tasks.py - Celery tasks

Testing Recommendations

Unit Tests

def test_token_generation():
    """Test secure token generation"""
    token = ConfirmationService.generate_token()
    assert len(token) == 64
    assert token.isalnum()

def test_create_confirmation():
    """Test confirmation creation"""
    confirmation = ConfirmationService.create_confirmation(appointment)
    assert confirmation.status == 'PENDING'
    assert confirmation.is_valid

def test_confirm_appointment():
    """Test appointment confirmation"""
    success, message = ConfirmationService.confirm_appointment(confirmation)
    assert success
    assert confirmation.status == 'CONFIRMED'
    assert appointment.status == 'CONFIRMED'

def test_expired_token():
    """Test expired token handling"""
    # Set expiration in past
    confirmation.expires_at = timezone.now() - timedelta(days=1)
    success, message = ConfirmationService.confirm_appointment(confirmation)
    assert not success
    assert "expired" in message.lower()

Benefits Delivered (So Far)

1. Security

  • Secure token generation
  • Single-use tokens
  • Time-limited validity
  • Metadata tracking

2. Patient Experience

  • Self-service confirmation
  • Multi-channel delivery
  • Clear expiration dates
  • Decline option available

3. Operational Efficiency

  • Automated confirmation requests
  • Reminder management
  • Status tracking
  • Audit trail

Conclusion

Phase 5 is 60% complete with core confirmation logic implemented. The ConfirmationService provides all necessary functionality for secure token management and confirmation processing. Remaining work focuses on user-facing components (views, templates, URLs) and automation (Celery tasks, signal integration).

Status: 🔄 IN PROGRESS - Core Logic Complete, UI Components Pending

Estimated Time to Complete: 2-3 hours for remaining components