Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d794d3f9c6 | |||
| d2e8eb9e4d | |||
| b6ffdd9553 |
@@ -1,6 +1,6 @@
|
|||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
from typing import Protocol, runtime_checkable
|
from typing import Protocol, runtime_checkable
|
||||||
from src.application.abstractions.repositories import IUserRepository, ISessionRepository, ILegalEntityRepository
|
from src.application.abstractions.repositories import IUserRepository, ISessionRepository
|
||||||
|
|
||||||
|
|
||||||
@runtime_checkable
|
@runtime_checkable
|
||||||
@@ -17,6 +17,3 @@ class IUnitOfWork(Protocol):
|
|||||||
@property
|
@property
|
||||||
def session_repository(self) -> ISessionRepository: ...
|
def session_repository(self) -> ISessionRepository: ...
|
||||||
|
|
||||||
@property
|
|
||||||
def legal_entity_repository(self) -> ILegalEntityRepository: ...
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
from src.application.abstractions.repositories.i_user_repository import IUserRepository
|
from src.application.abstractions.repositories.i_user_repository import IUserRepository
|
||||||
from src.application.abstractions.repositories.i_session_repository import ISessionRepository
|
from src.application.abstractions.repositories.i_session_repository import ISessionRepository
|
||||||
from src.application.abstractions.repositories.i_legal_entity_repository import ILegalEntityRepository
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
from abc import ABC, abstractmethod
|
|
||||||
|
|
||||||
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
|
||||||
|
|
||||||
|
|
||||||
class ILegalEntityRepository(ABC):
|
|
||||||
@abstractmethod
|
|
||||||
async def get_by_user_id(self, user_id: str) -> LegalEntityEntity | None:
|
|
||||||
raise NotImplementedError
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
from src.application.abstractions import IUnitOfWork
|
from src.application.abstractions import IUnitOfWork
|
||||||
from src.application.contracts import ILogger, ICache
|
from src.application.contracts import ILogger, ICache
|
||||||
from src.application.domain.entities import UserEntity
|
from src.application.domain.entities import UserEntity
|
||||||
from src.application.domain.enums.account_type import AccountType
|
|
||||||
from src.infrastructure.database.decorators import transactional
|
from src.infrastructure.database.decorators import transactional
|
||||||
|
|
||||||
|
|
||||||
@@ -14,7 +13,5 @@ class GetMeCommand:
|
|||||||
@transactional
|
@transactional
|
||||||
async def __call__(self, user_id: str) -> UserEntity:
|
async def __call__(self, user_id: str) -> UserEntity:
|
||||||
user = await self._unit_of_work.user_repository.get_user_by_id(user_id=user_id)
|
user = await self._unit_of_work.user_repository.get_user_by_id(user_id=user_id)
|
||||||
if user.account_type == AccountType.LEGAL_ENTITY.value:
|
|
||||||
user.legal_entity = await self._unit_of_work.legal_entity_repository.get_by_user_id(user_id)
|
|
||||||
self._logger.info(f'User ID: {user.id}')
|
self._logger.info(f'User ID: {user.id}')
|
||||||
return user
|
return user
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from dataclasses import dataclass
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
|
||||||
class LegalEntityEntity:
|
|
||||||
id: str
|
|
||||||
user_id: str
|
|
||||||
name: str
|
|
||||||
inn: str
|
|
||||||
status: str
|
|
||||||
short_name: str | None = None
|
|
||||||
ogrn: str | None = None
|
|
||||||
kpp: str | None = None
|
|
||||||
legal_address: str | None = None
|
|
||||||
actual_address: str | None = None
|
|
||||||
bank_details: dict[str, Any] | None = None
|
|
||||||
contact_person: str | None = None
|
|
||||||
contact_phone: str | None = None
|
|
||||||
kyc_verified: bool = True
|
|
||||||
kyc_verified_at: datetime | None = None
|
|
||||||
@@ -2,8 +2,6 @@ from __future__ import annotations
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import date, datetime
|
from datetime import date, datetime
|
||||||
|
|
||||||
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass(slots=True)
|
@dataclass(slots=True)
|
||||||
class UserEntity:
|
class UserEntity:
|
||||||
@@ -30,6 +28,3 @@ class UserEntity:
|
|||||||
created_at: datetime | None = None
|
created_at: datetime | None = None
|
||||||
updated_at: datetime | None = None
|
updated_at: datetime | None = None
|
||||||
kyc_verified_at: datetime | None = None
|
kyc_verified_at: datetime | None = None
|
||||||
|
|
||||||
account_type: str = 'individual'
|
|
||||||
legal_entity: LegalEntityEntity | None = None
|
|
||||||
|
|||||||
@@ -1,6 +0,0 @@
|
|||||||
from enum import StrEnum
|
|
||||||
|
|
||||||
|
|
||||||
class AccountType(StrEnum):
|
|
||||||
INDIVIDUAL = 'individual'
|
|
||||||
LEGAL_ENTITY = 'legal_entity'
|
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
from src.infrastructure.database.models.base import Base
|
from src.infrastructure.database.models.base import Base
|
||||||
from src.infrastructure.database.models.user import UserModel
|
from src.infrastructure.database.models.user import UserModel
|
||||||
from src.infrastructure.database.models.legal_entity import LegalEntityModel
|
|
||||||
from src.infrastructure.database.models.sessions import Session
|
from src.infrastructure.database.models.sessions import Session
|
||||||
|
|
||||||
__all__ = ['Base', 'UserModel', 'LegalEntityModel', 'Session']
|
__all__ = ['Base', 'UserModel', 'Session']
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from datetime import datetime
|
|
||||||
from typing import Any
|
|
||||||
|
|
||||||
from sqlalchemy import Boolean, DateTime, ForeignKey, String, Text
|
|
||||||
from sqlalchemy.dialects.postgresql import JSONB
|
|
||||||
from sqlalchemy.orm import Mapped, mapped_column
|
|
||||||
|
|
||||||
from src.infrastructure.database.models.base import Base
|
|
||||||
from src.infrastructure.database.models.mixins import AuditTimestampsMixin, UlidPrimaryKeyMixin
|
|
||||||
|
|
||||||
|
|
||||||
class LegalEntityModel(Base, UlidPrimaryKeyMixin, AuditTimestampsMixin):
|
|
||||||
__tablename__ = 'legal_entities'
|
|
||||||
|
|
||||||
user_id: Mapped[str] = mapped_column(String(26), ForeignKey('users.id', ondelete='RESTRICT'), nullable=False, unique=True, index=True)
|
|
||||||
name: Mapped[str] = mapped_column(String(512), nullable=False)
|
|
||||||
short_name: Mapped[str | None] = mapped_column(String(256), nullable=True)
|
|
||||||
inn: Mapped[str] = mapped_column(String(12), nullable=False, index=True)
|
|
||||||
ogrn: Mapped[str | None] = mapped_column(String(15), nullable=True)
|
|
||||||
kpp: Mapped[str | None] = mapped_column(String(9), nullable=True)
|
|
||||||
legal_address: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
||||||
actual_address: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
||||||
bank_details: Mapped[dict[str, Any] | None] = mapped_column(JSONB, nullable=True)
|
|
||||||
contact_person: Mapped[str | None] = mapped_column(String(256), nullable=True)
|
|
||||||
contact_phone: Mapped[str | None] = mapped_column(String(16), nullable=True)
|
|
||||||
status: Mapped[str] = mapped_column(String(32), nullable=False, server_default='active', default='active')
|
|
||||||
kyc_verified: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default='true', default=True)
|
|
||||||
kyc_verified_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
||||||
encrypted_mnemonic: Mapped[str | None] = mapped_column(Text, nullable=True)
|
|
||||||
created_by: Mapped[str | None] = mapped_column(String(26), nullable=True)
|
|
||||||
@@ -27,7 +27,3 @@ class UserModel(Base, UlidPrimaryKeyMixin, AuditTimestampsMixin, SoftDeleteMixin
|
|||||||
|
|
||||||
kyc_verified: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default='false', default=False)
|
kyc_verified: Mapped[bool] = mapped_column(Boolean, nullable=False, server_default='false', default=False)
|
||||||
kyc_verified_at: Mapped[DateTime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
kyc_verified_at: Mapped[DateTime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
||||||
|
|
||||||
account_type: Mapped[str] = mapped_column(String(20), nullable=False, server_default='individual', default='individual')
|
|
||||||
provisioned_by: Mapped[str | None] = mapped_column(String(26), nullable=True)
|
|
||||||
provisioned_at: Mapped[DateTime | None] = mapped_column(DateTime(timezone=True), nullable=True)
|
|
||||||
|
|||||||
@@ -1,3 +1,2 @@
|
|||||||
from src.infrastructure.database.repositories.user_repository import UserRepository
|
from src.infrastructure.database.repositories.user_repository import UserRepository
|
||||||
from src.infrastructure.database.repositories.session_repository import SessionRepository
|
from src.infrastructure.database.repositories.session_repository import SessionRepository
|
||||||
from src.infrastructure.database.repositories.legal_entity_repository import LegalEntityRepository
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from sqlalchemy import select
|
|
||||||
from sqlalchemy.ext.asyncio import AsyncSession
|
|
||||||
from sqlalchemy.exc import SQLAlchemyError
|
|
||||||
|
|
||||||
from src.application.abstractions.repositories.i_legal_entity_repository import ILegalEntityRepository
|
|
||||||
from src.application.contracts import ILogger
|
|
||||||
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
|
||||||
from src.application.domain.exceptions import InternalException
|
|
||||||
from src.infrastructure.database.models.legal_entity import LegalEntityModel
|
|
||||||
|
|
||||||
|
|
||||||
class LegalEntityRepository(ILegalEntityRepository):
|
|
||||||
def __init__(self, session: AsyncSession, logger: ILogger):
|
|
||||||
self._session = session
|
|
||||||
self._logger = logger
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _to_entity(model: LegalEntityModel) -> LegalEntityEntity:
|
|
||||||
return LegalEntityEntity(
|
|
||||||
id=model.id,
|
|
||||||
user_id=model.user_id,
|
|
||||||
name=model.name,
|
|
||||||
inn=model.inn,
|
|
||||||
status=model.status,
|
|
||||||
short_name=model.short_name,
|
|
||||||
ogrn=model.ogrn,
|
|
||||||
kpp=model.kpp,
|
|
||||||
legal_address=model.legal_address,
|
|
||||||
actual_address=model.actual_address,
|
|
||||||
bank_details=model.bank_details,
|
|
||||||
contact_person=model.contact_person,
|
|
||||||
contact_phone=model.contact_phone,
|
|
||||||
kyc_verified=model.kyc_verified,
|
|
||||||
kyc_verified_at=model.kyc_verified_at,
|
|
||||||
)
|
|
||||||
|
|
||||||
async def get_by_user_id(self, user_id: str) -> LegalEntityEntity | None:
|
|
||||||
try:
|
|
||||||
stmt = select(LegalEntityModel).where(LegalEntityModel.user_id == user_id)
|
|
||||||
result = await self._session.execute(stmt)
|
|
||||||
model = result.scalar_one_or_none()
|
|
||||||
if model is None:
|
|
||||||
return None
|
|
||||||
return self._to_entity(model)
|
|
||||||
except SQLAlchemyError as exc:
|
|
||||||
self._logger.exception(str(exc))
|
|
||||||
raise InternalException(message=f'Database error: {exc}') from exc
|
|
||||||
@@ -50,7 +50,6 @@ class UserRepository(IUserRepository):
|
|||||||
is_deleted=user.is_deleted,
|
is_deleted=user.is_deleted,
|
||||||
created_at=user.created_at,
|
created_at=user.created_at,
|
||||||
updated_at=user.updated_at,
|
updated_at=user.updated_at,
|
||||||
account_type=user.account_type,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
async def get_user_by_id(self, user_id: str) -> UserEntity:
|
async def get_user_by_id(self, user_id: str) -> UserEntity:
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker
|
||||||
from src.application.abstractions import IUnitOfWork
|
from src.application.abstractions import IUnitOfWork
|
||||||
from src.application.abstractions.repositories import IUserRepository, ISessionRepository, ILegalEntityRepository
|
from src.application.abstractions.repositories import IUserRepository, ISessionRepository
|
||||||
from src.application.contracts import ILogger
|
from src.application.contracts import ILogger
|
||||||
from src.infrastructure.database.repositories import UserRepository, SessionRepository, LegalEntityRepository
|
from src.infrastructure.database.repositories import UserRepository, SessionRepository
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -12,14 +12,12 @@ class UnitOfWork(IUnitOfWork):
|
|||||||
self._session: AsyncSession = None
|
self._session: AsyncSession = None
|
||||||
self._user_repository: IUserRepository = None
|
self._user_repository: IUserRepository = None
|
||||||
self._session_repository: ISessionRepository = None
|
self._session_repository: ISessionRepository = None
|
||||||
self._legal_entity_repository: ILegalEntityRepository = None
|
|
||||||
self._logger: ILogger = logger
|
self._logger: ILogger = logger
|
||||||
|
|
||||||
async def __aenter__(self):
|
async def __aenter__(self):
|
||||||
self._logger.debug('UnitOfWork enter')
|
self._logger.debug('UnitOfWork enter')
|
||||||
self._user_repository = None
|
self._user_repository = None
|
||||||
self._session_repository = None
|
self._session_repository = None
|
||||||
self._legal_entity_repository = None
|
|
||||||
self._session = self.session_factory()
|
self._session = self.session_factory()
|
||||||
return self
|
return self
|
||||||
|
|
||||||
@@ -46,9 +44,3 @@ class UnitOfWork(IUnitOfWork):
|
|||||||
if self._session_repository is None:
|
if self._session_repository is None:
|
||||||
self._session_repository = SessionRepository(session=self._session, logger=self._logger)
|
self._session_repository = SessionRepository(session=self._session, logger=self._logger)
|
||||||
return self._session_repository
|
return self._session_repository
|
||||||
|
|
||||||
@property
|
|
||||||
def legal_entity_repository(self) -> ILegalEntityRepository:
|
|
||||||
if self._legal_entity_repository is None:
|
|
||||||
self._legal_entity_repository = LegalEntityRepository(session=self._session, logger=self._logger)
|
|
||||||
return self._legal_entity_repository
|
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ from src.presentation.dependencies.logger import get_logger
|
|||||||
from src.presentation.decorators import csrf_protect
|
from src.presentation.decorators import csrf_protect
|
||||||
from src.presentation.schemas.api_errors import ApiErrorPayload, ApiValidationErrorsPayload
|
from src.presentation.schemas.api_errors import ApiErrorPayload, ApiValidationErrorsPayload
|
||||||
from src.presentation.schemas.me_public import MeUserPublicResponse
|
from src.presentation.schemas.me_public import MeUserPublicResponse
|
||||||
from src.presentation.serializers import me_user_public
|
|
||||||
|
|
||||||
account_router = APIRouter()
|
account_router = APIRouter()
|
||||||
|
|
||||||
@@ -37,6 +36,10 @@ account_router = APIRouter()
|
|||||||
'description': 'Ошибка проверки CSRF (нет пары cookie/заголовка, несовпадение или просрочен токен).',
|
'description': 'Ошибка проверки CSRF (нет пары cookie/заголовка, несовпадение или просрочен токен).',
|
||||||
'model': ApiErrorPayload,
|
'model': ApiErrorPayload,
|
||||||
},
|
},
|
||||||
|
status.HTTP_404_NOT_FOUND: {
|
||||||
|
'description': 'Учётная запись не найдена.',
|
||||||
|
'model': ApiErrorPayload,
|
||||||
|
},
|
||||||
status.HTTP_422_UNPROCESSABLE_ENTITY: {
|
status.HTTP_422_UNPROCESSABLE_ENTITY: {
|
||||||
'description': 'Ошибка валидации входных данных (например, заголовков).',
|
'description': 'Ошибка валидации входных данных (например, заголовков).',
|
||||||
'model': ApiValidationErrorsPayload,
|
'model': ApiValidationErrorsPayload,
|
||||||
@@ -52,4 +55,22 @@ async def me(
|
|||||||
) -> MeUserPublicResponse:
|
) -> MeUserPublicResponse:
|
||||||
user = await command(user_id=auth.user_id)
|
user = await command(user_id=auth.user_id)
|
||||||
logger.info(f'Get user: {user.id}')
|
logger.info(f'Get user: {user.id}')
|
||||||
return me_user_public(user)
|
return MeUserPublicResponse(
|
||||||
|
id=user.id,
|
||||||
|
email=user.email,
|
||||||
|
first_name=user.first_name,
|
||||||
|
middle_name=user.middle_name,
|
||||||
|
last_name=user.last_name,
|
||||||
|
birth_date=user.birth_date,
|
||||||
|
encrypted_mnemonic=user.encrypted_mnemonic,
|
||||||
|
phone=user.phone,
|
||||||
|
passport_data=user.passport_data,
|
||||||
|
inn=user.inn,
|
||||||
|
erc20=user.erc20,
|
||||||
|
avatar_link=user.avatar_link,
|
||||||
|
kyc_verified=user.kyc_verified,
|
||||||
|
is_deleted=user.is_deleted,
|
||||||
|
created_at=user.created_at,
|
||||||
|
updated_at=user.updated_at,
|
||||||
|
kyc_verified_at=user.kyc_verified_at
|
||||||
|
)
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ from src.presentation.schemas import (
|
|||||||
)
|
)
|
||||||
from src.presentation.schemas.api_errors import ApiErrorPayload, ApiValidationErrorsPayload
|
from src.presentation.schemas.api_errors import ApiErrorPayload, ApiValidationErrorsPayload
|
||||||
from src.presentation.schemas.me_public import MeUserPublicResponse, SetAvatarPublicResponse
|
from src.presentation.schemas.me_public import MeUserPublicResponse, SetAvatarPublicResponse
|
||||||
from src.presentation.serializers import me_user_public
|
|
||||||
|
|
||||||
|
|
||||||
account_settings_router = APIRouter(prefix='/settings')
|
account_settings_router = APIRouter(prefix='/settings')
|
||||||
@@ -175,7 +174,25 @@ async def set_avatar(
|
|||||||
command: SetAvatarCommand = Depends(get_set_avatar_command),
|
command: SetAvatarCommand = Depends(get_set_avatar_command),
|
||||||
) -> SetAvatarPublicResponse:
|
) -> SetAvatarPublicResponse:
|
||||||
user, webp_size = await command(user_id=auth.user_id, image_bytes=body.decoded_bytes)
|
user, webp_size = await command(user_id=auth.user_id, image_bytes=body.decoded_bytes)
|
||||||
pub = me_user_public(user)
|
pub = MeUserPublicResponse(
|
||||||
|
id=user.id,
|
||||||
|
email=user.email,
|
||||||
|
first_name=user.first_name,
|
||||||
|
middle_name=user.middle_name,
|
||||||
|
last_name=user.last_name,
|
||||||
|
birth_date=user.birth_date,
|
||||||
|
encrypted_mnemonic=user.encrypted_mnemonic,
|
||||||
|
phone=user.phone,
|
||||||
|
passport_data=user.passport_data,
|
||||||
|
inn=user.inn,
|
||||||
|
erc20=user.erc20,
|
||||||
|
avatar_link=user.avatar_link,
|
||||||
|
kyc_verified=user.kyc_verified,
|
||||||
|
is_deleted=user.is_deleted,
|
||||||
|
created_at=user.created_at,
|
||||||
|
updated_at=user.updated_at,
|
||||||
|
kyc_verified_at=user.kyc_verified_at
|
||||||
|
)
|
||||||
return SetAvatarPublicResponse(**pub.model_dump(), webp_size_bytes=webp_size)
|
return SetAvatarPublicResponse(**pub.model_dump(), webp_size_bytes=webp_size)
|
||||||
|
|
||||||
|
|
||||||
@@ -197,7 +214,25 @@ async def delete_avatar(
|
|||||||
command: DeleteAvatarCommand = Depends(get_delete_avatar_command),
|
command: DeleteAvatarCommand = Depends(get_delete_avatar_command),
|
||||||
) -> MeUserPublicResponse:
|
) -> MeUserPublicResponse:
|
||||||
user = await command(user_id=auth.user_id)
|
user = await command(user_id=auth.user_id)
|
||||||
return me_user_public(user)
|
return MeUserPublicResponse(
|
||||||
|
id=user.id,
|
||||||
|
email=user.email,
|
||||||
|
first_name=user.first_name,
|
||||||
|
middle_name=user.middle_name,
|
||||||
|
last_name=user.last_name,
|
||||||
|
birth_date=user.birth_date,
|
||||||
|
encrypted_mnemonic=user.encrypted_mnemonic,
|
||||||
|
phone=user.phone,
|
||||||
|
passport_data=user.passport_data,
|
||||||
|
inn=user.inn,
|
||||||
|
erc20=user.erc20,
|
||||||
|
avatar_link=user.avatar_link,
|
||||||
|
kyc_verified=user.kyc_verified,
|
||||||
|
is_deleted=user.is_deleted,
|
||||||
|
created_at=user.created_at,
|
||||||
|
updated_at=user.updated_at,
|
||||||
|
kyc_verified_at=user.kyc_verified_at
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@account_settings_router.post(
|
@account_settings_router.post(
|
||||||
|
|||||||
@@ -5,45 +5,6 @@ from datetime import date, datetime
|
|||||||
from pydantic import BaseModel, ConfigDict, Field
|
from pydantic import BaseModel, ConfigDict, Field
|
||||||
|
|
||||||
from src.application.domain.entities import UserEntity
|
from src.application.domain.entities import UserEntity
|
||||||
from src.application.domain.entities.legal_entity import LegalEntityEntity
|
|
||||||
|
|
||||||
|
|
||||||
class LegalEntityPublicResponse(BaseModel):
|
|
||||||
model_config = ConfigDict(from_attributes=False)
|
|
||||||
|
|
||||||
id: str
|
|
||||||
name: str
|
|
||||||
inn: str
|
|
||||||
status: str
|
|
||||||
short_name: str | None = None
|
|
||||||
ogrn: str | None = None
|
|
||||||
kpp: str | None = None
|
|
||||||
legal_address: str | None = None
|
|
||||||
actual_address: str | None = None
|
|
||||||
bank_details: dict | None = None
|
|
||||||
contact_person: str | None = None
|
|
||||||
contact_phone: str | None = None
|
|
||||||
kyc_verified: bool | None = None
|
|
||||||
kyc_verified_at: datetime | None = None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_entity(cls, entity: LegalEntityEntity) -> LegalEntityPublicResponse:
|
|
||||||
return cls(
|
|
||||||
id=entity.id,
|
|
||||||
name=entity.name,
|
|
||||||
inn=entity.inn,
|
|
||||||
status=entity.status,
|
|
||||||
short_name=entity.short_name,
|
|
||||||
ogrn=entity.ogrn,
|
|
||||||
kpp=entity.kpp,
|
|
||||||
legal_address=entity.legal_address,
|
|
||||||
actual_address=entity.actual_address,
|
|
||||||
bank_details=entity.bank_details,
|
|
||||||
contact_person=entity.contact_person,
|
|
||||||
contact_phone=entity.contact_phone,
|
|
||||||
kyc_verified=entity.kyc_verified,
|
|
||||||
kyc_verified_at=entity.kyc_verified_at,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class MeUserPublicResponse(BaseModel):
|
class MeUserPublicResponse(BaseModel):
|
||||||
@@ -66,16 +27,9 @@ class MeUserPublicResponse(BaseModel):
|
|||||||
created_at: datetime | None = Field(None, description='Время создания записи')
|
created_at: datetime | None = Field(None, description='Время создания записи')
|
||||||
updated_at: datetime | None = Field(None, description='Время последнего обновления')
|
updated_at: datetime | None = Field(None, description='Время последнего обновления')
|
||||||
kyc_verified_at: datetime | None = Field(None, description='Время подтверждения KYC')
|
kyc_verified_at: datetime | None = Field(None, description='Время подтверждения KYC')
|
||||||
account_type: str | None = Field(None, description='individual | legal_entity')
|
|
||||||
legal_entity: LegalEntityPublicResponse | None = Field(None, description='Профиль юрлица')
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_user(cls, user: UserEntity) -> MeUserPublicResponse:
|
def from_user(cls, user: UserEntity) -> MeUserPublicResponse:
|
||||||
legal_entity = (
|
|
||||||
LegalEntityPublicResponse.from_entity(user.legal_entity)
|
|
||||||
if user.legal_entity is not None
|
|
||||||
else None
|
|
||||||
)
|
|
||||||
return cls(
|
return cls(
|
||||||
id=user.id,
|
id=user.id,
|
||||||
email=user.email,
|
email=user.email,
|
||||||
@@ -94,8 +48,6 @@ class MeUserPublicResponse(BaseModel):
|
|||||||
created_at=user.created_at,
|
created_at=user.created_at,
|
||||||
updated_at=user.updated_at,
|
updated_at=user.updated_at,
|
||||||
kyc_verified_at=user.kyc_verified_at,
|
kyc_verified_at=user.kyc_verified_at,
|
||||||
account_type=user.account_type,
|
|
||||||
legal_entity=legal_entity,
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1 +0,0 @@
|
|||||||
from src.presentation.serializers.me_user import me_user_payload, me_user_public
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
from __future__ import annotations
|
|
||||||
|
|
||||||
from src.application.domain.entities import UserEntity
|
|
||||||
|
|
||||||
from src.presentation.schemas.me_public import MeUserPublicResponse
|
|
||||||
|
|
||||||
|
|
||||||
def me_user_public(user: UserEntity) -> MeUserPublicResponse:
|
|
||||||
return MeUserPublicResponse.from_user(user)
|
|
||||||
|
|
||||||
|
|
||||||
def me_user_payload(user: UserEntity) -> dict:
|
|
||||||
return me_user_public(user).model_dump(mode='json')
|
|
||||||
Reference in New Issue
Block a user