# Generated by Django 5.2.7 on 2025-10-19 15:50 import django.core.validators import django.db.models.deletion import django_ckeditor_5.fields import django_countries.fields import django_extensions.db.fields import recruitment.validators from django.conf import settings from django.db import migrations, models class Migration(migrations.Migration): initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='BreakTime', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('start_time', models.TimeField(verbose_name='Start Time')), ('end_time', models.TimeField(verbose_name='End Time')), ], ), migrations.CreateModel( name='FormStage', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('name', models.CharField(help_text='Name of the stage', max_length=200)), ('order', models.PositiveIntegerField(default=0, help_text='Order of the stage in the form')), ('is_predefined', models.BooleanField(default=False, help_text='Whether this is a default resume stage')), ], options={ 'verbose_name': 'Form Stage', 'verbose_name_plural': 'Form Stages', 'ordering': ['order'], }, ), migrations.CreateModel( name='HiringAgency', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('name', models.CharField(max_length=200, unique=True, verbose_name='Agency Name')), ('contact_person', models.CharField(blank=True, max_length=150, verbose_name='Contact Person')), ('email', models.EmailField(blank=True, max_length=254)), ('phone', models.CharField(blank=True, max_length=20)), ('website', models.URLField(blank=True)), ('notes', models.TextField(blank=True, help_text='Internal notes about the agency')), ('country', django_countries.fields.CountryField(blank=True, max_length=2, null=True)), ('address', models.TextField(blank=True, null=True)), ], options={ 'verbose_name': 'Hiring Agency', 'verbose_name_plural': 'Hiring Agencies', 'ordering': ['name'], }, ), migrations.CreateModel( name='Source', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('name', models.CharField(help_text='e.g., ATS, ERP ', max_length=100, unique=True, verbose_name='Source Name')), ('source_type', models.CharField(help_text='e.g., ATS, ERP ', max_length=100, verbose_name='Source Type')), ('description', models.TextField(blank=True, help_text='A description of the source', verbose_name='Description')), ('ip_address', models.GenericIPAddressField(blank=True, help_text='The IP address of the source', null=True, verbose_name='IP Address')), ('created_at', models.DateTimeField(auto_now_add=True)), ('api_key', models.CharField(blank=True, help_text='API key for authentication (will be encrypted)', max_length=255, null=True, verbose_name='API Key')), ('api_secret', models.CharField(blank=True, help_text='API secret for authentication (will be encrypted)', max_length=255, null=True, verbose_name='API Secret')), ('trusted_ips', models.TextField(blank=True, help_text='Comma-separated list of trusted IP addresses', null=True, verbose_name='Trusted IP Addresses')), ('is_active', models.BooleanField(default=True, help_text='Whether this source is active for integration', verbose_name='Active')), ('integration_version', models.CharField(blank=True, help_text='Version of the integration protocol', max_length=50, verbose_name='Integration Version')), ('last_sync_at', models.DateTimeField(blank=True, help_text='Timestamp of the last successful synchronization', null=True, verbose_name='Last Sync At')), ('sync_status', models.CharField(blank=True, choices=[('IDLE', 'Idle'), ('SYNCING', 'Syncing'), ('ERROR', 'Error'), ('DISABLED', 'Disabled')], default='IDLE', max_length=20, verbose_name='Sync Status')), ], options={ 'verbose_name': 'Source', 'verbose_name_plural': 'Sources', 'ordering': ['name'], }, ), migrations.CreateModel( name='ZoomMeeting', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('topic', models.CharField(max_length=255, verbose_name='Topic')), ('meeting_id', models.CharField(db_index=True, max_length=20, unique=True, verbose_name='Meeting ID')), ('start_time', models.DateTimeField(db_index=True, verbose_name='Start Time')), ('duration', models.PositiveIntegerField(verbose_name='Duration')), ('timezone', models.CharField(max_length=50, verbose_name='Timezone')), ('join_url', models.URLField(verbose_name='Join URL')), ('participant_video', models.BooleanField(default=True, verbose_name='Participant Video')), ('password', models.CharField(blank=True, max_length=20, null=True, verbose_name='Password')), ('join_before_host', models.BooleanField(default=False, verbose_name='Join Before Host')), ('mute_upon_entry', models.BooleanField(default=False, verbose_name='Mute Upon Entry')), ('waiting_room', models.BooleanField(default=False, verbose_name='Waiting Room')), ('zoom_gateway_response', models.JSONField(blank=True, null=True, verbose_name='Zoom Gateway Response')), ('status', models.CharField(blank=True, db_index=True, default='waiting', max_length=20, null=True, verbose_name='Status')), ], options={ 'abstract': False, }, ), migrations.CreateModel( name='FormField', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('label', models.CharField(help_text='Label for the field', max_length=200)), ('field_type', models.CharField(choices=[('text', 'Text Input'), ('email', 'Email'), ('phone', 'Phone'), ('textarea', 'Text Area'), ('file', 'File Upload'), ('date', 'Date Picker'), ('select', 'Dropdown'), ('radio', 'Radio Buttons'), ('checkbox', 'Checkboxes')], help_text='Type of the field', max_length=20)), ('placeholder', models.CharField(blank=True, help_text='Placeholder text', max_length=200)), ('required', models.BooleanField(default=False, help_text='Whether the field is required')), ('order', models.PositiveIntegerField(default=0, help_text='Order of the field in the stage')), ('is_predefined', models.BooleanField(default=False, help_text='Whether this is a default field')), ('options', models.JSONField(blank=True, default=list, help_text='Options for selection fields (stored as JSON array)')), ('file_types', models.CharField(blank=True, help_text="Allowed file types (comma-separated, e.g., '.pdf,.doc,.docx')", max_length=200)), ('max_file_size', models.PositiveIntegerField(default=5, help_text='Maximum file size in MB (default: 5MB)')), ('multiple_files', models.BooleanField(default=False, help_text='Allow multiple files to be uploaded')), ('max_files', models.PositiveIntegerField(default=1, help_text='Maximum number of files allowed (when multiple_files is True)')), ('stage', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='fields', to='recruitment.formstage')), ], options={ 'verbose_name': 'Form Field', 'verbose_name_plural': 'Form Fields', 'ordering': ['order'], }, ), migrations.CreateModel( name='FormTemplate', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('name', models.CharField(help_text='Name of the form template', max_length=200)), ('description', models.TextField(blank=True, help_text='Description of the form template')), ('is_active', models.BooleanField(default=False, help_text='Whether this template is active')), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='form_templates', to=settings.AUTH_USER_MODEL)), ], options={ 'verbose_name': 'Form Template', 'verbose_name_plural': 'Form Templates', 'ordering': ['-created_at'], }, ), migrations.CreateModel( name='FormSubmission', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('submitted_at', models.DateTimeField(auto_now_add=True, db_index=True)), ('applicant_name', models.CharField(blank=True, help_text='Name of the applicant', max_length=200)), ('applicant_email', models.EmailField(blank=True, db_index=True, help_text='Email of the applicant', max_length=254)), ('submitted_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='form_submissions', to=settings.AUTH_USER_MODEL)), ('template', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='submissions', to='recruitment.formtemplate')), ], options={ 'verbose_name': 'Form Submission', 'verbose_name_plural': 'Form Submissions', 'ordering': ['-submitted_at'], }, ), migrations.AddField( model_name='formstage', name='template', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='stages', to='recruitment.formtemplate'), ), migrations.CreateModel( name='Candidate', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('first_name', models.CharField(max_length=255, verbose_name='First Name')), ('last_name', models.CharField(max_length=255, verbose_name='Last Name')), ('email', models.EmailField(db_index=True, max_length=254, verbose_name='Email')), ('phone', models.CharField(max_length=20, verbose_name='Phone')), ('address', models.TextField(max_length=200, verbose_name='Address')), ('resume', models.FileField(upload_to='resumes/', verbose_name='Resume')), ('is_resume_parsed', models.BooleanField(default=False, verbose_name='Resume Parsed')), ('is_potential_candidate', models.BooleanField(default=False, verbose_name='Potential Candidate')), ('parsed_summary', models.TextField(blank=True, verbose_name='Parsed Summary')), ('applied', models.BooleanField(default=False, verbose_name='Applied')), ('stage', models.CharField(choices=[('Applied', 'Applied'), ('Exam', 'Exam'), ('Interview', 'Interview'), ('Offer', 'Offer')], db_index=True, default='Applied', max_length=100, verbose_name='Stage')), ('applicant_status', models.CharField(blank=True, choices=[('Applicant', 'Applicant'), ('Candidate', 'Candidate')], default='Applicant', max_length=100, null=True, verbose_name='Applicant Status')), ('exam_date', models.DateTimeField(blank=True, null=True, verbose_name='Exam Date')), ('exam_status', models.CharField(blank=True, choices=[('Passed', 'Passed'), ('Failed', 'Failed')], max_length=100, null=True, verbose_name='Exam Status')), ('interview_date', models.DateTimeField(blank=True, null=True, verbose_name='Interview Date')), ('interview_status', models.CharField(blank=True, choices=[('Passed', 'Passed'), ('Failed', 'Failed')], max_length=100, null=True, verbose_name='Interview Status')), ('offer_date', models.DateField(blank=True, null=True, verbose_name='Offer Date')), ('offer_status', models.CharField(blank=True, choices=[('Accepted', 'Accepted'), ('Rejected', 'Rejected')], max_length=100, null=True, verbose_name='Offer Status')), ('join_date', models.DateField(blank=True, null=True, verbose_name='Join Date')), ('ai_analysis_data', models.JSONField(default=dict, help_text='Full JSON output from the resume scoring model.', verbose_name='AI Analysis Data')), ('submitted_by_agency', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='submitted_candidates', to='recruitment.hiringagency', verbose_name='Submitted by Agency')), ], options={ 'verbose_name': 'Candidate', 'verbose_name_plural': 'Candidates', }, ), migrations.CreateModel( name='JobPosting', fields=[ ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('title', models.CharField(max_length=200)), ('department', models.CharField(blank=True, max_length=100)), ('job_type', models.CharField(choices=[('FULL_TIME', 'Full-time'), ('PART_TIME', 'Part-time'), ('CONTRACT', 'Contract'), ('INTERNSHIP', 'Internship'), ('FACULTY', 'Faculty'), ('TEMPORARY', 'Temporary')], default='FULL_TIME', max_length=20)), ('workplace_type', models.CharField(choices=[('ON_SITE', 'On-site'), ('REMOTE', 'Remote'), ('HYBRID', 'Hybrid')], default='ON_SITE', max_length=20)), ('location_city', models.CharField(blank=True, max_length=100)), ('location_state', models.CharField(blank=True, max_length=100)), ('location_country', models.CharField(default='Saudia Arabia', max_length=100)), ('description', django_ckeditor_5.fields.CKEditor5Field(verbose_name='Description')), ('qualifications', django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True)), ('salary_range', models.CharField(blank=True, help_text='e.g., $60,000 - $80,000', max_length=200)), ('benefits', django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True)), ('application_url', models.URLField(blank=True, help_text='URL where candidates apply', null=True, validators=[django.core.validators.URLValidator()])), ('application_start_date', models.DateField(blank=True, null=True)), ('application_deadline', models.DateField(blank=True, db_index=True, null=True)), ('application_instructions', django_ckeditor_5.fields.CKEditor5Field(blank=True, null=True)), ('internal_job_id', models.CharField(editable=False, max_length=50, primary_key=True, serialize=False)), ('created_by', models.CharField(blank=True, help_text='Name of person who created this job', max_length=100)), ('status', models.CharField(choices=[('DRAFT', 'Draft'), ('ACTIVE', 'Active'), ('CLOSED', 'Closed'), ('CANCELLED', 'Cancelled'), ('ARCHIVED', 'Archived')], db_index=True, default='DRAFT', max_length=20)), ('hash_tags', models.CharField(blank=True, help_text='Comma-separated hashtags for linkedin post like #hiring,#jobopening', max_length=200, validators=[recruitment.validators.validate_hash_tags])), ('linkedin_post_id', models.CharField(blank=True, help_text='LinkedIn post ID after posting', max_length=200)), ('linkedin_post_url', models.URLField(blank=True, help_text='Direct URL to LinkedIn post')), ('posted_to_linkedin', models.BooleanField(default=False)), ('linkedin_post_status', models.CharField(blank=True, help_text='Status of LinkedIn posting', max_length=50)), ('linkedin_posted_at', models.DateTimeField(blank=True, null=True)), ('published_at', models.DateTimeField(blank=True, db_index=True, null=True)), ('position_number', models.CharField(blank=True, help_text='University position number', max_length=50)), ('reporting_to', models.CharField(blank=True, help_text='Who this position reports to', max_length=100)), ('joining_date', models.DateField(blank=True, help_text='Desired start date', null=True)), ('open_positions', models.PositiveIntegerField(default=1, help_text='Number of open positions for this job')), ('max_applications', models.PositiveIntegerField(blank=True, default=1000, help_text='Maximum number of applications allowed', null=True)), ('cancel_reason', models.TextField(blank=True, help_text='Reason for canceling the job posting', verbose_name='Cancel Reason')), ('cancelled_by', models.CharField(blank=True, help_text='Name of person who cancelled this job', max_length=100, verbose_name='Cancelled By')), ('cancelled_at', models.DateTimeField(blank=True, null=True)), ('hiring_agency', models.ManyToManyField(blank=True, help_text='External agency responsible for sourcing candidates for this role', related_name='jobs', to='recruitment.hiringagency', verbose_name='Hiring Agency')), ('source', models.ForeignKey(blank=True, help_text='The system or channel from which this job posting originated or was first published.', null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='job_postings', to='recruitment.source')), ], options={ 'verbose_name': 'Job Posting', 'verbose_name_plural': 'Job Postings', 'ordering': ['-created_at'], }, ), migrations.CreateModel( name='InterviewSchedule', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('start_date', models.DateField(db_index=True, verbose_name='Start Date')), ('end_date', models.DateField(db_index=True, verbose_name='End Date')), ('working_days', models.JSONField(verbose_name='Working Days')), ('start_time', models.TimeField(verbose_name='Start Time')), ('end_time', models.TimeField(verbose_name='End Time')), ('break_start_time', models.TimeField(blank=True, null=True, verbose_name='Break Start Time')), ('break_end_time', models.TimeField(blank=True, null=True, verbose_name='Break End Time')), ('interview_duration', models.PositiveIntegerField(verbose_name='Interview Duration (minutes)')), ('buffer_time', models.PositiveIntegerField(default=0, verbose_name='Buffer Time (minutes)')), ('candidates', models.ManyToManyField(blank=True, null=True, related_name='interview_schedules', to='recruitment.candidate')), ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to=settings.AUTH_USER_MODEL)), ('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='interview_schedules', to='recruitment.jobposting')), ], ), migrations.AddField( model_name='formtemplate', name='job', field=models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='form_template', to='recruitment.jobposting'), ), migrations.AddField( model_name='candidate', name='job', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='candidates', to='recruitment.jobposting', verbose_name='Job'), ), migrations.CreateModel( name='JobPostingImage', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('post_image', models.ImageField(upload_to='post/', validators=[recruitment.validators.validate_image_size])), ('job', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='post_images', to='recruitment.jobposting')), ], ), migrations.CreateModel( name='Profile', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('profile_image', models.ImageField(blank=True, null=True, upload_to='profile_pic/')), ('user', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='profile', to=settings.AUTH_USER_MODEL)), ], ), migrations.CreateModel( name='SharedFormTemplate', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('is_public', models.BooleanField(default=False, help_text='Whether this template is publicly available')), ('shared_with', models.ManyToManyField(blank=True, related_name='shared_templates', to=settings.AUTH_USER_MODEL)), ('template', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, to='recruitment.formtemplate')), ], options={ 'verbose_name': 'Shared Form Template', 'verbose_name_plural': 'Shared Form Templates', }, ), migrations.CreateModel( name='IntegrationLog', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('action', models.CharField(choices=[('REQUEST', 'Request'), ('RESPONSE', 'Response'), ('ERROR', 'Error'), ('SYNC', 'Sync'), ('CREATE_JOB', 'Create Job'), ('UPDATE_JOB', 'Update Job')], max_length=20, verbose_name='Action')), ('endpoint', models.CharField(blank=True, max_length=255, verbose_name='Endpoint')), ('method', models.CharField(blank=True, max_length=10, verbose_name='HTTP Method')), ('request_data', models.JSONField(blank=True, null=True, verbose_name='Request Data')), ('response_data', models.JSONField(blank=True, null=True, verbose_name='Response Data')), ('status_code', models.CharField(blank=True, max_length=10, verbose_name='Status Code')), ('error_message', models.TextField(blank=True, verbose_name='Error Message')), ('ip_address', models.GenericIPAddressField(verbose_name='IP Address')), ('user_agent', models.CharField(blank=True, max_length=255, verbose_name='User Agent')), ('processing_time', models.FloatField(blank=True, null=True, verbose_name='Processing Time (seconds)')), ('source', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='integration_logs', to='recruitment.source', verbose_name='Source')), ], options={ 'verbose_name': 'Integration Log', 'verbose_name_plural': 'Integration Logs', 'ordering': ['-created_at'], }, ), migrations.CreateModel( name='TrainingMaterial', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('title', models.CharField(max_length=255, verbose_name='Title')), ('content', django_ckeditor_5.fields.CKEditor5Field(blank=True, verbose_name='Content')), ('video_link', models.URLField(blank=True, verbose_name='Video Link')), ('file', models.FileField(blank=True, upload_to='training_materials/', verbose_name='File')), ('created_by', models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='Created by')), ], options={ 'verbose_name': 'Training Material', 'verbose_name_plural': 'Training Materials', }, ), migrations.CreateModel( name='ScheduledInterview', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('interview_date', models.DateField(db_index=True, verbose_name='Interview Date')), ('interview_time', models.TimeField(verbose_name='Interview Time')), ('status', models.CharField(choices=[('scheduled', 'Scheduled'), ('confirmed', 'Confirmed'), ('cancelled', 'Cancelled'), ('completed', 'Completed')], db_index=True, default='scheduled', max_length=20)), ('created_at', models.DateTimeField(auto_now_add=True)), ('updated_at', models.DateTimeField(auto_now=True)), ('candidate', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='scheduled_interviews', to='recruitment.candidate')), ('job', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='scheduled_interviews', to='recruitment.jobposting')), ('schedule', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.CASCADE, related_name='interviews', to='recruitment.interviewschedule')), ('zoom_meeting', models.OneToOneField(on_delete=django.db.models.deletion.CASCADE, related_name='interview', to='recruitment.zoommeeting')), ], ), migrations.CreateModel( name='MeetingComment', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('content', django_ckeditor_5.fields.CKEditor5Field(verbose_name='Content')), ('author', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='meeting_comments', to=settings.AUTH_USER_MODEL, verbose_name='Author')), ('meeting', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='comments', to='recruitment.zoommeeting', verbose_name='Meeting')), ], options={ 'verbose_name': 'Meeting Comment', 'verbose_name_plural': 'Meeting Comments', 'ordering': ['-created_at'], }, ), migrations.CreateModel( name='FieldResponse', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created at')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated at')), ('slug', django_extensions.db.fields.RandomCharField(blank=True, editable=False, length=8, unique=True, verbose_name='Slug')), ('value', models.JSONField(blank=True, help_text='Response value (stored as JSON)', null=True)), ('uploaded_file', models.FileField(blank=True, null=True, upload_to='form_uploads/')), ('field', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='recruitment.formfield')), ('submission', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='responses', to='recruitment.formsubmission')), ], options={ 'verbose_name': 'Field Response', 'verbose_name_plural': 'Field Responses', 'indexes': [models.Index(fields=['submission'], name='recruitment_submiss_474130_idx'), models.Index(fields=['field'], name='recruitment_field_i_097e5b_idx')], }, ), migrations.AddIndex( model_name='formsubmission', index=models.Index(fields=['submitted_at'], name='recruitment_submitt_7946c8_idx'), ), migrations.AddIndex( model_name='interviewschedule', index=models.Index(fields=['start_date'], name='recruitment_start_d_15d55e_idx'), ), migrations.AddIndex( model_name='interviewschedule', index=models.Index(fields=['end_date'], name='recruitment_end_dat_aeb00e_idx'), ), migrations.AddIndex( model_name='interviewschedule', index=models.Index(fields=['created_by'], name='recruitment_created_d0bdcc_idx'), ), migrations.AddIndex( model_name='formtemplate', index=models.Index(fields=['created_at'], name='recruitment_created_c21775_idx'), ), migrations.AddIndex( model_name='formtemplate', index=models.Index(fields=['is_active'], name='recruitment_is_acti_ae5efb_idx'), ), migrations.AddIndex( model_name='candidate', index=models.Index(fields=['stage'], name='recruitment_stage_f1c6eb_idx'), ), migrations.AddIndex( model_name='candidate', index=models.Index(fields=['created_at'], name='recruitment_created_73590f_idx'), ), migrations.AddIndex( model_name='jobposting', index=models.Index(fields=['status', 'created_at', 'title'], name='recruitment_status_8b77aa_idx'), ), migrations.AddIndex( model_name='jobposting', index=models.Index(fields=['slug'], name='recruitment_slug_004045_idx'), ), migrations.AddIndex( model_name='scheduledinterview', index=models.Index(fields=['job', 'status'], name='recruitment_job_id_f09e22_idx'), ), migrations.AddIndex( model_name='scheduledinterview', index=models.Index(fields=['interview_date', 'interview_time'], name='recruitment_intervi_7f5877_idx'), ), migrations.AddIndex( model_name='scheduledinterview', index=models.Index(fields=['candidate', 'job'], name='recruitment_candida_43d5b0_idx'), ), ]