56 lines
1.7 KiB
Python
56 lines
1.7 KiB
Python
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
from uuid import uuid4
|
|
|
|
from app.application.users.dto import UserDTO
|
|
from app.application.users.ports.unit_of_work import UnitOfWork
|
|
from app.domain.users.entities import User
|
|
from app.domain.users.services import ensure_unique_email
|
|
from app.domain.users.value_objects import Email
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class CreateUserCommand:
|
|
email: str
|
|
full_name: str
|
|
|
|
|
|
class CreateUserUseCase:
|
|
"""
|
|
Inbound port (use case).
|
|
Outbound ports: UnitOfWork -> UserRepository, and email integration.
|
|
"""
|
|
|
|
def __init__(self, uow: UnitOfWork, welcome_email_sender) -> None:
|
|
self._uow = uow
|
|
self._welcome_email_sender = welcome_email_sender
|
|
|
|
async def execute(self, cmd: CreateUserCommand) -> UserDTO:
|
|
email_vo = Email(cmd.email)
|
|
async with self._uow:
|
|
existing = await self._uow.users.get_by_email(str(email_vo))
|
|
ensure_unique_email(existing_user=existing)
|
|
|
|
user = User.register(
|
|
user_id=uuid4(), email=email_vo, full_name=cmd.full_name
|
|
)
|
|
await self._uow.users.add(user)
|
|
await self._uow.commit()
|
|
|
|
for ev in user.pull_events():
|
|
from app.domain.users.events import UserRegistered
|
|
|
|
if isinstance(ev, UserRegistered):
|
|
await self._welcome_email_sender.send_welcome(
|
|
to_email=ev.email, full_name=cmd.full_name
|
|
)
|
|
|
|
return UserDTO(
|
|
id=user.id,
|
|
email=str(user.email),
|
|
full_name=user.full_name,
|
|
is_active=user.is_active,
|
|
created_at=user.created_at,
|
|
)
|