give every topic a starter question so the app can be clicked through

تا امروز کوریکولوم بود و سوال نبود: هر ۱۴ سوالِ دیتابیسِ لوکال روی ردیف‌های
[DEMO] نشسته بودند و در export کنار گذاشته می‌شدند. یعنی سینیور می‌توانست در
مرورگرِ محتوا پایین برود ولی هیچ درسی آزمونی نداشت — که از «محتوا نداریم»
بدتر است، چون شبیهِ خرابی به‌نظر می‌رسد.

حالا هر ۱۶۸ مبحث دستِ‌کم یک سوالِ چهارگزینه‌ای دارد: ۲۳ برای پایه نهم، ۴۶ ششم،
۴۶ هفتم، ۵۳ سوم. هر سوال به درسی وصل است که عنوانش همان موضوع را می‌گوید، نه
به یک درسِ دلخواه.

جای گزینهٔ درست با seed ثابت جابه‌جا شده (۴۴/۴۹/۳۵/۴۰ در چهار موقعیت). اگر
جوابِ درست همیشه گزینهٔ اول باشد، آزمون دیگر چیزی را نمی‌سنجد و آمارِ
«درصدِ غلط» هم بی‌معنا می‌شود. یک تست همین را نگه می‌دارد.

این‌ها نمونه‌اند نه محتوای نهایی: یک سوال برای هر مبحث فقط نشان می‌دهد مسیرِ
درس → آزمون → XP کار می‌کند. سوال‌های واقعیِ هر درس کارِ
`generate_questions_from_chunks` است که به اعتبارِ AI نیاز دارد، و از پنلِ
ادمین هم می‌شود دستی اضافه کرد.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-14 20:42:14 +03:30
parent 9c3db68cbb
commit ca983d237f
2 changed files with 2894 additions and 1 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -193,3 +193,39 @@ class SeedFilesInRepoTests(TestCase):
call_command('seed_content')
question_io.resolve_paths(rows) # مسیرِ حل‌نشده خطا می‌دهد
def test_committed_questions_are_well_formed(self):
rows = json.loads(
seed_content.QUESTIONS_FILE.read_text(encoding='utf-8'))['questions']
if not rows:
self.skipTest('هنوز سوالِ واقعی‌ای در ریپو نیست.')
for index, row in enumerate(rows):
where = f'سوال {index + 1}'
self.assertTrue(row['prompt'].strip(), where)
self.assertEqual(len(row['choices']), 4, where)
self.assertEqual(len(set(row['choices'])), 4, where)
self.assertIn(row['correct'], range(4), where)
def test_every_topic_has_at_least_one_question(self):
"""
هدفِ این مجموعه «نمونه در چند جا» نیست: هر مبحث باید دستِ‌کم یک سوال
داشته باشد، وگرنه ادمین در مرورگرِ محتوا به ستون‌های خالی می‌رسد و
نمی‌داند محتوا نیست یا چیزی خراب است.
"""
call_command('seed_content')
empty = Node.objects.filter(lessons__questions__isnull=True).distinct()
empty = [node for node in empty if not Question.objects.filter(
lesson__node=node).exists()]
self.assertEqual(empty, [], f'{len(empty)} مبحث بدونِ سوال ماند.')
def test_the_right_answer_is_not_always_the_first_choice(self):
"""جوابِ درست اگر همیشه گزینهٔ اول باشد، آزمون سنجشِ چیزی نیست."""
rows = json.loads(
seed_content.QUESTIONS_FILE.read_text(encoding='utf-8'))['questions']
if len(rows) < 10:
self.skipTest('برای این بررسی سوالِ کافی نیست.')
positions = {row['correct'] for row in rows}
self.assertGreater(len(positions), 2)