from django.contrib.auth import get_user_model from django.core.exceptions import ValidationError as DjangoValidationError from rest_framework import serializers from rest_framework_simplejwt.tokens import RefreshToken from ..models import Role from ..validators import normalize_iran_mobile, validate_iran_mobile User = get_user_model() class IranPhoneField(serializers.CharField): def to_internal_value(self, data): v = super().to_internal_value(data) normalized = normalize_iran_mobile(v) try: validate_iran_mobile(normalized) except DjangoValidationError: raise serializers.ValidationError("Enter a valid Iranian mobile number.") return normalized class OTPSendSerializer(serializers.Serializer): phone_number = IranPhoneField() class OTPVerifySerializer(serializers.Serializer): phone_number = IranPhoneField() code = serializers.CharField(min_length=4, max_length=6) full_name = serializers.CharField(required=False, allow_blank=True, max_length=150) role = serializers.ChoiceField( required=False, choices=[(Role.STUDENT.value, "student"), (Role.TEACHER.value, "teacher")], ) def validate(self, attrs): if not User.objects.filter(phone_number=attrs["phone_number"]).exists(): missing = {} if not attrs.get("full_name"): missing["full_name"] = "Required for new account" if not attrs.get("role"): missing["role"] = "Required for new account" if missing: raise serializers.ValidationError(missing) return attrs class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = ["id", "phone_number", "full_name", "role", "email", "language"] read_only_fields = fields def issue_tokens_for(user) -> dict: refresh = RefreshToken.for_user(user) return {"access": str(refresh.access_token), "refresh": str(refresh)}