docs: question packs, credit rules, real hearts

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-02 12:14:45 +03:30
parent 58c8e6d014
commit 4c7ccf10a0
3 changed files with 42 additions and 18 deletions

View File

@@ -102,8 +102,8 @@ BAZAAR_REFRESH_TOKEN=
# ═══════════════════════════════════════════════════════════════════════ # ═══════════════════════════════════════════════════════════════════════
# کلیدِ مسیرهای داخلیِ سرور-به-سرور؛ خالی روی سرور = آن مسیرها بسته‌اند. # کلیدِ مسیرهای داخلیِ سرور-به-سرور؛ خالی روی سرور = آن مسیرها بسته‌اند.
# INTERNAL_SERVICE_KEY= # INTERNAL_SERVICE_KEY=
# با صفر قلب جلوی جواب دادن گرفته شود؟ فقط وقتی فرانت صفحه‌ی «قلب تمام شد» دارد. # با صفر قلب جلوی جواب دادن گرفته شود؟ پیش‌فرض روشن (از ۲۰۲۶-۱۰-۰۲)؛ ۰ خاموشش می‌کند.
# HEARTS_ENFORCED=0 # HEARTS_ENFORCED=1
# سقف‌های کدِ ورود: هر شماره در روز، و کلِ سامانه در روز (ضدِ SMS pumping). # سقف‌های کدِ ورود: هر شماره در روز، و کلِ سامانه در روز (ضدِ SMS pumping).
# OTP_REQUEST_PHONE_DAILY_MAX=10 # OTP_REQUEST_PHONE_DAILY_MAX=10
# OTP_SMS_GLOBAL_DAILY_MAX=300 # OTP_SMS_GLOBAL_DAILY_MAX=300

View File

@@ -409,8 +409,13 @@ anyone who can read this repo can forge a token for any user.**
- **لحنِ دستیار از سن** (`tone_for`، پرامپت `tutor-v12-age-tone`): ۱۸+ در هر پایه لحنِ بزرگسال می‌گیرد؛ - **لحنِ دستیار از سن** (`tone_for`، پرامپت `tutor-v12-age-tone`): ۱۸+ در هر پایه لحنِ بزرگسال می‌گیرد؛
نمادگذاری از کتابِ پایه. کشِ جواب با لحن کلید می‌خورد. فقط یک مقایسه‌ی زنده (سوم، ۸ و ۴۵ سال). نمادگذاری از کتابِ پایه. کشِ جواب با لحن کلید می‌خورد. فقط یک مقایسه‌ی زنده (سوم، ۸ و ۴۵ سال).
- **شناسه‌ی نمایشی** `User482917` (`accounts/public_id.py`، از id، بی‌ستون؛ ادمین با آن جستجو می‌کند). - **شناسه‌ی نمایشی** `User482917` (`accounts/public_id.py`، از id، بی‌ستون؛ ادمین با آن جستجو می‌کند).
- **قیمتِ پلن‌ها** (`subscription.0008`): ماهانه ۱۷۹ و سالانه ۱٬۷۹۰ هزار تومان، هر دو ۱۰ سوال در روز - **بسته‌ی سوال به‌جای اشتراک** (`subscription.0009/0010`): ۲۰ / ۶۰ / ۱۵۰ سوال به ۴۵ / ۱۱۹ / ۲۵۹ هزار
(۰۰۰۷ ۹۹ هزار و ۵ سوال بود؛ ۵ در برابرِ ۳ِ رایگان بی‌فایده بود). حساب در گزارشِ هزینه‌ی گزارش-۲۶. تومان، بی‌انقضا، با ۷ / ۳۰ / ۶۰ روز قلبِ نامحدود (`HeartsPass`). اعتبار در دفترِ `QuestionCredit`،
اول سهمیه‌ی رایگانِ روز خرج می‌شود؛ هر سوالی که به API برسد اعتبار می‌خورد، ردِ صافی/کش/خطا نه
(`Message.charge`). پلن‌های ماهانه/سالانه `on_sale=False` (مشترکِ فعلی سقفش را دارد). مسیرِ قیمت‌ها
پیش از بسته: ۲۹۹ هزار سالانه → ۹۹/۹۹۰ با ۵ سوال → ۱۷۹/۱٬۷۹۰ با ۱۰ سوال. شرح: `docs/ai-cost-and-guardrails.md`.
- **قلب واقعی است:** `HEARTS_ENFORCED` پیش‌فرض روشن؛ قلبِ صفر جلوی جواب را می‌گیرد (فرانت صفحه‌ی «قلب‌هات
تموم شد» را دارد). روی سرور از ۲۰۲۶-۱۰-۰۲ ۱۱:۴۲.
- **حذفِ حساب** `POST /api/user/delete`: شماره‌دار با کدِ پیامکیِ تازه (`verify_phone_otp`، مشترک با ورود)، - **حذفِ حساب** `POST /api/user/delete`: شماره‌دار با کدِ پیامکیِ تازه (`verify_phone_otp`، مشترک با ورود)،
مهمان با «حذف»؛ سفارش‌ها و statuslog می‌مانند؛ دموها رد می‌شوند. «ورود با حسابِ دیگر» فقط خروج است؛ مهمان با «حذف»؛ سفارش‌ها و statuslog می‌مانند؛ دموها رد می‌شوند. «ورود با حسابِ دیگر» فقط خروج است؛
چند حساب روی یک دستگاه عمداً نگه داشته نمی‌شود. چند حساب روی یک دستگاه عمداً نگه داشته نمی‌شود.

