import uuid from django.db import models class LessonChunk(models.Model): """ یک تکه‌ی درسیِ خلاصه‌شده که هم در همین جدول (منبعِ حقیقت) و هم به‌صورتِ یک نقطه در Qdrant (فقط index، قابلِ بازسازی) ذخیره می‌شه. برداشتِ پاک‌سازی‌شده از subjects.LessonChunk مخزنِ Rag_backend، با این تفاوت‌ها طبق معماریِ این پروژه: - هیچ FK بین‌اپی نداره؛ lesson_id فقط یک ارجاعِ سبک به content.Lesson است (دقیقاً مثل Conversation.lesson_id در ai_tutor). - subject/grade به‌صورتِ رشته/عدد نگه‌داری می‌شن چون مدلِ content ما مدلِ Subject نداره و نامِ collectionِ تیمِ دیگه بر پایه‌ی همین رشته‌هاست. - embedding_vector هم ذخیره می‌شه تا collectionِ Qdrant بدونِ فراخوانیِ دوباره‌ی embedding قابلِ بازسازی باشه. """ lesson_id = models.IntegerField(db_index=True) # ارجاع سبک به content.Lesson grade_id = models.IntegerField(null=True, blank=True) # ارجاع سبک به content.Grade subject = models.CharField(max_length=100) lesson_number = models.IntegerField() chapter = models.IntegerField(null=True, blank=True) # عنوانِ کاملِ فصل، دقیقاً همون رشته‌ای که در payloadِ تیمِ دیگه هست # («فصل ۲: کسر»). retrieval برای ریاضی روی همین مقدار فیلتر می‌کنه، پس # بدونِ این هر چیزی که ingest کنیم در جستجو پیدا نمی‌شه. chapter_title = models.CharField(max_length=255, blank=True) grade_title = models.CharField(max_length=100, blank=True) order = models.PositiveIntegerField() title = models.CharField(max_length=255) original_text = models.TextField() summary = models.TextField() embedding_vector = models.JSONField(null=True, blank=True) # --- ساختارِ استخراج‌شده از کتاب (همون قراردادِ ریاضیِ تیمِ دیگه) ------- # vision یک‌بار و با هزینه این‌ها رو درمی‌آره؛ اگه فقط متنِ صاف‌شده رو # نگه داریم، برای هر بازسازی باید دوباره همون هزینه رو بدیم. ضمناً # problem/solution ورودیِ مستقیمِ ساختِ سؤال‌های مسیرِ درس‌اند. problem_type = models.CharField(max_length=255, blank=True) keywords = models.JSONField(default=list, blank=True) general_solution = models.TextField(blank=True) problem = models.TextField(blank=True) solution = models.TextField(blank=True) collection = models.CharField(max_length=200, db_index=True) qdrant_point_id = models.UUIDField(default=uuid.uuid4, editable=False) created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['lesson_id', 'order'] constraints = [ models.UniqueConstraint( fields=['collection', 'qdrant_point_id'], name='uniq_lesson_chunk_qdrant_point', ), ] indexes = [ models.Index(fields=['subject', 'lesson_number']), ] def __str__(self): return f"chunk-lesson{self.lesson_id}-{self.order} ({self.subject})" class LessonChunkImage(models.Model): """تصویرِ پیوست به یک chunk (برای محتوای چندوجهیِ آینده).""" chunk = models.ForeignKey(LessonChunk, on_delete=models.CASCADE, related_name='images') img_url = models.TextField() description = models.TextField(blank=True) created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"image-chunk{self.chunk_id}"