Kavenegar is being switched on, so every OTP request now costs credit: - phone numbers are normalised to 09XXXXXXXXX everywhere (login, OTP, family invite, TEST_LOGIN_PHONES keys) and existing rows are migrated; non-Iranian and landline numbers are rejected before any SMS - cooldown and a daily per-phone cap are counted in the database, so the three gunicorn workers no longer triple them - a global daily OTP SMS cap (default 300) stops SMS pumping - per-IP rates widened for CGNAT / school Wi-Fi (env-overridable) - provider message id is logged; SMS text warns not to share the code Second audit round: an offer no longer shortens a longer paid plan, Zarinpal error bodies no longer 500, island XP reaches the parent report, a non-numeric questionId no longer 500s after the answer is generated. 596 tests green. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
57 lines
2.1 KiB
Python
57 lines
2.1 KiB
Python
from rest_framework import serializers
|
|
|
|
from accounts.serializers import IranMobileField
|
|
|
|
|
|
class FamilyLinkInviteRequestSerializer(serializers.Serializer):
|
|
childPhone = IranMobileField()
|
|
|
|
|
|
class FamilyLinkInviteResponseSerializer(serializers.Serializer):
|
|
familyLinkId = serializers.CharField()
|
|
inviteCode = serializers.CharField()
|
|
status = serializers.CharField()
|
|
|
|
|
|
class FamilyLinkAcceptRequestSerializer(serializers.Serializer):
|
|
inviteCode = serializers.CharField(max_length=10)
|
|
|
|
|
|
class FamilyLinkAcceptResponseSerializer(serializers.Serializer):
|
|
familyLinkId = serializers.CharField()
|
|
status = serializers.CharField()
|
|
acceptedAt = serializers.DateTimeField(allow_null=True)
|
|
|
|
|
|
class FamilyLinkStatusResponseSerializer(serializers.Serializer):
|
|
familyLinkId = serializers.CharField()
|
|
status = serializers.CharField()
|
|
childName = serializers.CharField(allow_blank=True)
|
|
|
|
|
|
class FamilySettingsResponseSerializer(serializers.Serializer):
|
|
dailyLimitMinutes = serializers.IntegerField()
|
|
quietHoursStart = serializers.TimeField(allow_null=True)
|
|
quietHoursEnd = serializers.TimeField(allow_null=True)
|
|
|
|
|
|
class FamilySettingsUpdateRequestSerializer(serializers.Serializer):
|
|
dailyLimitMinutes = serializers.IntegerField(required=False, min_value=0)
|
|
quietHoursStart = serializers.TimeField(required=False, allow_null=True)
|
|
quietHoursEnd = serializers.TimeField(required=False, allow_null=True)
|
|
|
|
|
|
class FamilySettingsUpdateResponseSerializer(serializers.Serializer):
|
|
success = serializers.BooleanField()
|
|
|
|
|
|
class FamilyWeeklyReportResponseSerializer(serializers.Serializer):
|
|
weekStart = serializers.DateField()
|
|
xpEarned = serializers.IntegerField()
|
|
lessonsCompleted = serializers.IntegerField()
|
|
# افزوده ۲۰۲۶-۰۹-۲۵: جزیرههایی که آزمونشان در این هفته تمام شده. xpEarned
|
|
# از همین تاریخ امتیازِ آزمونِ جزیره را هم دارد.
|
|
islandsCompleted = serializers.IntegerField()
|
|
currentStreak = serializers.IntegerField()
|
|
openedAt = serializers.DateTimeField(allow_null=True)
|