120 lines
3.6 KiB
Python
120 lines
3.6 KiB
Python
from drf_spectacular.utils import extend_schema_field
|
|
from rest_framework import serializers
|
|
|
|
from .models import Choice, Grade, Lesson, Question
|
|
|
|
|
|
# ---- Grades ----
|
|
|
|
class GradeSerializer(serializers.ModelSerializer):
|
|
class Meta:
|
|
model = Grade
|
|
fields = ['id', 'title', 'icon', 'color']
|
|
|
|
|
|
class GradesListResponseSerializer(serializers.Serializer):
|
|
grades = GradeSerializer(many=True)
|
|
|
|
|
|
# ---- Home (skill map + stats) ----
|
|
|
|
class NodeStatusSerializer(serializers.Serializer):
|
|
id = serializers.CharField()
|
|
title = serializers.CharField()
|
|
status = serializers.ChoiceField(choices=['locked', 'unlocked', 'completed'])
|
|
|
|
|
|
class UnitWithNodesSerializer(serializers.Serializer):
|
|
id = serializers.CharField()
|
|
title = serializers.CharField()
|
|
nodes = NodeStatusSerializer(many=True)
|
|
|
|
|
|
class StatsSerializer(serializers.Serializer):
|
|
progressPercent = serializers.FloatField()
|
|
xp = serializers.IntegerField()
|
|
coins = serializers.IntegerField()
|
|
|
|
|
|
class HomeResponseSerializer(serializers.Serializer):
|
|
units = UnitWithNodesSerializer(many=True)
|
|
stats = StatsSerializer()
|
|
|
|
|
|
# ---- Lesson intro ----
|
|
|
|
class LessonIntroResponseSerializer(serializers.Serializer):
|
|
lessonId = serializers.CharField()
|
|
title = serializers.CharField()
|
|
introText = serializers.CharField()
|
|
mascotAnimation = serializers.CharField()
|
|
|
|
|
|
# ---- Lesson questions ----
|
|
|
|
class ChoiceOptionSerializer(serializers.Serializer):
|
|
id = serializers.CharField()
|
|
value = serializers.CharField()
|
|
|
|
|
|
class QuestionSerializer(serializers.Serializer):
|
|
id = serializers.CharField()
|
|
type = serializers.CharField()
|
|
prompt = serializers.CharField()
|
|
options = ChoiceOptionSerializer(many=True)
|
|
|
|
|
|
class LessonQuestionsResponseSerializer(serializers.Serializer):
|
|
questions = QuestionSerializer(many=True)
|
|
|
|
|
|
# ---- Answer submission ----
|
|
|
|
class AnswerRequestSerializer(serializers.Serializer):
|
|
selectedOptionId = serializers.IntegerField()
|
|
|
|
|
|
class AnswerResponseSerializer(serializers.Serializer):
|
|
correct = serializers.BooleanField()
|
|
correctOptionId = serializers.CharField()
|
|
xpEarned = serializers.IntegerField()
|
|
heartsRemaining = serializers.IntegerField()
|
|
|
|
|
|
# ---- Lesson completion ----
|
|
|
|
class LessonCompleteRequestSerializer(serializers.Serializer):
|
|
correctCount = serializers.IntegerField()
|
|
totalQuestions = serializers.IntegerField()
|
|
|
|
|
|
class LessonCompleteResponseSerializer(serializers.Serializer):
|
|
stars = serializers.IntegerField()
|
|
xpEarned = serializers.IntegerField()
|
|
coinsEarned = serializers.IntegerField()
|
|
stats = StatsSerializer()
|
|
|
|
|
|
# ---- Node progress (تکمیلشده / نصفهرها / در حال انجام) ----
|
|
|
|
class NodeProgressSerializer(serializers.Serializer):
|
|
nodeId = serializers.CharField(source='node_id')
|
|
nodeTitle = serializers.CharField(source='node.title')
|
|
unitId = serializers.CharField(source='node.unit_id')
|
|
status = serializers.ChoiceField(
|
|
choices=['not_started', 'in_progress', 'completed', 'abandoned'],
|
|
)
|
|
lessonsCompleted = serializers.IntegerField(source='lessons_completed_count')
|
|
lessonsTotal = serializers.SerializerMethodField()
|
|
startedAt = serializers.DateTimeField(source='started_at', allow_null=True)
|
|
completedAt = serializers.DateTimeField(source='completed_at', allow_null=True)
|
|
lastActivityAt = serializers.DateTimeField(source='last_activity_at', allow_null=True)
|
|
|
|
@extend_schema_field(serializers.IntegerField)
|
|
def get_lessonsTotal(self, obj):
|
|
return obj.node.lessons.count()
|
|
|
|
|
|
class NodeProgressListResponseSerializer(serializers.Serializer):
|
|
progress = NodeProgressSerializer(many=True)
|