Paywall: first unit of each grade free; 1/3/6-month subscriptions; AI sold separately
- 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>
This commit is contained in:
44
subscription/migrations/0013_monthly_plans_2026_10.py
Normal file
44
subscription/migrations/0013_monthly_plans_2026_10.py
Normal file
@@ -0,0 +1,44 @@
|
||||
"""
|
||||
اشتراکِ زمانی برمیگردد (تصمیمِ سینیور و مدیرعامل، ۲۰۲۶-۱۰-۱۰): فصلِ اولِ هر پایه رایگان است و
|
||||
بقیهی فصلها با اشتراک باز میشوند (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)]
|
||||
Reference in New Issue
Block a user