- content: unit_is_free/has_unit_access; questions, node quiz, answer and lesson/node complete return 402 subscription_required outside the first unit without an active subscription. /api/home units carry requiresSubscription. - subscription.0013: monthly 498k, quarterly 798k, six-month 1,298k toman, unlimited hearts, 3 AI questions/day; packs stay on sale for more questions. - AI_DAILY_QUOTA_FREE default 3 -> 2. - /api/subscription/status adds planTitle, planDurationDays, aiDailyQuota. - tests: content/tests_paywall.py; existing unlock-order tests get a subscription. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
45 lines
3.1 KiB
Python
45 lines
3.1 KiB
Python
"""
|
||
اشتراکِ زمانی برمیگردد (تصمیمِ سینیور و مدیرعامل، ۲۰۲۶-۱۰-۱۰): فصلِ اولِ هر پایه رایگان است و
|
||
بقیهی فصلها با اشتراک باز میشوند (content.views.unit_is_free). بستههای سوال کنارِ اشتراک میمانند.
|
||
|
||
قیمتها از سینیور: یکماهه ۴۹۸، سهماهه ۷۹۸، ششماهه ۱٬۲۹۸ هزار تومان.
|
||
|
||
اشتراک «محتوا و قلب» میفروشد، نه دستیار (تصمیمِ مالک، ۲۰۲۶-۱۰-۱۰): سقفِ دستیار برای مشترک ۳ سوال در
|
||
روز است و بیشتر از آن با بستهی سوال خریده میشود. حساب: هر سوال دستِ بالا ~۷۰۰ تومان
|
||
(docs/ai-cost-and-guardrails.md). با سقفِ ۸، مشترکِ ششماههای که هر روز سقف را پر کند ~۱۶۸ هزار تومان در
|
||
ماه هزینه داشت، یعنی ۷۸٪ِ سهمِ ماهانهی قیمت (۲۱۶ هزار)، و با ۱۵٪ِ کافهبازار ~۷٪ میماند. با سقفِ ۳ همین
|
||
بدترین حالت ~۶۳ هزار تومان است: ۲۹٪ِ ششماهه، ۲۴٪ِ سهماهه، ۱۳٪ِ یکماهه. این بدترین حالت است، نه
|
||
میانگین؛ مصرفِ واقعی سنجیده نشده. سقف از ادمین عوض میشود (Plan.ai_daily_quota).
|
||
|
||
پلنهای اشتراکیِ قدیمی (ماهانه/سالانه) دست نمیخورند و on_sale=False میمانند.
|
||
"""
|
||
from django.db import migrations
|
||
|
||
FEATURES = ['همهی فصلها و جزیرهها باز', 'قلبِ نامحدود', '۳ سوال در روز از دستیارِ هوشمند']
|
||
PLANS = [
|
||
{'title': 'یکماهه', 'price': 498_000, 'duration_days': 30, 'badge': '', 'popular': False},
|
||
{'title': 'سهماهه', 'price': 798_000, 'duration_days': 90, 'badge': 'محبوبترین', 'popular': True},
|
||
{'title': 'ششماهه', 'price': 1_298_000, 'duration_days': 180, 'badge': 'بهصرفهترین', 'popular': False},
|
||
]
|
||
|
||
|
||
def seed(apps, schema_editor):
|
||
Plan = apps.get_model('subscription', 'Plan')
|
||
# بستهها هم «محبوبترین» داشتند؛ دو کارتِ «محبوبترین» در یک صفحه معنا ندارد.
|
||
Plan.objects.filter(kind='pack').update(popular=False)
|
||
for plan in PLANS:
|
||
if not Plan.objects.filter(kind='subscription', on_sale=True, duration_days=plan['duration_days']).exists():
|
||
Plan.objects.create(kind='subscription', currency='IRT', discount_percent=0, ai_daily_quota=3,
|
||
features=FEATURES, on_sale=True, question_credits=0, hearts_days=0, **plan)
|
||
|
||
|
||
def undo(apps, schema_editor):
|
||
Plan = apps.get_model('subscription', 'Plan')
|
||
Plan.objects.filter(kind='subscription', on_sale=True, subscriptions__isnull=True,
|
||
title__in=[p['title'] for p in PLANS]).delete()
|
||
|
||
|
||
class Migration(migrations.Migration):
|
||
dependencies = [('subscription', '0012_plan_bazaar_sku')]
|
||
operations = [migrations.RunPython(seed, undo)]
|