feat(account): GET /me user endpoint only, disable cache and extra routers

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-12 20:44:35 +03:00
commit d94dd31439
107 changed files with 5083 additions and 0 deletions

View File

@@ -0,0 +1,5 @@
from src.presentation.schemas.phone import SetPhoneRequest
from src.presentation.schemas.bank import BankUpdateRequest, BankConfirmRequest
from src.presentation.schemas.crypto_wallet import CryptoWalletConfirmRequest
from src.presentation.schemas.password import ChangePasswordConfirmRequest
from src.presentation.schemas.email import ChangeEmailConfirmOldRequest, ChangeEmailCompleteRequest

View File

@@ -0,0 +1,110 @@
import re
from typing import Self
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
@model_validator(mode='after')
def at_least_one(self) -> Self:
if not any([self.bik, self.account_number, self.card_number]):
raise ValueError('At least one field is required')
return self
@field_validator('bik')
@classmethod
def validate_bik(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')
return v
@field_validator('account_number')
@classmethod
def validate_account_number(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')
return v
@field_validator('card_number')
@classmethod
def validate_card_number(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)')
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
@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')
return self
@field_validator('code')
@classmethod
def validate_code(cls, v: str) -> str:
v = v.strip()
if not re.match(r'^\d{6}$', v):
raise ValueError('Code must be exactly 6 digits')
return v
@field_validator('bik')
@classmethod
def validate_bik(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')
return v
@field_validator('account_number')
@classmethod
def validate_account_number(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')
return v
@field_validator('card_number')
@classmethod
def validate_card_number(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)')
return v

View File

@@ -0,0 +1,23 @@
import re
from pydantic import BaseModel, field_validator
class CryptoWalletConfirmRequest(BaseModel):
code: str
wallet_address: str
@field_validator('code')
@classmethod
def validate_code(cls, v: str) -> str:
v = v.strip()
if not re.match(r'^\d{6}$', v):
raise ValueError('Code must be exactly 6 digits')
return v
@field_validator('wallet_address')
@classmethod
def validate_tron_address(cls, v: str) -> str:
v = v.strip()
if not re.match(r'^T[1-9A-HJ-NP-Za-km-z]{33}$', v):
raise ValueError('Invalid TRON wallet address')
return v

View File

@@ -0,0 +1,35 @@
import re
from pydantic import BaseModel, field_validator
class ChangeEmailConfirmOldRequest(BaseModel):
code: str
new_email: str
@field_validator('code')
@classmethod
def validate_code(cls, v: str) -> str:
v = v.strip()
if not re.match(r'^\d{6}$', v):
raise ValueError('Code must be exactly 6 digits')
return v
@field_validator('new_email')
@classmethod
def validate_new_email(cls, v: str) -> str:
v = v.strip().lower()
if not re.match(r'^[^@\s]+@[^@\s]+\.[^@\s]+$', v):
raise ValueError('Invalid email address')
return v
class ChangeEmailCompleteRequest(BaseModel):
code: str
@field_validator('code')
@classmethod
def validate_code(cls, v: str) -> str:
v = v.strip()
if not re.match(r'^\d{6}$', v):
raise ValueError('Code must be exactly 6 digits')
return v

View File

@@ -0,0 +1,30 @@
import re
from typing import Self
from pydantic import BaseModel, field_validator, model_validator
class ChangePasswordConfirmRequest(BaseModel):
code: str
new_password: str
confirm_password: str
@model_validator(mode='after')
def passwords_match(self) -> Self:
if self.new_password != self.confirm_password:
raise ValueError('Passwords do not match')
return self
@field_validator('code')
@classmethod
def validate_code(cls, v: str) -> str:
v = v.strip()
if not re.match(r'^\d{6}$', v):
raise ValueError('Code must be exactly 6 digits')
return v
@field_validator('new_password')
@classmethod
def validate_new_password(cls, v: str) -> str:
if len(v) < 8:
raise ValueError('Password must be at least 8 characters')
return v

View File

@@ -0,0 +1,17 @@
import re
from pydantic import BaseModel, field_validator
from src.application.domain.exceptions import ApplicationException
class SetPhoneRequest(BaseModel):
phone: str
@field_validator('phone')
@classmethod
def validate_russian_phone(cls, v: str) -> str:
cleaned = re.sub(r'[\s\-\(\)]', '', v)
pattern = r'^(\+7|8)\d{10}$'
if not re.match(pattern, cleaned):
raise ApplicationException(message='Invalid Russian phone number', status_code=429)
normalized = '+7' + cleaned[-10:]
return normalized