View File

@@ -31,21 +31,40 @@ Message.objects.filter(role='assistant', created_at__gte=since).values('conversa
.annotate(p=Sum('prompt_tokens'), c=Sum('completion_tokens')) # سنت = (0.4p + 1.6c) / 1e4 .annotate(p=Sum('prompt_tokens'), c=Sum('completion_tokens')) # سنت = (0.4p + 1.6c) / 1e4
``` ```
## سقفِ روزانه ## بسته‌ی سوال و سقفِ روزانه (از ۲۰۲۶-۱۰-۰۲)
- رایگان: `AI_DAILY_QUOTA_FREE` در `.env`، پیش‌فرض **۳**. تا ۲۰۲۶-۱۰-۰۱ همه، با اشتراک یا بی‌اشتراک، اشتراکِ ماهانه/سالانه کنار رفت و **بسته‌ی سوال** جایش آمد (`subscription.0009`، `subscription.0010`):
۱۵ سوال در روز داشتند.
- مشترک: `Plan.ai_daily_quota`، در ادمین قابلِ ویرایش و پیش‌فرض ۱۵. اشتراکِ بی‌پلن (هدیه) هم ۱۵ | بسته | قیمت (تومان) | هر سوال | هدیه | سهمِ هزینه از درآمدِ خالص (میانگین / دبیرستان) |
می‌گیرد. کد در `subscription.services.ai_daily_quota` است. |---|---|---|---|---|
- کاربرِ رایگانی که به سقف می‌رسد پیامِ «با خریدِ اشتراک…» می‌گیرد و اپ دکمه‌ی «دیدنِ اشتراک‌ها» | ۲۰ سوال | ۴۵٬۰۰۰ | ۲٬۲۵۰ | ۷ روز قلبِ نامحدود | ۳۱٪ / ۴۰٪ |
را نشان می‌دهد. | ۶۰ سوال | ۱۱۹٬۰۰۰ | ۱٬۹۸۰ | ۳۰ روز | ۳۶٪ / ۴۶٪ |
- قیمتِ فعلی (migrationِ `subscription.0008`): ماهانه ۱۷۹٬۰۰۰ و سالانه ۱٬۷۹۰٬۰۰۰ تومان، هر دو ۱۰ سوال در | ۱۵۰ سوال | ۲۵۹٬۰۰۰ | ۱٬۷۳۰ | ۶۰ روز | ۴۱٪ / ۵۲٪ |
روز. ۵ سوال (`0007`) در برابرِ ۳ِ رایگان تفاوتی حس نمی‌شد. با هزینه‌ی ~۶۰۰ تومان برای هر سوال و مصرفِ
یک‌سومِ سقف، ۱۰ سوال حدودِ ~۱۷۶ هزار تومان در ماه می‌خواهد تا دستیار حداکثر ۴۰٪ِ درآمدِ خالص (پس از ۱۵٪یِ سهم‌ها پس از ۱۵٪یِ کافه‌بازار حساب شده‌اند. چرا بسته: همه هر روز نمی‌آیند، ۱۷۹ هزار تومان در ماه برای خیلی‌ها زیاد
بازار) باشد؛ ۱۵ سوال ~۲۶۵ هزار. خرجِ کاربرهای رایگان به ازای هر مشترک با درصدِ تبدیل تغییر می‌کند: با ۵٪ بود، و مشترکِ پرکار زیان می‌ساخت. با بسته هر سوال جدا سود دارد. مسیرِ قیمت‌ها پیش از این:
تبدیل و میانگینِ ۵ سوال در ماه برای هر رایگان، ~۵۷ هزار تومان؛ زیرِ ۵٪ از خرجِ خودِ مشترک بیشتر می‌شود. - سالانه ۲۹۹ هزار تومان، با ۱۵ سوال در روز برای همه.
API پلن‌ها `aiDailyQuota` و `freeAiDailyQuota` می‌دهد و کارتِ پلن عدد را از همین می‌سازد. - ماهانه/سالانه ۹۹ و ۹۹۰ هزار تومان، با ۵ سوال در روز.
- انتخابِ عددها تصمیمِ محصولی است. جدولِ قیمت در برابرِ سقف در نسخه‌ی کاملِ گزارش آمده است. - ماهانه/سالانه ۱۷۹ و ۱٬۷۹۰ هزار تومان، با ۱۰ سوال در روز.
پلن‌های اشتراکی پاک نشدند (`on_sale=False`) تا مشترکِ فعلی سقفش را نگه دارد.
- **ترتیبِ خرج:** اول `AI_DAILY_QUOTA_FREE` سوالِ رایگانِ همان روز (پیش‌فرض ۳)، بعد اعتبارِ بسته؛ مشترکِ
قدیمی سقفِ `Plan.ai_daily_quota`ِ خودش را دارد.
- **چه چیزی خرج می‌شود:** هر سوالی که به API برسد، از جمله ردِ «غیرِ ریاضی» توسطِ مدل. ردِ صافیِ سرور،
جوابِ کش‌شده و جوابی که ساخته نشد چیزی کم نمی‌کنند. `Message.charge` روی هر پیامِ کاربر می‌گوید
سوال از کجا پرداخت شد (`free` / `credit` / `none`).
- **دفترِ اعتبار** `subscription.QuestionCredit`: هر خرید یک ردیفِ مثبت دارد (هر سفارش فقط یک بار، با
قیدِ یکتا) و هر سوال یک ردیفِ ۱−. کم شدن داخلِ همان تراکنشی است که ردیفِ کاربر را قفل می‌کند. دو
سوالِ هم‌زمان با یک اعتبار آزموده نشده است؛ جلوگیری به آن قفل و `transaction_mode: IMMEDIATE`ِ
SQLite سپرده شده.
- **قلبِ نامحدودِ بسته** در `HeartsPass` است، جدا از `Subscription`، تا خریدِ بسته اشتراکِ کسی را عوض
نکند. از پایانِ کارتِ قبلی ادامه پیدا می‌کند. `HEARTS_ENFORCED` حالا پیش‌فرض روشن است، پس قلبِ صفر
واقعاً جلوی جواب را می‌گیرد.
- اپ موجودی را از `GET /api/ai/quota` می‌خواند و بعد از هر جواب از `remainingQuota` و `credits`ِ خودِ
جواب. صفحه‌ی خرید `GET /api/subscription/status` (`questionCredits`، `unlimitedHeartsUntil`) را می‌خواند.
- **کافه‌بازار:** هر بسته باید در پنلِ بازار «محصولِ مصرفی» تعریف شود و اپِ اندروید بعد از تأیید
consume کند. این هنوز انجام نشده است.
## محافظِ دستیار (`rag/services/guardrails.py`) ## محافظِ دستیار (`rag/services/guardrails.py`)