# Generated by Django 5.2.3 on 2025-10-08 00:19 import django.core.validators import django.db.models.deletion from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('appointments', '0003_appointmentpriorityrule_schedulingmetrics_and_more'), ] operations = [ migrations.CreateModel( name='QueueConfiguration', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('use_dynamic_positioning', models.BooleanField(default=True, help_text='Enable AI-powered dynamic queue positioning')), ('priority_weight', models.DecimalField(decimal_places=2, default=0.5, help_text='Weight for priority score factor (0.0-1.0)', max_digits=3, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)])), ('wait_time_weight', models.DecimalField(decimal_places=2, default=0.3, help_text='Weight for wait time fairness factor (0.0-1.0)', max_digits=3, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)])), ('appointment_time_weight', models.DecimalField(decimal_places=2, default=0.2, help_text='Weight for appointment time proximity factor (0.0-1.0)', max_digits=3, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)])), ('enable_overflow_queue', models.BooleanField(default=False, help_text='Enable overflow queue when capacity is reached')), ('overflow_threshold', models.IntegerField(default=10, help_text='Queue size threshold to trigger overflow', validators=[django.core.validators.MinValueValidator(1)])), ('use_historical_data', models.BooleanField(default=True, help_text='Use historical data for wait time estimation')), ('default_service_time_minutes', models.IntegerField(default=20, help_text='Default service time in minutes', validators=[django.core.validators.MinValueValidator(5), django.core.validators.MaxValueValidator(480)])), ('historical_data_days', models.IntegerField(default=7, help_text='Number of days of historical data to use', validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(90)])), ('enable_websocket_updates', models.BooleanField(default=True, help_text='Enable WebSocket real-time updates')), ('update_interval_seconds', models.IntegerField(default=30, help_text='Update broadcast interval in seconds', validators=[django.core.validators.MinValueValidator(5), django.core.validators.MaxValueValidator(300)])), ('load_factor_normal_threshold', models.DecimalField(decimal_places=2, default=0.5, help_text='Utilization threshold for normal load (0.0-1.0)', max_digits=3, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)])), ('load_factor_moderate_threshold', models.DecimalField(decimal_places=2, default=0.75, help_text='Utilization threshold for moderate load (0.0-1.0)', max_digits=3, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)])), ('load_factor_high_threshold', models.DecimalField(decimal_places=2, default=0.9, help_text='Utilization threshold for high load (0.0-1.0)', max_digits=3, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(1)])), ('auto_reposition_enabled', models.BooleanField(default=True, help_text='Automatically reposition queue entries')), ('reposition_interval_minutes', models.IntegerField(default=15, help_text='Interval for auto-repositioning in minutes', validators=[django.core.validators.MinValueValidator(1), django.core.validators.MaxValueValidator(120)])), ('notify_on_position_change', models.BooleanField(default=True, help_text='Notify patients when queue position changes significantly')), ('position_change_threshold', models.IntegerField(default=3, help_text='Position change threshold to trigger notification', validators=[django.core.validators.MinValueValidator(1)])), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('queue', models.OneToOneField(help_text='Associated waiting queue', on_delete=django.db.models.deletion.CASCADE, related_name='configuration', to='appointments.waitingqueue')), ], options={ 'verbose_name': 'Queue Configuration', 'verbose_name_plural': 'Queue Configurations', 'db_table': 'appointments_queue_configuration', }, ), migrations.CreateModel( name='QueueMetrics', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('date', models.DateField(help_text='Metrics date')), ('hour', models.IntegerField(help_text='Hour of day (0-23)', validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(23)])), ('total_entries', models.IntegerField(default=0, help_text='Total queue entries during this hour')), ('completed_entries', models.IntegerField(default=0, help_text='Number of completed entries')), ('no_shows', models.IntegerField(default=0, help_text='Number of no-shows')), ('left_queue', models.IntegerField(default=0, help_text='Number of patients who left queue')), ('average_wait_time_minutes', models.DecimalField(decimal_places=2, default=0, help_text='Average wait time in minutes', max_digits=6)), ('max_wait_time_minutes', models.IntegerField(default=0, help_text='Maximum wait time in minutes')), ('min_wait_time_minutes', models.IntegerField(default=0, help_text='Minimum wait time in minutes')), ('average_service_time_minutes', models.DecimalField(decimal_places=2, default=0, help_text='Average service time in minutes', max_digits=6)), ('peak_queue_size', models.IntegerField(default=0, help_text='Peak queue size during this hour')), ('average_queue_size', models.DecimalField(decimal_places=2, default=0, help_text='Average queue size during this hour', max_digits=6)), ('min_queue_size', models.IntegerField(default=0, help_text='Minimum queue size during this hour')), ('throughput', models.IntegerField(default=0, help_text='Number of patients served per hour')), ('utilization_rate', models.DecimalField(decimal_places=2, default=0, help_text='Queue utilization rate percentage', max_digits=5, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])), ('no_show_rate', models.DecimalField(decimal_places=2, default=0, help_text='No-show rate percentage', max_digits=5, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])), ('abandonment_rate', models.DecimalField(decimal_places=2, default=0, help_text='Queue abandonment rate percentage', max_digits=5, validators=[django.core.validators.MinValueValidator(0), django.core.validators.MaxValueValidator(100)])), ('repositioning_events', models.IntegerField(default=0, help_text='Number of queue repositioning events')), ('average_position_changes', models.DecimalField(decimal_places=2, default=0, help_text='Average position changes per entry', max_digits=5)), ('average_load_factor', models.DecimalField(decimal_places=2, default=1.0, help_text='Average load factor during this hour', max_digits=3)), ('peak_load_factor', models.DecimalField(decimal_places=2, default=1.0, help_text='Peak load factor during this hour', max_digits=3)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('queue', models.ForeignKey(help_text='Associated waiting queue', on_delete=django.db.models.deletion.CASCADE, related_name='metrics', to='appointments.waitingqueue')), ], options={ 'verbose_name': 'Queue Metrics', 'verbose_name_plural': 'Queue Metrics', 'db_table': 'appointments_queue_metrics', 'ordering': ['-date', '-hour'], 'indexes': [models.Index(fields=['queue', 'date'], name='appointment_queue_i_7f290c_idx'), models.Index(fields=['date', 'hour'], name='appointment_date_d0647d_idx'), models.Index(fields=['queue', 'date', 'hour'], name='appointment_queue_i_c74231_idx'), models.Index(fields=['utilization_rate'], name='appointment_utiliza_b2a554_idx'), models.Index(fields=['no_show_rate'], name='appointment_no_show_1ecfe1_idx')], 'unique_together': {('queue', 'date', 'hour')}, }, ), ]