Question packs removed at the root; all subscriptions 4 assistant questions a day; Bazaar is subscription-only
- subscription.0017/0018, payment.0013: pack plans deleted, QuestionCredit/HeartsPass models and Plan.kind / question_credits / hearts_days / Order.question_credits / hearts_days dropped. The only paid pack order was the company owner's test account (user 26). - Assistant: no credit spending; quota is the daily cap only (free 2, every plan 4, gift subscription 4). - Bazaar: verify_purchase is subscription-only (no inapp guess), start/purchase responses lose productType, verify refuses an order without a subscription. A paid order with no subscription now logs ERROR. - Removed POST /api/payment/orders (internal; no caller). Its permission tests stay. - Pack-based tests rewritten on subscriptions (refund, security, Bazaar token); pack-only test files deleted. - docs: profit table for 4/day on both payment routes plus free users; handbook, operations, CLAUDE.md current. 949 tests green. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,11 +12,8 @@ class PlanSerializer(serializers.Serializer):
|
||||
features = serializers.ListField(child=serializers.CharField())
|
||||
badge = serializers.CharField(allow_blank=True)
|
||||
aiDailyQuota = serializers.IntegerField(help_text='سوال در روز از دستیار برای مشترکِ این پلن.')
|
||||
kind = serializers.ChoiceField(choices=['pack', 'subscription'])
|
||||
questionCredits = serializers.IntegerField(help_text='بسته: سوالهایی که به اعتبار اضافه میشود (منقضی نمیشود).')
|
||||
heartsDays = serializers.IntegerField(help_text='بسته: روزهای قلبِ نامحدودِ هدیه.')
|
||||
bazaarSku = serializers.CharField(
|
||||
allow_blank=True, help_text='SKUِ همین پلن (بسته یا اشتراک) در کافهبازار؛ خالی یعنی در بازار خریدنی نیست.')
|
||||
allow_blank=True, help_text='SKUِ همین اشتراک در کافهبازار (محصولِ «اشتراکی»)؛ خالی یعنی در بازار خریدنی نیست.')
|
||||
|
||||
|
||||
class PlansListResponseSerializer(serializers.Serializer):
|
||||
@@ -41,17 +38,12 @@ class PurchaseResponseSerializer(serializers.Serializer):
|
||||
bazaarSku = serializers.CharField(
|
||||
required=False, help_text='فقط بازار: SKUی که اپِ اندروید با Poolakey میخرد؛ '
|
||||
'developerPayload همان orderId باشد.')
|
||||
bazaarProductType = serializers.ChoiceField(
|
||||
choices=['inapp', 'subscription'], required=False,
|
||||
help_text='فقط بازار: inapp (بسته؛ purchaseProduct و بعد consume) یا subscription (subscribeProduct، بیconsume).')
|
||||
|
||||
|
||||
class SubscriptionStatusResponseSerializer(serializers.Serializer):
|
||||
active = serializers.BooleanField(help_text='اشتراکِ زمانی فعال (یک/سه/ششماهه)؛ نه بسته.')
|
||||
active = serializers.BooleanField(help_text='اشتراکِ زمانی فعال (یک/سه/ششماهه).')
|
||||
planTitle = serializers.CharField(allow_null=True, help_text='نامِ پلنِ اشتراکِ فعال؛ null بیاشتراک.')
|
||||
planDurationDays = serializers.IntegerField(allow_null=True, help_text='طولِ دورهی پلنِ فعال به روز.')
|
||||
aiDailyQuota = serializers.IntegerField(help_text='سقفِ سوالِ روزانهی همین کاربر از دستیار.')
|
||||
planId = serializers.CharField(allow_null=True)
|
||||
expiresAt = serializers.DateTimeField(allow_null=True)
|
||||
questionCredits = serializers.IntegerField(help_text='سوالهای خریدهشدهی باقیمانده (منقضی نمیشوند).')
|
||||
unlimitedHeartsUntil = serializers.DateTimeField(allow_null=True, help_text='پایانِ قلبِ نامحدودِ هدیهی بسته.')
|
||||
|
||||
Reference in New Issue
Block a user