activeToday: activity recorded today (Tehran date). lost: length of a streak that broke (last active day before yesterday), so the app can show it frozen. Same rule as effective_current_streak; the weekly report keeps its own two-field streak serializer. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
107 lines
4.4 KiB
Python
107 lines
4.4 KiB
Python
from rest_framework import serializers
|
||
|
||
|
||
class StreakSummarySerializer(serializers.Serializer):
|
||
current = serializers.IntegerField()
|
||
longest = serializers.IntegerField()
|
||
|
||
|
||
class UserStreakSerializer(StreakSummarySerializer):
|
||
"""زنجیره در /api/user/summary: بهعلاوهی وضعیتی که خانه با آن آتش/در خطر/یخزده را نشان میدهد."""
|
||
activeToday = serializers.BooleanField(help_text='امروز (وقتِ تهران) فعالیتی ثبت شده؛ زنجیره امروز روشن است.')
|
||
lost = serializers.IntegerField(
|
||
help_text='طولِ زنجیرهای که با نیامدنِ دیروز شکست؛ صفر یعنی چیزی نشکسته. اپ آن را «یخزده» نشان میدهد.',
|
||
)
|
||
|
||
|
||
class UserSummaryResponseSerializer(serializers.Serializer):
|
||
userId = serializers.CharField()
|
||
name = serializers.CharField()
|
||
avatar = serializers.CharField()
|
||
gradeId = serializers.IntegerField(allow_null=True)
|
||
xp = serializers.IntegerField()
|
||
coins = serializers.IntegerField()
|
||
streak = UserStreakSerializer()
|
||
subscription = serializers.CharField(allow_null=True)
|
||
|
||
|
||
class StreakCalendarResponseSerializer(serializers.Serializer):
|
||
currentStreak = serializers.IntegerField()
|
||
longestStreak = serializers.IntegerField()
|
||
activeDays = serializers.ListField(child=serializers.DateField())
|
||
|
||
|
||
class LeaderboardEntrySerializer(serializers.Serializer):
|
||
rank = serializers.IntegerField()
|
||
userId = serializers.CharField()
|
||
name = serializers.CharField()
|
||
xpInPeriod = serializers.IntegerField()
|
||
|
||
|
||
class LeaderboardResponseSerializer(serializers.Serializer):
|
||
period = serializers.ChoiceField(choices=['weekly', 'all_time'])
|
||
entries = LeaderboardEntrySerializer(many=True)
|
||
|
||
|
||
class UserHeartsResponseSerializer(serializers.Serializer):
|
||
currentHearts = serializers.IntegerField()
|
||
maxHearts = serializers.IntegerField()
|
||
nextRefillAt = serializers.DateTimeField(allow_null=True)
|
||
# همهی قلبها کی یکجا پر میشوند (۲۴ ساعت بعد از اولین قلبِ ازدسترفته).
|
||
fullRefillAt = serializers.DateTimeField(allow_null=True)
|
||
isUnlimited = serializers.BooleanField()
|
||
|
||
|
||
class CharacterSerializer(serializers.Serializer):
|
||
characterId = serializers.CharField()
|
||
slug = serializers.CharField()
|
||
name = serializers.CharField()
|
||
icon = serializers.CharField()
|
||
unlockXp = serializers.IntegerField()
|
||
unlocked = serializers.BooleanField()
|
||
selected = serializers.BooleanField()
|
||
|
||
|
||
class CharacterListResponseSerializer(serializers.Serializer):
|
||
characters = CharacterSerializer(many=True)
|
||
|
||
|
||
class SelectCharacterRequestSerializer(serializers.Serializer):
|
||
characterId = serializers.CharField()
|
||
|
||
|
||
class SelectCharacterResponseSerializer(serializers.Serializer):
|
||
characterId = serializers.CharField()
|
||
selected = serializers.BooleanField()
|
||
|
||
|
||
class WeeklyReportDaySerializer(serializers.Serializer):
|
||
date = serializers.DateField()
|
||
minutes = serializers.IntegerField(help_text='تخمینی؛ از فاصلهی رویدادها، نه زمانِ واقعیِ باز بودنِ اپ.')
|
||
questions = serializers.IntegerField()
|
||
correct = serializers.IntegerField()
|
||
xp = serializers.IntegerField()
|
||
lessons = serializers.IntegerField()
|
||
islands = serializers.IntegerField()
|
||
aiQuestions = serializers.IntegerField()
|
||
|
||
|
||
class WeeklyReportTotalsSerializer(serializers.Serializer):
|
||
minutes = serializers.IntegerField()
|
||
activeDays = serializers.IntegerField()
|
||
questions = serializers.IntegerField()
|
||
correct = serializers.IntegerField()
|
||
xp = serializers.IntegerField()
|
||
lessons = serializers.IntegerField(help_text='درسهای یکتا؛ تکرارِ یک درس یک بار شمرده میشود.')
|
||
islands = serializers.IntegerField(help_text='جزیرههای یکتا.')
|
||
aiQuestions = serializers.IntegerField()
|
||
|
||
|
||
class WeeklyReportResponseSerializer(serializers.Serializer):
|
||
today = serializers.DateField()
|
||
days = WeeklyReportDaySerializer(many=True, help_text='۷ روزِ آخر تا امروز، قدیمی به جدید.')
|
||
previousDays = WeeklyReportDaySerializer(many=True, help_text='۷ روزِ پیش از آن، قدیمی به جدید.')
|
||
thisWeek = WeeklyReportTotalsSerializer()
|
||
lastWeek = WeeklyReportTotalsSerializer()
|
||
streak = StreakSummarySerializer()
|