Files
MathApp/progress/serializers.py
Zareian 39247f6d53 senior's post-demo changes: parent report in the student's own account, Jalali birth date, invoices, math-only tutor, priced quotas
- remove the family app from the root (separate parent accounts, invite codes, parental
  settings); progress.0006 drops its tables, permissions and migration history, and
  Profile.parent_phone, the two family notification types and ?userId= on
  /api/progress/nodes go with it
- GET /api/user/weekly-report: last 7 days next to the 7 before (estimated minutes,
  questions, accuracy, islands, tutor questions) for the "parent report" page
- profile birthDate in Jalali (accounts/jalali.py), ages 5-99, birthYear derived from it
- GET /api/payment/invoices; orders now snapshot list price and plan title
- tutor answers only math: server pre-filter, scope rule in the prompt (tutor-v11),
  refusal marker replaced with fixed text; self-harm gets a help line instead
- streamed answers now record token usage (it was always 0)
- daily tutor quota: AI_DAILY_QUOTA_FREE (default 3) vs Plan.ai_daily_quota
- delete_users management command for wiping test accounts across every app
- docs/ai-cost-and-guardrails.md: measured cost per question and guardrail results

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-02 02:38:43 +03:30

99 lines
3.8 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
from rest_framework import serializers
class StreakSummarySerializer(serializers.Serializer):
current = serializers.IntegerField()
longest = serializers.IntegerField()
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 = StreakSummarySerializer()
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()