Subscriptions only: Bazaar panel prices (598/898/1398k), assistant quota 5/3/3 from a cost calculation, packs off sale

- subscription.0016: prices equal to the Bazaar panel (senior), ai_daily_quota 5/3/3, card features; packs on_sale=False
  (one paid pack order, user 26, keeps its credits; pack paths stay for that order and for admin).
- Quota math in docs/ai-cost-and-guardrails.md: ~77% of a Bazaar sale reaches us; worst case (full quota every day)
  the assistant costs 23/27/35% of it.
- Assistant quota message points to the subscription, not packs.
982 tests green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 19:57:16 +03:30
parent c0fa46be44
commit 9c3adc3e60
13 changed files with 95 additions and 40 deletions

View File

@@ -30,7 +30,7 @@ class DailyQuotaTests(TestCase):
self.assertEqual([self.ask().status_code for _ in range(2)], [200, 200])
blocked = self.ask()
self.assertEqual(blocked.status_code, 429)
self.assertIn('بسته', blocked.json()['detail'])
self.assertIn('اشتراک', blocked.json()['detail']) # بسته از subscription.0016 فروخته نمی‌شود
def test_remaining_quota_follows_the_users_own_limit(self):
self.assertEqual(self.ask().json()['remainingQuota'], 1)

View File

@@ -360,9 +360,10 @@ class AskAIView(APIView):
n = str(quota).translate(str.maketrans('0123456789', '۰۱۲۳۴۵۶۷۸۹'))
raise Throttled(detail=(
f'سقفِ امروزِ سوال از دستیار ({n} سوال) پر شد. با خریدِ بسته‌ی سوال همین الان ادامه بده.'
# بسته‌ی سوال از subscription.0016 فروخته نمی‌شود؛ مشترک تا فردا صبر می‌کند، بی‌اشتراک اشتراک می‌خرد.
f'سقفِ امروزِ سوال از دستیار ({n} سوال) پر شد. فردا دوباره می‌تونی بپرسی.'
if has_active_subscription(user.id) else
f'سوال‌های رایگانِ امروز ({n} سوال) تمام شد. با خریدِ بسته‌ی سوال همین الان ادامه بده.'
f'سوال‌های رایگانِ امروز ({n} سوال) تمام شد. با خریدِ اشتراک هر روز سوالِ بیشتری بپرس.'
))
conversation_id = v.get('conversationId')