from django.contrib.auth import get_user_model from rest_framework import serializers from apps.accounts.models import OtpChannel, PhoneOTP from apps.accounts.services.phone import normalize_phone_number User = get_user_model() class UserSerializer(serializers.ModelSerializer): class Meta: model = User fields = [ "id", "email", "phone_number", "first_name", "last_name", "role", "is_phone_verified", "preferred_language", ] read_only_fields = ["id", "role", "is_phone_verified"] class RegisterSerializer(serializers.ModelSerializer): password = serializers.CharField(write_only=True, min_length=8) phone_number = serializers.CharField(max_length=20, required=True) class Meta: model = User fields = ["email", "password", "phone_number", "first_name", "last_name"] def validate_phone_number(self, value): if not value: return value try: return normalize_phone_number(value) except ValueError as exc: raise serializers.ValidationError(str(exc)) from exc def create(self, validated_data): return User.objects.create_user(**validated_data) class OTPRequestSerializer(serializers.Serializer): phone_number = serializers.CharField(max_length=20) channel = serializers.ChoiceField(choices=OtpChannel.choices) def validate_phone_number(self, value): try: return normalize_phone_number(value) except ValueError as exc: raise serializers.ValidationError(str(exc)) from exc class OTPVerifySerializer(serializers.Serializer): request_id = serializers.UUIDField() code = serializers.CharField(max_length=6) class PhoneAuthRequestSerializer(serializers.Serializer): phone_number = serializers.CharField(max_length=20) channel = serializers.ChoiceField(choices=OtpChannel.choices) device_id = serializers.CharField(required=False, allow_blank=True, max_length=128, write_only=True) email = serializers.EmailField(required=False, allow_null=True, allow_blank=True) first_name = serializers.CharField(required=False, allow_blank=True) last_name = serializers.CharField(required=False, allow_blank=True) def validate_phone_number(self, value): try: return normalize_phone_number(value) except ValueError as exc: raise serializers.ValidationError(str(exc)) from exc class PhoneAuthVerifySerializer(serializers.Serializer): request_id = serializers.UUIDField() code = serializers.CharField(max_length=6) class OTPStatusSerializer(serializers.ModelSerializer): class Meta: model = PhoneOTP fields = ["id", "phone_number", "channel", "provider", "created_at", "expires_at", "verified_at"] read_only_fields = fields