from django.db import models class Plan(models.Model): """ ⚠️ اصلاح نسبت به سند اولیه: نمونه‌ی پاسخ GET /api/subscription/plans در سند Endpointهای API یک فیلد boolean به اسم `popular` داره («ماهانه» → false، «سالانه» → true) که در دیاگرام مدل‌ها (سند معماری داده) برای Plan اصلاً ذکر نشده. چون بدون این فیلد نمی‌شه دقیقاً همون response schema رو پیاده‌سازی کرد، اینجا اضافه شده — دقیقاً مثل فیکس is_correct روی content.Choice در فاز ۱. """ title = models.CharField(max_length=50) price = models.PositiveIntegerField() currency = models.CharField(max_length=10, default='IRT') discount_percent = models.PositiveSmallIntegerField(default=0) popular = models.BooleanField(default=False) # منبعِ صریحِ مدتِ اشتراک؛ بدونش activate_subscription مجبور بود مدت رو # از رویِ متنِ title (مثلاً کلمه‌ی «سالانه») حدس بزنه. duration_days = models.PositiveIntegerField(default=30) def __str__(self): return self.title class Subscription(models.Model): """وضعیتِ pending برای فاصله‌ی بینِ ساختنِ Subscription (در purchase) و تاییدِ پرداخت (webhook)؛ فعال‌سازیِ واقعی توسطِ subscription.services.activate_subscription انجام می‌شه.""" STATUS_CHOICES = [ ('pending', 'در انتظار پرداخت'), ('active', 'فعال'), ('expired', 'منقضی'), ('canceled', 'لغوشده'), ] user_id = models.IntegerField(unique=True, db_index=True) # ارجاع سبک به accounts.User plan = models.ForeignKey(Plan, on_delete=models.SET_NULL, null=True, related_name='subscriptions') status = models.CharField(max_length=15, choices=STATUS_CHOICES, default='pending') started_at = models.DateTimeField(auto_now_add=True) expires_at = models.DateTimeField(null=True, blank=True) order_id = models.IntegerField(null=True, blank=True) # ارجاع سبک به payment.Order # چون Subscription فقط یک ردیف در ازای هر user_id داره، دو خریدِ هم‌زمانِ # همون کاربر می‌تونن به وضعیتِ میانیِ کاملاً یکسانی برسن (مقایسه‌ی # فیلدها کافی نیست برای CAS). version با UPDATEِ اتمیکِ # version=F('version')+1 (بدونِ select_for_update) هر نوشتنِ واقعی رو # از نوشتنِ هم‌زمانِ دیگری تمیز می‌ده. version = models.PositiveIntegerField(default=0) def __str__(self): return f"sub-user{self.user_id}-{self.status}"