CLAUDE.md: lesson figures workflow, cost, review lessons, frontend cache and nginx headers

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-07 19:48:10 +03:30
parent b93f43ef02
commit e00f6b80eb

View File

@@ -446,6 +446,39 @@ preferred setup, because there is then no key to leak. **Never let the server ru
`django-insecure-…` fallback from `config/settings.py`: that string is committed here, so
anyone who can read this repo can forge a token for any user.**
## شکلِ ثابتِ درس‌ها (`Lesson.figures`) و کشِ فرانت — روی سرور از ۲۰۲۶-۱۰-۰۷ ۱۶:۴۸ (`b93f43e`)
**شکلِ درس یک بار ساخته و تأیید می‌شود و بعد ثابت است؛ هنگامِ نمایش هیچ فراخوانیِ مدلی نیست.**
`Lesson.figures` فهرستِ `{where: intro|example|step, index?, diagram}` است (`index` برای step از صفر).
`GET /api/lessons/{id}/intro` آن را برمی‌گرداند و فرانت (`LessonScreen`) با همان `Diagram` دستیار می‌کشد.
شکل در `content/seed/curriculum.json` هم می‌رود (`figures`)، و `seed_content` آن را **فقط در خانه‌ی خالی** می‌نشاند
(مثلِ `example`/`steps`). پس برای عوض‌کردنِ شکلِ درسی که روی سرور هست باید `figures` آن درس را خالی کرد و دوباره دیپلو کرد؛
**شناسه‌ی درس روی سرور با لپ‌تاپ فرق دارد** (۳۰۰۳..۳۰۰۶ محلی = ۲۲۹۸..۲۳۰۱ سرور)، پس با شناسه‌ی محلی روی سرور کار نکن.
- **ساخت:** `python manage.py gen_lesson_figures --grade 12 --limit 4 [--lesson ID] [--redo] [--dry-run]`.
همان مدلِ چت و کاتالوگِ `<diagram>` و اعتبارسنجِ `rag.services.diagram.validate` (مسیرِ ارزانِ دستیار).
مدل می‌تواند `[]` بدهد؛ همه‌ی درس‌ها شکل نمی‌خواهند. شماره‌ی قدم‌ها در پرامپت ۱‌به‌بعد است (همان شماره‌ای که کاربر می‌بیند)
و کد یکی کم می‌کند؛ با شمارش از صفر شکل زیرِ قدمِ اشتباه می‌نشست.
- **هزینه (سنجیده ۲۰۲۶-۱۰-۰۷):** هر درس ≈ ۳٫۵ هزار توکنِ ورودی و ۰٫۱ تا ۰٫۶ هزار خروجی. صورتحسابِ GapGPT برای یک فراخوانی
≈ ۰٫۰۳ سنت داد و فرمولِ رسمیِ `gpt-4.1-mini` ≈ ۰٫۱۵ سنت؛ این دو نمی‌خوانند و علتش پیدا نشد. برآوردِ ۳۰۰۰ درس ۱ تا ۴٫۵ دلار.
- **باید با چشم دید.** در همین چهار درس مدل خط‌شکسته را با `line` (بی‌پایان) کشید، یک بار فقط نقطه بی‌خط داد، نمودارِ تابع را با
بازه‌ی بزرگ له کرد، و برای قدمِ ۳ شکل را زیرِ قدمِ ۲ گذاشت. چهار درسِ اولِ حسابانِ ۱۲ (فصل «تابع») بازبینی شدند؛
هیچ درسِ دیگری شکل ندارد. برچسب‌هایی مثلِ «A۲» و «g(x)=f(x)+۲» کنارِ لبه کمی ناجورند و رفع نشدند.
- **ایرادِ محتوا، نه شکل:** مثال و قدم‌های درسِ «تابع درجه سوم، توابع یک‌نوا…» کپیِ مثالِ «تبدیل نمودار توابع» است و با عنوانش
نمی‌خواند (از `fill_lesson_texts`). شکل‌هایش با همان متن می‌خوانند.
- **بازبینیِ زنده بی‌پیامک:** با یک `OTPCode` که خودت برای یکی از دموها (مثلاً `09120000105`، پایه‌ی ۱۲، کاربر ۱۴) در دیتابیسِ سرور
می‌سازی (کدِ تصادفی، ۵ دقیقه، از stdin نه از argv) وارد شو، توکن را در `localStorage['tadrisino.tokens']` (`{token, refreshToken}`)
بگذار و با `puppeteer-core` (در scratchpad، نه ریپو) از «نقشه ← فصل ← جزیره ← اول درس‌هاش رو بخونم» برو. آخرش `POST /api/auth/logout`.
توکنِ دسترسی را چاپ نکن (یک بار چاپ شد).
**کشِ مرورگر:** سینیور شکلِ درس‌ها را در یک مرورگر نمی‌دید و در مرورگرِ دیگر می‌دید؛ API و bundleِ زنده درست بودند. علتِ احتمالی
(مستقیم دیده نشد): `index.html` فقط `etag` داشت و بی `Cache-Control` از کش بالا می‌آمد. در `/etc/nginx/sites-available/mathapp-front`
(فقط سایتِ ما؛ بکاپ کنارش `…bak-20261007`) حالا `Cache-Control: no-cache` برای همه و `immutable, max-age=1y` برای `/assets/` هست
(`nginx -t` و `reload`، نه restart). از بیرون `index.html` و مسیرهای اپ `no-cache` دادند؛ هدرِ `/assets/` را نشد دید چون
ArvanCloud فایل‌های js را خودش نگه می‌دارد (`x-cache: HIT`). **`config.js` هم از کشِ آروان می‌آید**؛ با عوض‌شدنِ دامنه‌ی API
کشِ آن را در پنلِ آروان پاک کن (نه فقط `index.html`). مرورگری که پیش از این تغییر `index.html` را کش کرده یک بار باید
«Clear site data» بزند. بارِ هم‌زمانِ هزار نفر آزموده نشد؛ استدلال این است که فایل‌های سنگین از CDN می‌آیند و `index.html` ۳۰۴ می‌گیرد.
## وضعیت ۲۰۲۶-۱۰-۰۷ — روی سرور (`2779270`، ری‌استارت ۱۴:۱۶)
بکاپ‌های همان روز در `.deploy-backups/`: `env-before-secretkey-redis-20261007-135850`،