13 KiB
Group Session Implementation Report
Overview
This document details the implementation of group session support for the AgdarCentre appointment system, allowing multiple patients to be booked into the same appointment slot for group therapy sessions.
Implementation Date
November 11, 2025
Requirements Summary
Based on user requirements:
- Capacity: 1-20 patients per group session
- Workflow: Create empty group sessions, add patients later
- Status Tracking: Individual status per patient
- Billing: Per patient (separate invoices)
- Documentation: Both shared group notes AND individual patient notes
- Architecture: Session-based model (Option 1)
What Was Implemented
1. Database Models (✅ COMPLETED)
New Model: Session
Located in: appointments/models.py
Purpose: Represents a scheduled session (individual or group) that can accommodate one or more patients.
Key Fields:
session_number: Unique identifier (auto-generated)session_type: INDIVIDUAL or GROUPmax_capacity: 1-20 patients (validated)provider,clinic,room: Core relationshipsscheduled_date,scheduled_time,duration: Schedulingstatus: SCHEDULED, IN_PROGRESS, COMPLETED, CANCELLEDgroup_notes: Shared notes for entire session
Key Properties:
current_capacity: Number of enrolled patientsavailable_spots: Remaining capacityis_full: Boolean check if at capacitycapacity_percentage: Utilization percentageget_participants_list(): Get enrolled patients
New Model: SessionParticipant
Located in: appointments/models.py
Purpose: Represents individual patient participation in a session with unique tracking.
Key Fields:
session: FK to Sessionpatient: FK to Patientappointment_number: Unique per participant (for billing)status: BOOKED, CONFIRMED, CANCELLED, NO_SHOW, ARRIVED, ATTENDEDconfirmation_sent_at,arrival_at,attended_at: Individual timestampsindividual_notes: Patient-specific notesfinance_cleared,consent_verified: Per-patient prerequisitesno_show_reason,no_show_notes: Individual tracking
Key Properties:
can_check_in: Check if prerequisites metget_status_color(): UI color coding
Modified Model: Appointment
Added Field:
session: FK to Session (nullable, for backward compatibility)
This allows existing appointments to be linked to sessions during migration.
2. Migration Files (✅ COMPLETED)
Migration: appointments/migrations/0004_add_session_models.py
Creates:
- Session model with all fields and indexes
- SessionParticipant model with all fields and indexes
- HistoricalSession (for audit trail)
- HistoricalSessionParticipant (for audit trail)
- Adds session FK to Appointment model
- Creates all necessary database indexes for performance
Status: Migration file created, ready to run with python3 manage.py migrate
Architecture Design
Data Flow for Group Sessions
1. CREATE GROUP SESSION
└─> Session (capacity=8, type=GROUP)
└─> session_number: "SES-AGDAR-2025-12345"
2. ADD PATIENTS TO SESSION
├─> SessionParticipant #1 (Patient A)
│ └─> appointment_number: "APT-AGDAR-2025-10001"
├─> SessionParticipant #2 (Patient B)
│ └─> appointment_number: "APT-AGDAR-2025-10002"
└─> SessionParticipant #3 (Patient C)
└─> appointment_number: "APT-AGDAR-2025-10003"
3. INDIVIDUAL TRACKING
├─> Patient A: CONFIRMED, finance_cleared=True
├─> Patient B: BOOKED, finance_cleared=False
└─> Patient C: NO_SHOW
4. BILLING
├─> Invoice for APT-AGDAR-2025-10001 (Patient A)
├─> Invoice for APT-AGDAR-2025-10002 (Patient B)
└─> Invoice for APT-AGDAR-2025-10003 (Patient C)
Backward Compatibility
Existing Appointments:
- All existing appointments remain functional
- Can be migrated to individual sessions (capacity=1)
- Appointment model retained for legacy support
- New bookings can use either Appointment or Session models
Next Steps (TODO)
Phase 1: Service Layer (HIGH PRIORITY)
Create SessionService class
Location: appointments/session_service.py
Methods to implement:
class SessionService:
@staticmethod
def create_group_session(provider, clinic, date, time, duration, service_type, max_capacity, **kwargs)
@staticmethod
def add_patient_to_session(session, patient, **kwargs)
@staticmethod
def remove_patient_from_session(participant, reason)
@staticmethod
def get_available_group_sessions(clinic, date_from, date_to, service_type=None)
@staticmethod
def check_session_capacity(session)
@staticmethod
def _generate_session_number(tenant)
@staticmethod
def _generate_appointment_number(tenant)
Update AppointmentService
Location: appointments/services.py
Modifications needed:
- Update
check_conflicts()to handle group sessions - Add session-aware booking logic
- Integrate with SessionService for group bookings
Phase 2: Admin Interface (HIGH PRIORITY)
Create Django Admin
Location: appointments/admin.py
Admin classes to add:
@admin.register(Session)
class SessionAdmin(admin.ModelAdmin):
list_display = ['session_number', 'session_type', 'provider', 'scheduled_date', 'current_capacity', 'max_capacity', 'status']
list_filter = ['session_type', 'status', 'clinic', 'scheduled_date']
search_fields = ['session_number', 'provider__user__first_name', 'provider__user__last_name']
readonly_fields = ['session_number', 'current_capacity', 'available_spots']
inlines = [SessionParticipantInline]
@admin.register(SessionParticipant)
class SessionParticipantAdmin(admin.ModelAdmin):
list_display = ['appointment_number', 'patient', 'session', 'status', 'finance_cleared', 'consent_verified']
list_filter = ['status', 'finance_cleared', 'consent_verified']
search_fields = ['appointment_number', 'patient__first_name_en', 'patient__last_name_en']
Phase 3: Forms (MEDIUM PRIORITY)
Create Session Forms
Location: appointments/forms.py
Forms to add:
GroupSessionCreateForm- Create new group sessionAddPatientToSessionForm- Add patient to existing sessionSessionParticipantStatusForm- Update participant statusGroupSessionNotesForm- Edit group notes
Phase 4: Views (MEDIUM PRIORITY)
Create Session Views
Location: appointments/views.py or appointments/session_views.py
Views to implement:
GroupSessionListView- List all group sessionsGroupSessionDetailView- View session with all participantsGroupSessionCreateView- Create new group sessionAddPatientToSessionView- Add patient to sessionSessionParticipantCheckInView- Check in individual participantGroupSessionCalendarView- Calendar view with group sessions
Phase 5: Templates (MEDIUM PRIORITY)
Create Templates
Location: appointments/templates/appointments/
Templates needed:
group_session_list.html- List of group sessionsgroup_session_detail.html- Session details with participantsgroup_session_form.html- Create/edit group sessionadd_patient_to_session.html- Add patient formsession_participant_checkin.html- Check-in interfacepartials/session_capacity_badge.html- Capacity indicator
Phase 6: API Endpoints (LOW PRIORITY)
REST API
Location: appointments/api_views.py
Endpoints to add:
GET /api/sessions/- List sessionsPOST /api/sessions/- Create sessionGET /api/sessions/{id}/- Session detailPOST /api/sessions/{id}/add-patient/- Add patientGET /api/sessions/available/- Available group sessionsPATCH /api/sessions/{id}/participants/{id}/- Update participant
Phase 7: Integration (LOW PRIORITY)
Billing Integration
- Link SessionParticipant.appointment_number to invoices
- Ensure per-patient billing works correctly
- Test invoice generation for group session participants
Clinical Documentation
- Link clinical forms to SessionParticipant.appointment_number
- Support both group_notes and individual_notes
- Update form templates to show session context
Notifications
- Send individual confirmations to each participant
- Group session reminders
- Capacity alerts (session full, spots available)
Phase 8: Testing (CRITICAL)
Unit Tests
Location: appointments/tests/
Test cases:
- Session creation with various capacities
- Adding patients up to capacity
- Capacity overflow prevention
- Individual status tracking
- Appointment number generation
- Conflict checking for group sessions
Integration Tests
- Full booking workflow
- Check-in process for group sessions
- Billing integration
- Clinical documentation linking
Migration Strategy
Step 1: Run Migration
python3 manage.py migrate appointments
Step 2: Data Migration (Optional)
Create a data migration to convert existing appointments to sessions:
# appointments/migrations/0005_migrate_appointments_to_sessions.py
def migrate_appointments_to_sessions(apps, schema_editor):
Appointment = apps.get_model('appointments', 'Appointment')
Session = apps.get_model('appointments', 'Session')
SessionParticipant = apps.get_model('appointments', 'SessionParticipant')
for appointment in Appointment.objects.all():
# Create individual session
session = Session.objects.create(
tenant=appointment.tenant,
session_number=f"SES-{appointment.appointment_number}",
session_type='INDIVIDUAL',
max_capacity=1,
provider=appointment.provider,
clinic=appointment.clinic,
room=appointment.room,
service_type=appointment.service_type,
scheduled_date=appointment.scheduled_date,
scheduled_time=appointment.scheduled_time,
duration=appointment.duration,
status='SCHEDULED' if appointment.status in ['BOOKED', 'CONFIRMED'] else 'COMPLETED',
)
# Create participant
SessionParticipant.objects.create(
session=session,
patient=appointment.patient,
appointment_number=appointment.appointment_number,
status=appointment.status,
finance_cleared=appointment.finance_cleared,
consent_verified=appointment.consent_verified,
)
# Link appointment to session
appointment.session = session
appointment.save()
Step 3: Update Existing Code
- Update views to handle both Appointment and Session models
- Update templates to show session information
- Update services to use SessionService for new bookings
Benefits of This Implementation
1. Scalability
- Supports 1-20 patients per session
- Easy to adjust capacity limits
- Efficient database queries with proper indexing
2. Flexibility
- Create empty sessions and add patients later
- Individual status tracking per patient
- Support for both individual and group sessions
3. Data Integrity
- Unique appointment numbers for billing
- Proper foreign key relationships
- Audit trail with simple-history
4. User Experience
- Clear capacity indicators
- Individual patient management
- Separate notes for group and individual
5. Billing Accuracy
- Each participant gets unique appointment number
- Per-patient invoicing
- Clear audit trail
Technical Considerations
Performance
- Indexed fields for fast queries
- Efficient capacity calculations
- Optimized participant lookups
Security
- Tenant isolation maintained
- Permission checks per participant
- Audit trail for all changes
Maintainability
- Clean separation of concerns
- Well-documented code
- Backward compatible
Conclusion
The foundation for group session support has been successfully implemented with:
- ✅ Database models (Session, SessionParticipant)
- ✅ Migration files
- ✅ Backward compatibility (session FK in Appointment)
- ✅ Comprehensive documentation
Next immediate steps:
- Run the migration:
python3 manage.py migrate appointments - Implement SessionService class
- Create Django admin interface
- Build forms and views
- Test the complete workflow
The implementation follows Django best practices and maintains compatibility with the existing appointment system while adding powerful group session capabilities.
Contact & Support
For questions or issues with this implementation:
- Review this document
- Check the inline code documentation
- Test in development environment first
- Create backup before running migrations in production
Implementation Status: Phase 1 Complete (Models & Migrations) Next Phase: Service Layer & Admin Interface Estimated Completion: 2-3 weeks for full implementation