feat: add get me
This commit is contained in:
@@ -30,10 +30,9 @@ async def me(
|
||||
'birth_date': str(user.birth_date) if user.birth_date else None,
|
||||
'crypto_wallet': user.crypto_wallet,
|
||||
'phone': user.phone,
|
||||
'bik': user.bik,
|
||||
'account_number': user.account_number,
|
||||
'card_number': user.card_number,
|
||||
'passport_data': user.passport_data,
|
||||
'inn': user.inn,
|
||||
'erc20': user.erc20,
|
||||
'kyc_verified': user.kyc_verified,
|
||||
'is_deleted': user.is_deleted,
|
||||
'created_at': user.created_at.isoformat() if user.created_at else None,
|
||||
|
||||
@@ -136,15 +136,15 @@ async def bank_details_complete(
|
||||
user = await command(
|
||||
user_id=auth.user_id,
|
||||
code=body.code,
|
||||
bik=body.bik,
|
||||
account_number=body.account_number,
|
||||
card_number=body.card_number,
|
||||
passport_data=body.passport_data,
|
||||
inn=body.inn,
|
||||
erc20=body.erc20,
|
||||
)
|
||||
return ORJSONResponse(
|
||||
status_code=status.HTTP_200_OK,
|
||||
content={
|
||||
'bik': user.bik,
|
||||
'account_number': user.account_number,
|
||||
'card_number': user.card_number,
|
||||
'passport_data': user.passport_data,
|
||||
'inn': user.inn,
|
||||
'erc20': user.erc20,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -4,69 +4,67 @@ from pydantic import BaseModel, field_validator, model_validator
|
||||
|
||||
|
||||
class BankUpdateRequest(BaseModel):
|
||||
bik: str | None = None
|
||||
account_number: str | None = None
|
||||
card_number: str | None = None
|
||||
passport_data: str | None = None
|
||||
inn: str | None = None
|
||||
erc20: str | None = None
|
||||
|
||||
@model_validator(mode='after')
|
||||
def at_least_one(self) -> Self:
|
||||
if not any([self.bik, self.account_number, self.card_number]):
|
||||
if not any([self.passport_data, self.inn, self.erc20]):
|
||||
raise ValueError('At least one field is required')
|
||||
return self
|
||||
|
||||
@field_validator('bik')
|
||||
@field_validator('passport_data', 'inn', 'erc20')
|
||||
@classmethod
|
||||
def validate_bik(cls, v: str | None) -> str | None:
|
||||
def strip_optional(cls, v: str | None) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
s = v.strip()
|
||||
return s or None
|
||||
|
||||
@field_validator('inn')
|
||||
@classmethod
|
||||
def validate_inn(cls, v: str | None) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
v = v.strip()
|
||||
if not re.match(r'^\d{9}$', v):
|
||||
raise ValueError('BIK must be exactly 9 digits')
|
||||
if not re.match(r'^\d{10}(\d{2})?$', v):
|
||||
raise ValueError('INN must be 10 or 12 digits')
|
||||
if len(v) > 12:
|
||||
raise ValueError('INN is too long')
|
||||
return v
|
||||
|
||||
@field_validator('account_number')
|
||||
@field_validator('erc20')
|
||||
@classmethod
|
||||
def validate_account_number(cls, v: str | None) -> str | None:
|
||||
def validate_erc20(cls, v: str | None) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
v = v.strip()
|
||||
if not re.match(r'^\d{20}$', v):
|
||||
raise ValueError('Account number must be exactly 20 digits')
|
||||
if not re.match(r'^0x[a-fA-F0-9]{40}$', v):
|
||||
raise ValueError('ERC20 address must be 0x followed by 40 hex characters')
|
||||
return v
|
||||
|
||||
@field_validator('card_number')
|
||||
@field_validator('passport_data')
|
||||
@classmethod
|
||||
def validate_card_number(cls, v: str | None) -> str | None:
|
||||
def validate_passport_data(cls, v: str | None) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
v = re.sub(r'[\s\-]', '', v)
|
||||
if not re.match(r'^\d{13,19}$', v):
|
||||
raise ValueError('Card number must be 13-19 digits')
|
||||
if not cls._luhn_check(v):
|
||||
raise ValueError('Invalid card number (Luhn check failed)')
|
||||
v = v.strip()
|
||||
if len(v) > 255:
|
||||
raise ValueError('Passport data is too long')
|
||||
return v
|
||||
|
||||
@staticmethod
|
||||
def _luhn_check(number: str) -> bool:
|
||||
digits = [int(d) for d in number]
|
||||
odd_digits = digits[-1::-2]
|
||||
even_digits = digits[-2::-2]
|
||||
total = sum(odd_digits)
|
||||
for d in even_digits:
|
||||
total += sum(divmod(d * 2, 10))
|
||||
return total % 10 == 0
|
||||
|
||||
|
||||
class BankConfirmRequest(BaseModel):
|
||||
code: str
|
||||
bik: str | None = None
|
||||
account_number: str | None = None
|
||||
card_number: str | None = None
|
||||
passport_data: str | None = None
|
||||
inn: str | None = None
|
||||
erc20: str | None = None
|
||||
|
||||
@model_validator(mode='after')
|
||||
def at_least_one_field(self) -> Self:
|
||||
if not any([self.bik, self.account_number, self.card_number]):
|
||||
raise ValueError('At least one bank field is required')
|
||||
if not any([self.passport_data, self.inn, self.erc20]):
|
||||
raise ValueError('At least one field is required')
|
||||
return self
|
||||
|
||||
@field_validator('code')
|
||||
@@ -77,34 +75,42 @@ class BankConfirmRequest(BaseModel):
|
||||
raise ValueError('Code must be exactly 6 digits')
|
||||
return v
|
||||
|
||||
@field_validator('bik')
|
||||
@field_validator('passport_data', 'inn', 'erc20')
|
||||
@classmethod
|
||||
def validate_bik(cls, v: str | None) -> str | None:
|
||||
def strip_optional(cls, v: str | None) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
s = v.strip()
|
||||
return s or None
|
||||
|
||||
@field_validator('inn')
|
||||
@classmethod
|
||||
def validate_inn(cls, v: str | None) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
v = v.strip()
|
||||
if not re.match(r'^\d{9}$', v):
|
||||
raise ValueError('BIK must be exactly 9 digits')
|
||||
if not re.match(r'^\d{10}(\d{2})?$', v):
|
||||
raise ValueError('INN must be 10 or 12 digits')
|
||||
if len(v) > 12:
|
||||
raise ValueError('INN is too long')
|
||||
return v
|
||||
|
||||
@field_validator('account_number')
|
||||
@field_validator('erc20')
|
||||
@classmethod
|
||||
def validate_account_number(cls, v: str | None) -> str | None:
|
||||
def validate_erc20(cls, v: str | None) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
v = v.strip()
|
||||
if not re.match(r'^\d{20}$', v):
|
||||
raise ValueError('Account number must be exactly 20 digits')
|
||||
if not re.match(r'^0x[a-fA-F0-9]{40}$', v):
|
||||
raise ValueError('ERC20 address must be 0x followed by 40 hex characters')
|
||||
return v
|
||||
|
||||
@field_validator('card_number')
|
||||
@field_validator('passport_data')
|
||||
@classmethod
|
||||
def validate_card_number(cls, v: str | None) -> str | None:
|
||||
def validate_passport_data(cls, v: str | None) -> str | None:
|
||||
if v is None:
|
||||
return None
|
||||
v = re.sub(r'[\s\-]', '', v)
|
||||
if not re.match(r'^\d{13,19}$', v):
|
||||
raise ValueError('Card number must be 13-19 digits')
|
||||
if not BankUpdateRequest._luhn_check(v):
|
||||
raise ValueError('Invalid card number (Luhn check failed)')
|
||||
v = v.strip()
|
||||
if len(v) > 255:
|
||||
raise ValueError('Passport data is too long')
|
||||
return v
|
||||
|
||||
Reference in New Issue
Block a user