Remove the guest system entirely: no is_guest/device_id, no guest throttles, phone login is the only way in

accounts.0008 drops the columns and refuses to run while guest rows exist.
Docs describe the current state; tests that only proved guest behaviour are gone.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-05 18:20:10 +03:30
parent 8835e01595
commit 663252a260
61 changed files with 357 additions and 1518 deletions

View File

@@ -1,7 +1,7 @@
"""
یک دیتاست کوچک و واقعی برای تست دستی/API لوکال یا staging می‌سازه، طوری که
اجرای مکرر (repeat) هیچ رکورد تکراری‌ای نسازه — همه‌چیز با get_or_create روی
یک کلید طبیعی/یکتا (phone، device_id، code، idempotency_key و ...) انجام
یک کلید طبیعی/یکتا (phone، code، idempotency_key و ...) انجام
می‌شه، نه با create ساده.
هدف: پوشش کمینه‌ی جریان‌های اصلی API در هر ۱۰ اپ (accounts، content،
@@ -45,7 +45,6 @@ from accounts.models import OTPCode, Profile, Session, User, hash_refresh_token
# یکسان و بازه‌ی اختصاصی، شناساییِ رکوردهای seed در دیتابیس هم ساده می‌مونه.
MAIN_PHONE = '09120000001'
REFERRED_PHONE = '09120000004'
GUEST_DEVICE_ID = 'seed-guest-device-0001'
SEED_TAG = '[SEED]'
@@ -107,9 +106,6 @@ class Command(BaseCommand):
phones = [MAIN_PHONE, REFERRED_PHONE]
user_ids = list(User.objects.filter(phone__in=phones).values_list('pk', flat=True))
guest = User.objects.filter(device_id=GUEST_DEVICE_ID, is_guest=True).first()
if guest:
user_ids.append(guest.pk)
if user_ids:
UserAnswer.objects.filter(user_id__in=user_ids).delete()
@@ -140,17 +136,13 @@ class Command(BaseCommand):
OTPCode.objects.filter(phone__in=phones).delete()
Session.objects.filter(user__phone__in=phones).delete()
if guest:
Session.objects.filter(user=guest).delete()
User.objects.filter(phone__in=phones).delete()
if guest:
guest.delete()
self.stdout.write('رکوردهای قبلیِ seed حذف شدن؛ در حال ساختِ دوباره...')
# -- seed -------------------------------------------------------------
def _seed(self):
main_user, guest_user, referred_user = self._seed_accounts()
main_user, referred_user = self._seed_accounts()
self._seed_content_and_progress(main_user)
self._seed_characters()
self._seed_ai_tutor(main_user)
@@ -161,8 +153,7 @@ class Command(BaseCommand):
self._seed_support(main_user)
tokens = [
('کاربر اصلی (ثبت‌نام‌شده)', main_user, issue_access_token(main_user.pk)),
('کاربر مهمان', guest_user, issue_access_token(guest_user.pk)),
('کاربر اصلی', main_user, issue_access_token(main_user.pk)),
]
return {'tokens': tokens}
@@ -170,7 +161,7 @@ class Command(BaseCommand):
def _seed_accounts(self):
main_user, _ = User.objects.get_or_create(
phone=MAIN_PHONE,
defaults=dict(name=f'{SEED_TAG} کاربر اصلی', is_guest=False, grade_id=None),
defaults=dict(name=f'{SEED_TAG} کاربر اصلی', grade_id=None),
)
Profile.objects.get_or_create(
user=main_user, defaults=dict(birth_year=1394, bio=f'{SEED_TAG} پروفایل تستی')
@@ -179,33 +170,17 @@ class Command(BaseCommand):
user=main_user,
refresh_token=hash_refresh_token(f'seed-refresh-{MAIN_PHONE}'),
defaults=dict(
device_id='seed-device-main',
expires_at=timezone.now() + timedelta(days=settings.REFRESH_TOKEN_TTL_DAYS),
revoked=False,
),
)
guest_user, _ = User.objects.get_or_create(
device_id=GUEST_DEVICE_ID,
is_guest=True,
defaults=dict(name=f'{SEED_TAG} کاربر مهمان'),
)
Session.objects.get_or_create(
user=guest_user,
refresh_token=hash_refresh_token(f'seed-refresh-{GUEST_DEVICE_ID}'),
defaults=dict(
device_id=GUEST_DEVICE_ID,
expires_at=timezone.now() + timedelta(days=settings.REFRESH_TOKEN_TTL_DAYS),
revoked=False,
),
)
referred_user, _ = User.objects.get_or_create(
phone=REFERRED_PHONE, defaults=dict(name=f'{SEED_TAG} کاربر معرفی‌شده', is_guest=False)
phone=REFERRED_PHONE, defaults=dict(name=f'{SEED_TAG} کاربر معرفی‌شده')
)
self.stdout.write(self.style.SUCCESS('accounts: 3 کاربر (اصلی/مهمان/معرفی‌شده) آماده شد.'))
return main_user, guest_user, referred_user
self.stdout.write(self.style.SUCCESS('accounts: ۲ کاربر (اصلی/معرفی‌شده) آماده شد.'))
return main_user, referred_user
# -- content + progress --------------------------------------------------
def _seed_content_and_progress(self, main_user):