Subjects per grade (math, calculus, geometry, stats, discrete), 5 new textbooks, 202 new islands, long islands split, hand-written figures and lesson texts for the new books

- content.Subject + Unit.subject, /api/home?subject=, tutor grounded in the chosen book
- 5 new books ingested; ~1150 hand-written questions, islands named by hand
- node_split: islands over 7 lessons split into parts of <=6 (lesson ids and progress kept)
- Lesson.figures hand-authored and visually checked for 653 lessons of the new books;
  gen_lesson_figures got --subject and survives network errors
- seed files re-exported

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 05:35:18 +03:30
parent 3d51b3b83a
commit 8cb1ecb85e
32 changed files with 81218 additions and 4486 deletions

View File

@@ -406,10 +406,14 @@ class AskAIView(APIView):
# فقط conversationId می‌فرستد و دیگر lessonId/gradeId نمی‌آید.
grade_id = v.get('gradeId') or conversation.grade_id
lesson_id = v.get('lessonId') or conversation.lesson_id
subject = (v.get('subject') or conversation.subject or '').strip()
# ⚠️ درسِ تازه‌ی همین درخواست از کتابِ ذخیره‌شده‌ی مکالمه جلو می‌افتد: از وقتی یک پایه چند
# کتاب دارد، مکالمه‌ای که با درسِ هندسه شروع شده می‌تواند با درسِ حسابان ادامه پیدا کند و
# `conversation.subject`/`lesson_number`ِ قدیمی جواب را از کتابِ غلط می‌گرفت.
explicit_lesson = bool(v.get('lessonId'))
subject = (v.get('subject') or ('' if explicit_lesson else conversation.subject) or '').strip()
grade_title = (v.get('grade') or '').strip()
lesson_number = v.get('lessonNumber')
if lesson_number is None:
if lesson_number is None and not explicit_lesson:
lesson_number = conversation.lesson_number
# اگر اپ فقط lessonId (یا فقط conversationId) داده — حالتِ طبیعی، چون
@@ -436,6 +440,14 @@ class AskAIView(APIView):
conversation.lesson_number = lesson_number
conversation.save(update_fields=['subject', 'lesson_number'])
# کتاب صریح آمده (فرانت کتابِ انتخابیِ دانش‌آموز را می‌فرستد) ولی درس و عنوانِ پایه نه:
# عنوانِ پایه از پایه‌ی خودِ کاربر درمی‌آید، وگرنه resolve_target هیچ collectionی نمی‌سازد
# و جواب بی‌صدا عمومی می‌شد.
if subject and not grade_title:
from rag.services.config import resolve_grade_title
grade_title = resolve_grade_title(grade_id or getattr(user, 'grade_id', None)) or ''
# نه درسی آمده نه subject — حالتِ عادیِ صفحه‌ی «از پی بپرس» که از نوارِ
# پایین باز می‌شود. پایه‌ی ذخیره‌شده‌ی خودِ کاربر کتاب را معلوم می‌کند؛
# بدونِ این، جواب‌های آن صفحه هیچ‌وقت به کتاب مستند نمی‌شدند.