# Generated by Django 4.2.30 on 2026-09-15 12:58 from django.conf import settings from django.db import migrations, models import django.db.models.deletion import django.utils.timezone import uuid class Migration(migrations.Migration): initial = True dependencies = [ ('profiles', '0001_initial'), migrations.swappable_dependency(settings.AUTH_USER_MODEL), ] operations = [ migrations.CreateModel( name='Course', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=255, verbose_name='Course Title')), ('slug', models.SlugField(allow_unicode=True, blank=True, max_length=280, null=True, unique=True, verbose_name='Slug / URL Identifier')), ('category', models.CharField(choices=[('razavi_teachings', 'Razavi Teachings & Lifestyle'), ('cultural_diplomacy', 'Cultural Diplomacy & Interfaith'), ('center_management', 'Center & Mosque Management'), ('international_media', 'International Media & Content'), ('specialized_languages', 'Specialized Languages & Translation'), ('general', 'General Religious Studies')], default='razavi_teachings', max_length=50, verbose_name='Category')), ('language', models.CharField(choices=[('fa', 'Persian'), ('ar', 'Arabic'), ('en', 'English'), ('ur', 'Urdu'), ('fr', 'French')], default='en', max_length=10, verbose_name='Language')), ('level', models.CharField(choices=[('introductory', 'Introductory'), ('intermediate', 'Intermediate'), ('advanced', 'Advanced')], default='introductory', max_length=20, verbose_name='Difficulty Level')), ('cover_image', models.ImageField(blank=True, null=True, upload_to='lms/covers/%Y/%m/', verbose_name='Cover Image')), ('instructor_name', models.CharField(max_length=255, verbose_name='Instructor Name')), ('instructor_title', models.CharField(blank=True, max_length=255, null=True, verbose_name='Instructor Title / Specialty')), ('instructor_avatar', models.ImageField(blank=True, null=True, upload_to='lms/instructors/%Y/%m/', verbose_name='Instructor Avatar')), ('organization_name', models.CharField(blank=True, max_length=255, null=True, verbose_name='Organization / Academy Name')), ('description', models.TextField(verbose_name='Course Description & Syllabus Summary')), ('duration_hours', models.FloatField(default=1.0, verbose_name='Duration (Hours)')), ('rating', models.FloatField(default=5.0, verbose_name='Average Rating')), ('reviews_count', models.PositiveIntegerField(default=0, verbose_name='Reviews Count')), ('is_published', models.BooleanField(default=True, verbose_name='Is Published')), ('is_featured', models.BooleanField(default=False, verbose_name='Is Featured')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), ('created_by', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='created_courses', to=settings.AUTH_USER_MODEL, verbose_name='Created By')), ('institution', models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='courses', to='profiles.institution', verbose_name='Partner Institution / Center')), ], options={ 'verbose_name': 'Course', 'verbose_name_plural': 'Courses', 'ordering': ('-is_featured', '-created_at'), }, ), migrations.CreateModel( name='CourseModule', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=255, verbose_name='Module Title')), ('description', models.TextField(blank=True, null=True, verbose_name='Module Description')), ('order', models.IntegerField(default=0, verbose_name='Display Order')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='modules', to='lms.course', verbose_name='Course')), ], options={ 'verbose_name': 'Course Module', 'verbose_name_plural': 'Course Modules', 'ordering': ('order', 'id'), }, ), migrations.CreateModel( name='Lesson', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('title', models.CharField(max_length=255, verbose_name='Lesson Title')), ('slug', models.SlugField(allow_unicode=True, blank=True, max_length=280, null=True, verbose_name='Slug')), ('lesson_type', models.CharField(choices=[('video', 'Video Lesson'), ('reading', 'Reading & Text'), ('quiz', 'Interactive Quiz'), ('assignment', 'Practical Assignment')], default='video', max_length=20, verbose_name='Lesson Type')), ('duration_minutes', models.PositiveIntegerField(default=15, verbose_name='Duration (Minutes)')), ('video_url', models.URLField(blank=True, max_length=500, null=True, verbose_name='Video URL (YouTube, Vimeo, HLS, MP4)')), ('content', models.TextField(blank=True, null=True, verbose_name='Lesson Content / Notes (Markdown)')), ('slides_attachment', models.FileField(blank=True, null=True, upload_to='lms/slides/%Y/%m/', verbose_name='Slides / PDF Handout')), ('order', models.IntegerField(default=0, verbose_name='Display Order')), ('is_preview', models.BooleanField(default=False, verbose_name='Is Free Preview (Public)')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), ('module', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lessons', to='lms.coursemodule', verbose_name='Module')), ], options={ 'verbose_name': 'Lesson', 'verbose_name_plural': 'Lessons', 'ordering': ('order', 'id'), }, ), migrations.CreateModel( name='QuizQuestion', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('question_text', models.TextField(verbose_name='Question Text')), ('options', models.JSONField(default=list, help_text='List of multiple-choice strings: ["Option A", "Option B", "Option C", "Option D"]', verbose_name='Options Array')), ('correct_option_index', models.PositiveSmallIntegerField(default=0, verbose_name='Correct Option Index (0-indexed)')), ('explanation', models.TextField(blank=True, null=True, verbose_name='Explanation / Reference for Correct Answer')), ('order', models.IntegerField(default=0, verbose_name='Display Order')), ('lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='quiz_questions', to='lms.lesson', verbose_name='Lesson')), ], options={ 'verbose_name': 'Quiz Question', 'verbose_name_plural': 'Quiz Questions', 'ordering': ('order', 'id'), }, ), migrations.CreateModel( name='LessonProgress', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('is_completed', models.BooleanField(default=False, verbose_name='Is Completed')), ('completed_at', models.DateTimeField(blank=True, null=True, verbose_name='Completed At')), ('quiz_score', models.FloatField(blank=True, null=True, verbose_name='Quiz Score (Percentage)')), ('lesson', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='user_progresses', to='lms.lesson', verbose_name='Lesson')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='lesson_progresses', to=settings.AUTH_USER_MODEL, verbose_name='User')), ], options={ 'verbose_name': 'Lesson Progress', 'verbose_name_plural': 'Lesson Progresses', 'unique_together': {('user', 'lesson')}, }, ), migrations.CreateModel( name='DigitalCertificate', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('certificate_code', models.CharField(help_text='e.g. CERT-RAZAVI-2026-AB12CD', max_length=100, unique=True, verbose_name='Verification Code')), ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='Unique UUID')), ('issue_date', models.DateField(default=django.utils.timezone.now, verbose_name='Issue Date')), ('final_score', models.FloatField(default=100.0, verbose_name='Final Score (%)')), ('certificate_file', models.FileField(blank=True, null=True, upload_to='lms/certificates/%Y/%m/', verbose_name='Certificate PDF Document')), ('is_revoked', models.BooleanField(default=False, verbose_name='Is Revoked')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='certificates', to='lms.course', verbose_name='Course')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='certificates', to=settings.AUTH_USER_MODEL, verbose_name='Student / User')), ], options={ 'verbose_name': 'Digital Certificate', 'verbose_name_plural': 'Digital Certificates', 'ordering': ('-created_at',), 'unique_together': {('user', 'course')}, }, ), migrations.CreateModel( name='CourseEnrollment', fields=[ ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('enrolled_at', models.DateTimeField(auto_now_add=True, verbose_name='Enrolled At')), ('completed_at', models.DateTimeField(blank=True, null=True, verbose_name='Completed At')), ('progress_percentage', models.PositiveSmallIntegerField(default=0, verbose_name='Progress Percentage (0-100)')), ('course', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='enrollments', to='lms.course', verbose_name='Course')), ('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='course_enrollments', to=settings.AUTH_USER_MODEL, verbose_name='User')), ], options={ 'verbose_name': 'Course Enrollment', 'verbose_name_plural': 'Course Enrollments', 'ordering': ('-enrolled_at',), 'unique_together': {('user', 'course')}, }, ), ]