- CLAUDE.md: 1,225 → ~430 lines, current state only (the dated status log stays in git history).
Server rules moved to the top: what is ours on 249/247 and what is not, non-negotiable rules,
announce-before-acting, password handling, and the full "deploy it" procedure with verification.
- README: formal entry page with current numbers (10 grades, 18,522 questions, 61 API operations,
973 tests, PostgreSQL/Redis).
- Removed docs/frontend/ (Figma-era guide with guest login and its own api.ts; the frontend repo has
the real client). Swagger's external-docs link now points at the frontend repo.
- architecture/operations/security/content-authoring/loadtest/textbooks: SQLite, guest login,
demo accounts, question packs and the port-80 note replaced by what is true now.
- Technical handbook text updated throughout; all seven diagrams redrawn (PostgreSQL, phone-only
login, subscriptions, current data model); PDF rebuilt.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- 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>
ingestِ دوباره جایگزین نمیکرد: qdrant_point_id یک uuid4 تازه به ازای هر ردیف
است، پس خواندنِ دوبارهی یک صفحه نسخهی تکراری کنارِ نسخهی قدیمی میگذاشت و
جستجو نمیتوانست تشخیص بدهد کدام کدام است.
--refresh {figures,unjudgeable,both,all} و --refresh-pages اضافه شدند.
سه تصمیمِ طراحی که عمدیاند:
۱. پاکسازی صفحهبهصفحه است و درست پیش از خواندنِ همان صفحه، نه یکجا از اول.
وسطِ تست یک crash همین را ثابت کرد: فقط یک صفحه خالی ماند (۲۷۹→۲۷۶) و بقیهی
کتاب دستنخورده. پاکسازیِ یکجا همان crash را به ۸۱ صفحهی خالی تبدیل میکرد.
۲. اول Qdrant، بعد دیتابیس. شناسهی نقطه فقط در ردیفِ DB است، پس ترتیبِ برعکس
یعنی شکستِ Qdrant نقاط را برای همیشه بیصاحب میگذارد — نه قابلِ یافتن، نه
قابلِ پاک کردن.
۳. order از Max گرفته میشود نه count: بازخوانی ردیفها را از وسط پاک میکند و
count عددی میداد که با orderهای موجود تصادم داشت.
تخمینِ هزینه حالا از اندازهگیریِ واقعیِ پنلِ صورتحساب میآید نه از جدولِ قیمت،
و وعدهی «با Batch API نصف» حذف شد چون GapGPT اصلاً /v1/batches ندارد.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
نقشهی فیزیکیِ کتابها (افستِ صفحه، بازهی هر فصل، درسهای داخلِ فصل از
فهرستِ خودِ کتاب) در rag/services/textbooks.py ثبت شد تا عنوانِ فصل از
کتاب بیاید نه از حدسِ مدل — رشتهی فصل باید دقیقاً بینِ ingest و retrieval
یکی باشد وگرنه نتیجه بیسروصدا خالی برمیگردد.
rag_ingest_book کتاب را فصلبهفصل ingest میکند و قابلِ ازسرگیری است:
rag.IngestedPage نشانهی «این صفحه پردازش شد» را نگه میدارد حتی وقتی
صفحه chunkی نساخته، وگرنه هر بار اجرای دوباره بابتِ صفحههای بیمسئله
دوباره پول میگرفت. --plan هزینه را رایگان برآورد میکند.
rag_import_collection نقاطِ موجودِ Qdrant را در LessonChunk میریزد —
فقط میخواند، رایگان و idempotent، برای پایههایی که تیمِ دیگر ingest
کرده بود.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two bugs made self-ingested content useless, both silently:
- _payload wrote `chapter_number` (int) while math retrieval filters on
`chapter` (the full "فصل ۲: کسر" string), so anything we ingest could
never match a search — no error, just permanently invisible content.
- ingest_pdf flattened the vision extraction into one text blob and threw
away type/keywords/generalSolution/problem/solution. LessonChunk is the
source of truth, so rebuilding meant paying for vision again — and the
problem/solution pairs are the input for building lesson questions.
LessonChunk now stores those fields and _payload emits them under the same
keys the other team's collections use, so ours and theirs stay one shape.
Also fixes a regression from the whitenoise commit: the Manifest storage
variant raises when staticfiles.json is absent, which broke all 23 admin
rendering tests (Django forces DEBUG=False in tests, so USE_FINDERS is off)
and would have taken the admin panel down entirely the day DEBUG=0 ships
without a collectstatic run.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>