add gamification characters (Duolingo-style mascot catalog)
New progress.Character model: an admin-managed catalog (same pattern as subscription.Plan) of selectable mascots, each unlocked once the user's XP crosses unlock_xp. No separate ownership table yet — unlocking is a pure function of UserStats.xp, kept intentionally minimal since this is the first of an incremental rollout the senior asked for. - GET /api/characters — catalog with per-user unlocked/selected flags - POST /api/characters/select — picks an active character, rejecting ones the user hasn't unlocked yet - UserStats.selected_character_id tracks the pick - seed_test_data now seeds 4 sample characters (owl/fox/turtle/lion) for local/staging testing Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -134,6 +134,9 @@ class Command(BaseCommand):
|
||||
BugReport.objects.filter(user_id__in=user_ids).delete()
|
||||
FamilyLink.objects.filter(parent_user_id__in=user_ids).delete()
|
||||
|
||||
from progress.models import Character
|
||||
Character.objects.filter(slug__startswith='seed-').delete()
|
||||
|
||||
Plan.objects.filter(title__startswith=SEED_TAG).delete()
|
||||
DiscountCode.objects.filter(code='SEEDTEST10').delete()
|
||||
Offer.objects.filter(code='SEEDTRIAL7').delete()
|
||||
@@ -153,6 +156,7 @@ class Command(BaseCommand):
|
||||
def _seed(self):
|
||||
main_user, guest_user, parent_user, child_user, referred_user = self._seed_accounts()
|
||||
self._seed_content_and_progress(main_user)
|
||||
self._seed_characters()
|
||||
self._seed_ai_tutor(main_user)
|
||||
plan_monthly, plan_yearly = self._seed_subscription_and_payment(main_user)
|
||||
self._seed_discount(main_user)
|
||||
@@ -303,6 +307,26 @@ class Command(BaseCommand):
|
||||
'content/progress: 1 پایه، 1 مبحث، 2 Node، 2 درس، 2 سوال و پیشرفتِ کاربرِ اصلی آماده شد.'
|
||||
))
|
||||
|
||||
# -- گیمیفیکیشن: کاراکترها -------------------------------------------------
|
||||
def _seed_characters(self):
|
||||
from progress.models import Character
|
||||
|
||||
# unlock_xp پلکانی، هماهنگ با xp=10ی کاربرِ اصلی که بالاتر ساخته شد:
|
||||
# فقط اولین کاراکتر (unlock_xp=0) براش باز است، بقیه هنوز قفلن —
|
||||
# برای اینکه هم مسیرِ «باز» و هم مسیرِ «قفل» در تست دستی قابلدیدن باشه.
|
||||
characters = [
|
||||
('seed-owl', f'{SEED_TAG} جغد کنجکاو', 'owl', 0, 1),
|
||||
('seed-fox', f'{SEED_TAG} روباه باهوش', 'fox', 100, 2),
|
||||
('seed-turtle', f'{SEED_TAG} لاکپشت صبور', 'turtle', 300, 3),
|
||||
('seed-lion', f'{SEED_TAG} شیر شجاع', 'lion', 600, 4),
|
||||
]
|
||||
for slug, name, icon, unlock_xp, order in characters:
|
||||
Character.objects.get_or_create(
|
||||
slug=slug, defaults=dict(name=name, icon=icon, unlock_xp=unlock_xp, order=order),
|
||||
)
|
||||
|
||||
self.stdout.write(self.style.SUCCESS(f'progress: {len(characters)} کاراکترِ گیمیفیکیشن آماده شد.'))
|
||||
|
||||
# -- ai_tutor -------------------------------------------------------------
|
||||
def _seed_ai_tutor(self, main_user):
|
||||
from ai_tutor.models import Conversation, Message, MessageFeedback
|
||||
|
||||
Reference in New Issue
Block a user